diff options
author | Georgey | 2017-07-05 11:40:43 +0530 |
---|---|---|
committer | Georgey | 2017-07-05 11:40:43 +0530 |
commit | 938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427 (patch) | |
tree | b343c0ee5609433c80e0de1db8b6886c9126dc2d | |
parent | 5b72577efe080c5294b32d804e4d26351fef30bc (diff) | |
download | symphony-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.tar.gz symphony-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.tar.bz2 symphony-938fef4a37a7b7c61b4b6ff74cb4cfd2f100c427.zip |
Added linux shared libraries and header files for int and ecos functions
918 files changed, 211920 insertions, 79 deletions
diff --git a/thirdparty/linux/include/coin/AmplTNLP.hpp b/thirdparty/linux/include/coin/AmplTNLP.hpp new file mode 100644 index 0000000..a8c823a --- /dev/null +++ b/thirdparty/linux/include/coin/AmplTNLP.hpp @@ -0,0 +1,569 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: AmplTNLP.hpp 2242 2013-04-24 19:26:30Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPAMPLTNLP_HPP__ +#define __IPAMPLTNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpTNLP.hpp" +#include "IpJournalist.hpp" +#include "IpOptionsList.hpp" + +#include <map> +#include <string> + +/* non Ipopt forward declaration */ +struct ASL_pfgh; +struct SufDecl; +struct SufDesc; + +namespace Ipopt +{ + class AmplSuffixHandler : public ReferencedObject + { + public: + AmplSuffixHandler(); + + ~AmplSuffixHandler(); + + enum Suffix_Type + { + Index_Type, + Number_Type + }; + + enum Suffix_Source + { + Variable_Source, + Constraint_Source, + Objective_Source, + Problem_Source + }; + + void AddAvailableSuffix(std::string suffix_string, Suffix_Source source, Suffix_Type type) + { + suffix_ids_.push_back(suffix_string); + suffix_types_.push_back(type); + suffix_sources_.push_back(source); + // suffix_values_.push_back(); + } + + const Index* GetIntegerSuffixValues(std::string suffix_string, Suffix_Source source) const; + + const Number* GetNumberSuffixValues(std::string suffix_string, Suffix_Source source) const; + + std::vector<Index> GetIntegerSuffixValues(Index n, std::string suffix_string, Suffix_Source source) const; + + std::vector<Number> GetNumberSuffixValues(Index n, std::string suffix_string, Suffix_Source source) const; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AmplSuffixHandler(); + + /** Copy Constructor */ + AmplSuffixHandler(const AmplSuffixHandler&); + + /** Overloaded Equals Operator */ + void operator=(const AmplSuffixHandler&); + //@} + + mutable ASL_pfgh* asl_; + + SufDecl* suftab_; + + std::vector<std::string> suffix_ids_; + std::vector<Suffix_Type> suffix_types_; + std::vector<Suffix_Source> suffix_sources_; + + /** Method called by AmplTNLP to prepare the asl for the suffixes */ + void PrepareAmplForSuffixes(ASL_pfgh* asl); + + /** Method called by AmplTNLP to retrieve the suffixes from asl */ + // void RetrieveSuffixesFromAmpl(ASL_pfgh* asl); + + friend class AmplTNLP; + }; + + /** Class for storing a number of AMPL options that should be + * registered to the AMPL Solver library interface */ + class AmplOptionsList : public ReferencedObject + { + public: + enum AmplOptionType { + String_Option, + Number_Option, + Integer_Option, + WS_Option, /* this is for AMPL's internal wantsol callback */ + HaltOnError_Option /* this is for our setting of the nerror_ member */ + }; + + /** Ampl Option class, contains name, type and description for an + * AMPL option */ + class AmplOption : public ReferencedObject + { + public: + AmplOption(const std::string ipopt_option_name, + AmplOptionType type, + const std::string description); + + ~AmplOption() + { + delete [] description_; + } + + const std::string& IpoptOptionName() const + { + return ipopt_option_name_; + } + AmplOptionType Type() const + { + return type_; + } + char* Description() const + { + return description_; + } + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + AmplOption(); + + /** Copy Constructor */ + AmplOption(const AmplOption&); + + /** Overloaded Equals Operator */ + void operator=(const AmplOption&); + //@} + + const std::string ipopt_option_name_; + const AmplOptionType type_; + char* description_; + }; + + class PrivatInfo + { + public: + PrivatInfo(const std::string ipopt_name, + SmartPtr<OptionsList> options, + SmartPtr<const Journalist> jnlst, + void** nerror = NULL) + : + ipopt_name_(ipopt_name), + options_(options), + jnlst_(jnlst), + nerror_(nerror) + {} + const std::string& IpoptName() const + { + return ipopt_name_; + } + const SmartPtr<OptionsList>& Options() const + { + return options_; + } + const SmartPtr<const Journalist>& Jnlst() const + { + return jnlst_; + } + void** NError() + { + return nerror_; + } + private: + const std::string ipopt_name_; + const SmartPtr<OptionsList> options_; + const SmartPtr<const Journalist> jnlst_; + void** nerror_; + }; + + public: + /** Default Constructor */ + AmplOptionsList() + : + keywds_(NULL), + nkeywds_(0) + {} + + /** Destructor */ + ~AmplOptionsList(); + + /** Adding a new AMPL Option */ + void AddAmplOption(const std::string ampl_option_name, + const std::string ipopt_option_name, + AmplOptionsList::AmplOptionType type, + const std::string description) + { + SmartPtr<AmplOption> new_option = + new AmplOption(ipopt_option_name, type, description); + ampl_options_map_[ampl_option_name] = ConstPtr(new_option); + } + + /** Number of AMPL Options */ + Index NumberOfAmplOptions() + { + return (Index)ampl_options_map_.size(); + } + + /** ASL keywords list for the stored options. */ + void* Keywords(const SmartPtr<OptionsList>& options, + SmartPtr<const Journalist> jnlst, + void** nerror); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AmplOptionsList(); + + /** Copy Constructor */ + AmplOptionsList(const AmplOptionsList&); + + /** Overloaded Equals Operator */ + void operator=(const AmplOptionsList&); + //@} + + void MakeValidLatexString(std::string source, std::string& dest) const; + + void PrintLatex(SmartPtr<const Journalist> jnlst); + + /** map for storing registered AMPL options */ + std::map<std::string, SmartPtr<const AmplOption> > ampl_options_map_; + // AW: I think it should be with const like in the following line + // but with const the AIX compiler fails + // std::map<const std::string, SmartPtr<const AmplOption> > ampl_options_map_; + + /** pointer to the keywords */ + void* keywds_; + + /** Number of entries stored in keywds_ */ + Index nkeywds_; + }; + + /** Ampl Interface. + * Ampl Interface, implemented as a TNLP. + */ + class AmplTNLP : public TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor. */ + AmplTNLP(const SmartPtr<const Journalist>& jnlst, + const SmartPtr<OptionsList> options, + char**& argv, SmartPtr<AmplSuffixHandler> + suffix_handler = NULL, bool allow_discrete = false, + SmartPtr<AmplOptionsList> ampl_options_list = NULL, + const char* ampl_option_string = NULL, + const char* ampl_invokation_string = NULL, + const char* ampl_banner_string = NULL, + std::string* nl_file_content = NULL); + + /** Default destructor */ + virtual ~AmplTNLP(); + //@} + + /** Exceptions */ + DECLARE_STD_EXCEPTION(NONPOSITIVE_SCALING_FACTOR); + + /**@name methods to gather information about the NLP. These + * methods are overloaded from TNLP. See TNLP for their more + * detailed documentation. */ + //@{ + /** returns dimensions of the nlp. Overloaded from TNLP */ + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style); + + /** returns names and other meta data for the variables and constraints + * Overloaded from TNLP */ + virtual bool get_var_con_metadata(Index n, + StringMetaDataMapType& var_string_md, + IntegerMetaDataMapType& var_integer_md, + NumericMetaDataMapType& var_numeric_md, + Index m, + StringMetaDataMapType& con_string_md, + IntegerMetaDataMapType& con_integer_md, + NumericMetaDataMapType& con_numeric_md); + + /** returns bounds of the nlp. Overloaded from TNLP */ + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u); + + /** Returns the constraint linearity. + * array will be alocated with length n. (default implementation + * just return false and does not fill the array). */ + virtual bool get_constraints_linearity(Index m, + LinearityType* const_types); + + /** provides a starting point for the nlp variables. Overloaded + from TNLP */ + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, Number* lambda); + + /** evaluates the objective value for the nlp. Overloaded from TNLP */ + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value); + + /** evaluates the gradient of the objective for the + nlp. Overloaded from TNLP */ + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f); + + /** evaluates the constraint residuals for the nlp. Overloaded from TNLP */ + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g); + + /** specifies the jacobian structure (if values is NULL) and + * evaluates the jacobian values (if values is not NULL) for the + * nlp. Overloaded from TNLP */ + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values); + + /** specifies the structure of the hessian of the lagrangian (if + * values is NULL) and evaluates the values (if values is not + * NULL). Overloaded from TNLP */ + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, Index* iRow, + Index* jCol, Number* values); + + /** retrieve the scaling parameters for the variables, objective + * function, and constraints. */ + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling); + //@} + + /** @name Solution Methods */ + //@{ + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + //@} + + /** @name Method for quasi-Newton approximation information. */ + //@{ + virtual Index get_number_of_nonlinear_variables(); + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars); + //@} + + + /**@name Ampl specific methods */ + //@{ + /** Return the ampl solver object (ASL*) */ + ASL_pfgh* AmplSolverObject() + { + return asl_; + } + + /** Write the solution file. This is a wrapper for AMPL's + * write_sol. TODO Maybe this should be at a different place, or + * collect the numbers itself? */ + void write_solution_file(const std::string& message) const; + + /** ampl orders the variables like (continuous, binary, integer). + * This method gives the number of binary and integer variables. + * For details, see Tables 3 and 4 in "Hooking Your Solver to + * AMPL" + */ + void get_discrete_info(Index& nlvb_, + Index& nlvbi_, + Index& nlvc_, + Index& nlvci_, + Index& nlvo_, + Index& nlvoi_, + Index& nbv_, + Index& niv_) const; + //@} + + /** A method for setting the index of the objective function to be + * considered. This method must be called after the constructor, + * and before anything else is called. It can only be called + * once, and if there is more than one objective function in the + * AMPL model, it MUST be called. */ + void set_active_objective(Index obj_no); + + /**@name Methods to set meta data for the variables + * and constraints. These values will be passed on + * to the TNLP in get_var_con_meta_data + */ + //@{ + void set_string_metadata_for_var(std::string tag, std::vector<std::string> meta_data) + { + var_string_md_[tag] = meta_data; + } + + void set_integer_metadata_for_var(std::string tag, std::vector<Index> meta_data) + { + var_integer_md_[tag] = meta_data; + } + + void set_numeric_metadata_for_var(std::string tag, std::vector<Number> meta_data) + { + var_numeric_md_[tag] = meta_data; + } + + void set_string_metadata_for_con(std::string tag, std::vector<std::string> meta_data) + { + con_string_md_[tag] = meta_data; + } + + void set_integer_metadata_for_con(std::string tag, std::vector<Index> meta_data) + { + con_integer_md_[tag] = meta_data; + } + + void set_numeric_metadata_for_con(std::string tag, std::vector<Number> meta_data) + { + con_numeric_md_[tag] = meta_data; + } + //@} + + /** Method for returning the suffix handler */ + SmartPtr<AmplSuffixHandler> get_suffix_handler() + { + return suffix_handler_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + AmplTNLP(); + + /** Copy Constructor */ + AmplTNLP(const AmplTNLP&); + + /** Overloaded Equals Operator */ + void operator=(const AmplTNLP&); + //@} + + /** Journlist */ + SmartPtr<const Journalist> jnlst_; + + /** pointer to the main ASL structure */ + ASL_pfgh* asl_; + + /** Sign of the objective fn (1 for min, -1 for max) */ + double obj_sign_; + + /**@name Problem Size Data*/ + //@{ + Index nz_h_full_; // number of nonzeros in the full_x hessian + /* the rest of the problem size data is available easily through the ampl variables */ + //@} + + /**@name Internal copies of data */ + //@{ + /** Solution Vectors */ + Number* x_sol_; + Number* z_L_sol_; + Number* z_U_sol_; + Number* g_sol_; + Number* lambda_sol_; + Number obj_sol_; + //@} + + /**@name Flags to track internal state */ + //@{ + /** true when the objective value has been calculated with the + * current x, set to false in apply_new_x, and set to true in + * internal_objval */ + bool objval_called_with_current_x_; + /** true when the constraint values have been calculated with the + * current x, set to false in apply_new_x, and set to true in + * internal_conval */ + bool conval_called_with_current_x_; + /** true when we have called hesset */ + bool hesset_called_; + /** true when set_active_objective has been called */ + bool set_active_objective_called_; + //@} + + /** Pointer to the Oinfo structure */ + void* Oinfo_ptr_; + + /** nerror flag passed to ampl calls - set to NULL to halt on error */ + void* nerror_; + + /** Suffix Handler */ + SmartPtr<AmplSuffixHandler> suffix_handler_; + + /** Make the objective call to ampl */ + bool internal_objval(const Number* x, Number& obj_val); + + /** Make the constraint call to ampl*/ + bool internal_conval(const Number* x, Index m, Number* g=NULL); + + /** Internal function to update the internal and ampl state if the + * x value changes */ + bool apply_new_x(bool new_x, Index n, const Number* x); + + /** Method for obtaining the name of the NL file and the options + * set from AMPL. Returns a pointer to a char* with the name of + * the stub */ + char* get_options(const SmartPtr<OptionsList>& options, + SmartPtr<AmplOptionsList>& ampl_options_list, + const char* ampl_option_string, + const char* ampl_invokation_string, + const char* ampl_banner_string, char**& argv); + + /** returns true if the ampl nerror code is ok */ + bool nerror_ok(void* nerror); + + /** calls hesset ASL function */ + void call_hesset(); + + /** meta data to pass on to TNLP */ + StringMetaDataMapType var_string_md_; + IntegerMetaDataMapType var_integer_md_; + NumericMetaDataMapType var_numeric_md_; + StringMetaDataMapType con_string_md_; + IntegerMetaDataMapType con_integer_md_; + NumericMetaDataMapType con_numeric_md_; + }; + + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/BonAmplInterface.hpp b/thirdparty/linux/include/coin/BonAmplInterface.hpp new file mode 100644 index 0000000..055004c --- /dev/null +++ b/thirdparty/linux/include/coin/BonAmplInterface.hpp @@ -0,0 +1,64 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2004, 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + +#ifndef BonminAmplInterface_H +#define BonminAmplInterface_H +#include "BonOsiTMINLPInterface.hpp" +#include "BonAmplTMINLP.hpp" + +class BM_lp; +namespace Bonmin +{ + /** Class for providing an Osi interface to Ipopt with an ampl nl file as input. */ + class AmplInterface: public OsiTMINLPInterface + { + public: + /** Default constructor */ + /** Default constructor only available for Bonmin's friends and child classes.*/ + AmplInterface(); + /**@name Methods to input a problem */ + //@{ + virtual void readAmplNlFile(char **& argv, Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + std::string* nl_file_content = NULL); + //@} + /** Copy constructor */ + AmplInterface(const AmplInterface &other); + /// Clone + virtual OsiSolverInterface * clone(bool CopyData = true); + + /// Destructor + virtual ~AmplInterface(); + + + /** Fast access to AmplTMINLP */ + const AmplTMINLP * amplModel() const + { + return GetRawPtr(amplTminlp_); + } + /** To set some application specific defaults. */ + virtual void setAppDefaultOptions(Ipopt::SmartPtr<Ipopt::OptionsList> Options); + + protected: + /** Read variables and row names in .col and .row files.*/ + void readNames() ; + + /** TMINLP problem (the original problem usually an AmplTMINLP).*/ + Ipopt::SmartPtr<Bonmin::AmplTMINLP> amplTminlp_; + + private: + /** Write the ampl solution file or write a bonmin one?*/ + int writeAmplSolFile_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonAmplSetup.hpp b/thirdparty/linux/include/coin/BonAmplSetup.hpp new file mode 100644 index 0000000..152d1b4 --- /dev/null +++ b/thirdparty/linux/include/coin/BonAmplSetup.hpp @@ -0,0 +1,32 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/15/2007 + +#ifndef BonAmplSetup_H +#define BonAmplSetup_H +#include "BonBonminSetup.hpp" +#include "BonAmplInterface.hpp" + +namespace Bonmin +{ + class BonminAmplSetup: public BonminSetup + { + public: + /** initialize bonmin with ampl model using the command line arguments.*/ + void initialize(char **& argv); + /** initialize bonmin with ampl model using the command line arguments and an existing OsiTMINLPInterface.*/ + void initialize(AmplInterface &toFill, char **& argv); + /** initialize bonmin with ampl model using the command line arguments reading options and nl file from strings.*/ + void initialize(char **& argv, std::string& opt_file_content, std::string& nl_file_content, bool createContinuousSolver /*= false*/); + /** initialize bonmin with ampl model using the command line arguments and an existing OsiTMINLPInterface reading options and nl file from strings.*/ + void initialize(AmplInterface &toFill, char **& argv, std::string& opt_file_content, std::string& nl_file_content, bool createContinuousSolver = true); + /** For Bcp. Initialize the passed OsiTMINLP interface with ampl model using the options and nl files contained in two strings.*/ + void fillOsiInterface(AmplInterface &toFill, char **& argv, std::string & options, std::string & nl, bool createContinuousSolver = true); + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonAmplTMINLP.hpp b/thirdparty/linux/include/coin/BonAmplTMINLP.hpp new file mode 100644 index 0000000..0a566a2 --- /dev/null +++ b/thirdparty/linux/include/coin/BonAmplTMINLP.hpp @@ -0,0 +1,332 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2004, 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 12/01/2004 + +#ifndef __IPAMPLTMINLP_HPP__ +#define __IPAMPLTMINLP_HPP__ + +#include "BonTMINLP.hpp" +#include "IpSmartPtr.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiCuts.hpp" +#include "BonRegisteredOptions.hpp" +#include "BonTypes.hpp" + +/* non Ipopt forward declaration */ +struct ASL_pfgh; +struct SufDecl; +struct SufDesc; + + +// Declarations, so that we don't have to include the Ipopt AMPL headers +namespace Ipopt +{ + class AmplSuffixHandler; + class AmplOptionsList; + class AmplTNLP; +} + +namespace Bonmin +{ + + /** Ampl MINLP Interface. + * Ampl MINLP Interface, implemented as a TMINLP. + * This interface creates a AmplTNLP and also retrieves + * the information about the binary and integer variables + */ + class AmplTMINLP : public TMINLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + AmplTMINLP(const Ipopt::SmartPtr<const Ipopt::Journalist>& jnlst, + const Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + const Ipopt::SmartPtr<Ipopt::OptionsList> options, + char**& argv, + Ipopt::AmplSuffixHandler* suffix_handler = NULL, + const std::string& appName = "bonmin", + std::string* nl_file_content = NULL); + + virtual void Initialize(const Ipopt::SmartPtr<const Ipopt::Journalist>& jnlst, + const Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + const Ipopt::SmartPtr<Ipopt::OptionsList> options, + char**& argv, + Ipopt::AmplSuffixHandler* suffix_handler =NULL, + const std::string& appName = "bonmin", + std::string* nl_file_content = NULL); + + /** read the branching priorities from ampl suffixes.*/ + void read_priorities(); + + /** read the sos constraints from ampl suffixes */ + void read_sos(); + + /** Read suffixes which indicate which constraints are convex.*/ + void read_convexities(); + + /** Read suffixes used to apply perspective in OA to some of the constraints.*/ + void read_onoff(); + + /** Read suffixes on objective functions for upper bounding*/ + void read_obj_suffixes(); + + /** Default constructor.*/ + AmplTMINLP(); + + virtual AmplTMINLP * createEmpty() + { + AmplTMINLP * tminlp = new AmplTMINLP; + return tminlp; + } + + /** destructor */ + virtual ~AmplTMINLP(); + //@} + + /** Return the ampl solver object (ASL*) */ + const ASL_pfgh* AmplSolverObject() const; + + + /**@name methods to gather information about the NLP. These + * methods are overloaded from TMINLP. See TMINLP for their more + * detailed documentation. */ + //@{ + /** returns dimensions of the nlp. Overloaded from TMINLP */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, + Ipopt::TNLP::IndexStyleEnum& index_style); + + /** returns the vector of variable types */ + virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types); + + /** return the variables linearity (linear or not)*/ + virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType * var_types); + + /** Returns the constraint linearity. + * array should be alocated with length at least n.*/ + virtual bool get_constraints_linearity(Ipopt::Index m, + Ipopt::TNLP::LinearityType* const_types); + + /** returns bounds of the nlp. Overloaded from TMINLP */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** provides a starting point for the nlp variables. Overloaded + from TMINLP */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, Ipopt::Number* lambda); + + /** evaluates the objective value for the nlp. Overloaded from TMINLP */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** evaluates the gradient of the objective for the + nlp. Overloaded from TMINLP */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** evaluates the constraint residuals for the nlp. Overloaded from TMINLP */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** specifies the jacobian structure (if values is NULL) and + * evaluates the jacobian values (if values is not NULL) for the + * nlp. Overloaded from TMINLP */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** specifies the structure of the hessian of the lagrangian (if + * values is NULL) and evaluates the values (if values is not + * NULL). Overloaded from TMINLP */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index* iRow, + Ipopt::Index* jCol, Ipopt::Number* values); + + /** compute the value of a single constraint */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** compute the structure or values of the gradient for one + constraint */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + //@} + + /** @name Solution Methods */ + //@{ + /** Called after optimizing to return results to ampl. + * Status code is put into solve_result_num according to the table below. + * <table> + * <tr> <td> <b> <center> Code </center> </b> </td> <td> <b> <center> Status </center> </b> </td> </tr> + * <tr> <td> 3 </td> <td> Integer optimal </td> </tr> + * <tr> <td> 220 </td> <td> problem is proven infeasible. </td> </tr> + * <tr> <td> 421 </td> <td> limit reached or user interrupt with integer feasible solution found. </td> </tr> + * <tr> <td> 410 </td> <td> limit reached or user interrupt without any integer feasible solution. </td> </tr> + * <tr> <td> 500 </td> <td> error. </td> </tr> + * <caption> Status codes for optimization. </caption> + * </table> + * */ + virtual void finalize_solution(TMINLP::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value); + + /** Write the solution using ampl's write_sol (called by finalize_solution).*/ + void write_solution(const std::string & message, const Ipopt::Number *x_sol); + //@} + + //@} + + + virtual const BranchingInfo * branchingInfo() const + { + return &branch_; + } + + virtual const SosInfo * sosConstraints() const + { + return &sos_; + } + + virtual const PerturbInfo* perturbInfo() const + { + return &perturb_info_; + } + + /** @name User callbacks */ + //@{ + /** Additional application specific options.*/ + virtual void fillApplicationOptions(Ipopt::AmplOptionsList* amplOptList) + {} + //@} + + + /** This methods gives the linear part of the objective function */ + virtual void getLinearPartOfObjective(double * obj); + + + /** Do we have an alternate objective for upper bounding?*/ + virtual bool hasUpperBoundingObjective() + { + return upperBoundingObj_ != -1; + } + + /** This method to returns the value of an alternative objective function for + upper bounding (if one has been declared by using the prefix UBObj).*/ + virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x, + Ipopt::Number& obj_value); + + /** Get accest to constraint convexities.*/ + virtual bool get_constraint_convexities(int m, TMINLP::Convexity * constraints_convexities)const + { + if (constraintsConvexities_ != NULL) { + CoinCopyN(constraintsConvexities_, m, constraints_convexities); + } + else { + CoinFillN(constraints_convexities, m, TMINLP::Convex); + } + return true; + } + /** Get dimension information on nonconvex constraints.*/ + virtual bool get_number_nonconvex(int & number_non_conv, int & number_concave) const + { + number_non_conv = numberNonConvex_; + number_concave = numberSimpleConcave_; + return true; + } + /** Get array describing the constraints marked nonconvex in the model.*/ + virtual bool get_constraint_convexities(int number_non_conv, MarkedNonConvex * non_convexes) const + { + assert(number_non_conv == numberNonConvex_); + CoinCopyN( nonConvexConstraintsAndRelaxations_, number_non_conv, non_convexes); + return true; + } + /** Fill array containing indices of simple concave constraints.*/ + virtual bool get_simple_concave_constraints(int number_concave, SimpleConcaveConstraint * simple_concave) const + { + assert(number_concave == numberSimpleConcave_); + CoinCopyN(simpleConcaves_, numberSimpleConcave_, simple_concave); + return true; + } + + /** Say if problem has a linear objective (for OA) */ + virtual bool hasLinearObjective() + { + return hasLinearObjective_; + } + + /** Access array describing onoff constraint.*/ + virtual const int * get_const_xtra_id() const{ + return c_extra_id_(); + } + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + AmplTMINLP(const AmplTMINLP&); + + /** Overloaded Equals Operator */ + void operator=(const AmplTMINLP&); + //@} + /** Name of application.*/ + std::string appName_; + + /** Index of the objective to use for upper bounding*/ + int upperBoundingObj_; + /** pointer to the internal AmplTNLP */ + Ipopt::AmplTNLP* ampl_tnlp_; + /** Journalist */ + Ipopt::SmartPtr<const Ipopt::Journalist> jnlst_; + + /** Storage of branching priorities information.*/ + BranchingInfo branch_; + /** Storage of sos constraints */ + SosInfo sos_; + /** Storage for perturbation radii */ + PerturbInfo perturb_info_; + /** Store a suffix handler.*/ + Ipopt::SmartPtr<Ipopt::AmplSuffixHandler> suffix_handler_; + + /** Store constraints types.*/ + TMINLP::Convexity * constraintsConvexities_; + + /** Store onoff information.*/ + vector<int> c_extra_id_; + + /** Ipopt::Number of nonConvex constraints.*/ + int numberNonConvex_; + /** Store marked non-convex constraints and their relaxations.*/ + MarkedNonConvex * nonConvexConstraintsAndRelaxations_; + /** Ipopt::Number of simpleConcave constraints.*/ + int numberSimpleConcave_; + /** Store simple concave constraints descriptions.*/ + SimpleConcaveConstraint * simpleConcaves_; + + /** Flag to indicate if objective function is linear */ + bool hasLinearObjective_; + + /** Flag to say if AMPL solution file should be written.*/ + int writeAmplSolFile_; + }; +} // namespace Ipopt + +#endif + diff --git a/thirdparty/linux/include/coin/BonArraysHelpers.hpp b/thirdparty/linux/include/coin/BonArraysHelpers.hpp new file mode 100644 index 0000000..a397fb8 --- /dev/null +++ b/thirdparty/linux/include/coin/BonArraysHelpers.hpp @@ -0,0 +1,52 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#include "CoinHelperFunctions.hpp" +#ifndef BonArraysHelpers_H +#define BonArraysHelpers_H + +namespace Bonmin { +template <class X> void +resizeAndCopyArray(X *& array, unsigned int oldSize, unsigned int newSize){ + if(newSize == 0){ + if(oldSize > 0){ + delete [] array; + array = NULL; + } + return; + } + X * buffy = new X[newSize]; + if(oldSize > 0){ + if(oldSize < newSize) + CoinCopyN(array, oldSize, buffy); + else + CoinCopyN(array, newSize, buffy); + delete [] array; + } + array = buffy; +} + +template <class X> void +resizeAndCopyArray(X *& array, unsigned int oldSize, unsigned int newSize, + unsigned int& capacity){ + if(newSize > capacity){ + X * buffy = new X[newSize]; + if(oldSize > 0){ + CoinCopyN(array, oldSize, buffy); + delete [] array; + } + array = buffy; + } + else { + newSize = oldSize; + } +} +}// Ends Bonmin namespace +#endif + diff --git a/thirdparty/linux/include/coin/BonAuxInfos.hpp b/thirdparty/linux/include/coin/BonAuxInfos.hpp new file mode 100644 index 0000000..8643a57 --- /dev/null +++ b/thirdparty/linux/include/coin/BonAuxInfos.hpp @@ -0,0 +1,110 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/23/2007 + +#ifndef BonAuxInfos_H +#define BonAuxInfos_H +#include <cstdlib> +#include <vector> +#include "OsiAuxInfo.hpp" +#include "CoinSmartPtr.hpp" +#include "BonTypes.hpp" + + +namespace Bonmin { + + + /** Bonmin class for passing info between components of branch-and-cuts.*/ +class AuxInfo : public OsiBabSolver { +public: + /** Default constructor.*/ + AuxInfo(int type); + + /** Constructor from OsiBabSolver.*/ + AuxInfo(const OsiBabSolver &other); + + /** Copy constructor.*/ + AuxInfo(const AuxInfo &other); + + /** Destructor.*/ + virtual ~AuxInfo(); + + /** Virtual copy constructor.*/ + virtual OsiAuxInfo * clone() const; + + /** Declare the node to be feasible.*/ + void setFeasibleNode(){ + infeasibleNode_ = false;} + + /** Declare the node to be infeasible.*/ + void setInfeasibleNode(){ + infeasibleNode_ = true;} + + /** Say if current node is found feasible by cut generators.*/ + bool infeasibleNode(){ + return infeasibleNode_;} + + /** Get solution found by nlp solver (or NULL if none found).*/ + const double * nlpSolution(){ + + if(hasNlpSolution_) + return nlpSolution_; + else + return NULL; + } + + /** Get objective value of nlp solution found, or +infinity if none exists */ + double nlpObjValue (); + + /** Pass a solution found by an nlp solver.*/ + void setNlpSolution(const double * sol, int numcols, double objValue); + + /** Say if has an nlp solution*/ + void setHasNlpSolution(bool b){ + hasNlpSolution_ = b;} + /** get the best solution computed with alternative objective function.*/ + const std::vector<double>& bestSolution2() const + { + return (*bestSolution2_)(); + } + /** return objective value of the best solution computed with alternative + objective function.*/ + double bestObj2() const + { + return (*bestObj2_)(); + } + /** Set an alternate objective value.*/ + void setBestObj2(double o) + { + (*bestObj2_)() = o; + } + void setBestSolution2(int n, double * d) + { + (*bestSolution2_)().clear(); + (*bestSolution2_)().insert((*bestSolution2_)().end(),d, d+n); + } +protected: + /** Say if current node was found infeasible during cut generation*/ + bool infeasibleNode_; + /** value of the objective function of this nlp solution */ + double objValue_; + /** nlp solution found by heuristic if any.*/ + double * nlpSolution_; + /** numcols_ gives the size of nlpSolution_.*/ + int numcols_; + /** say if has a solution.*/ + bool hasNlpSolution_; + /** Stores the solution with alternate objective.*/ + Coin::SmartPtr< SimpleReferenced<std::vector<double> > > bestSolution2_; + /** Alternate solution objective value.*/ + Coin::SmartPtr< SimpleReferenced<double> > bestObj2_; + }; +}/* End namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonBabInfos.hpp b/thirdparty/linux/include/coin/BonBabInfos.hpp new file mode 100644 index 0000000..4ff4b37 --- /dev/null +++ b/thirdparty/linux/include/coin/BonBabInfos.hpp @@ -0,0 +1,57 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/23/2007 + +#ifndef BonBabInfos_H +#define BonBabInfos_H +#include <stdlib.h> +#include "BonAuxInfos.hpp" + +namespace Bonmin +{ + class Bab; + /** Bonmin class for passing info between components of branch-and-cuts.*/ + class BabInfo : public Bonmin::AuxInfo + { + public: + /** Default constructor.*/ + BabInfo(int type); + + /** Constructor from OsiBabSolver.*/ + BabInfo(const OsiBabSolver &other); + + /** Copy constructor.*/ + BabInfo(const BabInfo &other); + + /** Destructor.*/ + virtual ~BabInfo(); + + /** Virtual copy constructor.*/ + virtual OsiAuxInfo * clone() const; + + /** Set pointer to the branch-and-bound algorithm (to access CbcModel).*/ + void setBabPtr(Bab * babPtr) + { + babPtr_ = babPtr; + } + + /** Pointer to the branch-and-bound algorithm (to access CbcModel).*/ + Bab * babPtr() + { + return babPtr_; + } + + bool hasSolution() const{ + return bestSolution_ != NULL;} + protected: + /** Pointer to branch-and-bound algorithm.*/ + Bab * babPtr_; + }; +}/* End namespace.*/ + +#endif diff --git a/thirdparty/linux/include/coin/BonBabSetupBase.hpp b/thirdparty/linux/include/coin/BonBabSetupBase.hpp new file mode 100644 index 0000000..c51c67c --- /dev/null +++ b/thirdparty/linux/include/coin/BonBabSetupBase.hpp @@ -0,0 +1,386 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/12/2007 + +#ifndef BabSetupBase_H +#define BabSetupBase_H + +#include <string> +#include <list> +#include "CglCutGenerator.hpp" +#include "CbcHeuristic.hpp" +#include "OsiChooseVariable.hpp" +#include "BonOsiTMINLPInterface.hpp" +#include "IpSmartPtr.hpp" +#include "BonTMINLP2OsiLP.hpp" + +namespace Bonmin +{ + /** A class to have all elements necessary to setup a branch-and-bound.*/ + class BabSetupBase + { + public: + /** Type for cut generation method with its frequency and string identification. */ + struct CuttingMethod + { + int frequency; + std::string id; + CglCutGenerator * cgl; + bool atSolution; + bool normal; + bool always; + CuttingMethod(): + atSolution(false), + normal(true), + always(false) + {} + + CuttingMethod(const CuttingMethod & other): + frequency(other.frequency), + id(other.id), + cgl(other.cgl), + atSolution(other.atSolution), + normal(other.normal), + always(other.always) + {} + }; + /** Type for heuristic method with its string identification. */ + struct HeuristicMethod + { + std::string id; + CbcHeuristic* heuristic; + HeuristicMethod() + {} + + HeuristicMethod(const HeuristicMethod & other): + id(other.id), + heuristic(other.heuristic) + {} + }; + typedef std::list<CuttingMethod> CuttingMethods; + typedef std::list<HeuristicMethod > HeuristicMethods; + + /** Strategies for comparing the nodes on the heap. */ + enum NodeComparison { + bestBound = 0 /** Best bound*/, + DFS /** Depth First Search*/, + BFS /** Best First Search */, + dynamic /** Dynamic strategy, see <a href="http://www.coin-or.org/Doxygen/Cbc/class_cbc_branch_dynamic_decision.html"> + CbcBranchActual.hpp </a> for explanations.*/, + bestGuess /** Best guessed integer solution is subtree below, based on pseudo costs */ + }; + + /** Strategies for traversing the tree.*/ + enum TreeTraversal { + HeapOnly=0 /** Only using the heap, uses CbcTree.*/, + DiveFromBest /** dive from top node of the heap untill it gets to a leaf of the tree. Uses Bonmin::CbcDiver.*/, + ProbedDive /** Eplore two kids before following on dive.*/, + DfsDiveFromBest /** dive from top node of the heap with more elaborate strategy (see options doc). Uses Bonmin::CbcDfsDiver.*/, + DfsDiveDynamic /** Same as DfsDiveFromBest, but after a prescribed number of integer solution are found switch to best-bound and if too many node switches to depth-first. Uses Bonmin::CbcDfsDiver.*/ + }; + + + /** @name Enums for optionslist parameters */ + enum VarSelectStra_Enum { + MOST_FRACTIONAL=0, + STRONG_BRANCHING, + RELIABILITY_BRANCHING, +#ifdef BONMIN_CURVATURE_BRANCHING + CURVATURE_ESTIMATOR, +#endif + QP_STRONG_BRANCHING, + LP_STRONG_BRANCHING, + NLP_STRONG_BRANCHING, + OSI_SIMPLE, + OSI_STRONG, + RANDOM + }; + + /** Parameters represented by an integer. */ + enum IntParameter{ + BabLogLevel = 0 /** Log level of main branch-and-bound*/, + BabLogInterval/** Display information every logIntervval nodes.*/, + MaxFailures /** Max number of failures in a branch.*/, + FailureBehavior /** Behavior of the algorithm in the case of a failure.*/, + MaxInfeasible /** Max number of consecutive infeasible problem in a branch + before fathoming.*/, + NumberStrong /** Number of candidates for strong branching.*/, + MinReliability /** Minimum reliability before trust pseudo-costs.*/, + MaxNodes /** Global node limit.*/, + MaxSolutions /** limit on number of integer feasible solution.*/, + MaxIterations /** Global iteration limit. */, + SpecialOption /** Spetial option in particular for Cbc. */, + DisableSos /** Consider or not SOS constraints.*/, + NumCutPasses/** Number of cut passes at nodes.*/, + NumCutPassesAtRoot/** Number of cut passes at nodes.*/, + RootLogLevel/** Log level for root relaxation.*/, + NumberIntParam /** Dummy end to size table*/ + }; + + + /** Parameters represented by a double.*/ + enum DoubleParameter{ + CutoffDecr = 0 /** Amount by which cutoff is incremented */, + Cutoff /** cutoff value */, + AllowableGap /** Stop if absolute gap is less than this. */, + AllowableFractionGap /** Stop if relative gap is less than this.*/, + IntTol /** Integer tolerance.*/, + MaxTime /** Global time limit. */, + NumberDoubleParam /** Dummy end to size table*/ + }; + + /** Default constructor. */ + BabSetupBase(const CoinMessageHandler * handler = NULL); + + /** Construct from existing tminlp. */ + BabSetupBase(Ipopt::SmartPtr<TMINLP> tminlp, const CoinMessageHandler * handler = NULL); + /** Construct from existing application.*/ + BabSetupBase(Ipopt::SmartPtr<TNLPSolver> app); + /** Construct from existing TMINLP interface.*/ + BabSetupBase(const OsiTMINLPInterface& nlp); + /** Copy but uses an other nlp.*/ + BabSetupBase(const BabSetupBase &setup, + OsiTMINLPInterface &nlp); + + /** Copy but uses an other nlp.*/ + BabSetupBase(const BabSetupBase &setup, + OsiTMINLPInterface &nlp, + const std::string &prefix); + + /** Copy constructor. */ + BabSetupBase(const BabSetupBase & other); + + /** virtual copy constructor. */ + virtual BabSetupBase * clone() const = 0; + + /** Make a copy with solver replace by one passed .*/ + virtual BabSetupBase *clone(OsiTMINLPInterface&nlp)const; + /** Virtual destructor. */ + virtual ~BabSetupBase(); + + /** @name Methods to initialize algorithm with various inputs. */ + /** @{ */ + /** use existing TMINLP interface (containing the options).*/ + void use(const OsiTMINLPInterface& nlp); + /** Read options (if not done before) and create interface using tminlp.*/ + void use(Ipopt::SmartPtr<TMINLP> tminlp ); + /** use specific instanciation of a TMINLP2TNLP.*/ + void use(Ipopt::SmartPtr<TMINLP2TNLP> prob); + /** Set the non-linear solver used */ + void setNonlinearSolver(OsiTMINLPInterface * s) + { + nonlinearSolver_ = s; + } + /** @} */ + + /** @name Methods to manipulate options. */ + /** @{ */ + /** Register all the options for this algorithm instance.*/ + virtual void registerOptions(); + /** Setup the defaults options for this algorithm. */ + virtual void setBabDefaultOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + {} + /** Register all the options for this algorithm instance.*/ + static void registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Get the options from default text file (bonmin.opt) if don't already have them.*/ + virtual void readOptionsFile() + { + if (readOptions_) return; + readOptionsFile("bonmin.opt"); + } + + /** Get the options from given fileName */ + void readOptionsFile(std::string fileName); + + /** Get the options from long string containing all.*/ + void readOptionsString(std::string opt_string); + + /** Get the options from stream.*/ + void readOptionsStream(std::istream& is); + + /** May print documentation of options if options print_options_documentation is set to yes.*/ + void mayPrintDoc(); + + + /** Get prefix to use for options.*/ + const char * prefix() const { + return prefix_.c_str(); + } + + /** Set the value for options, output...*/ + void setOptionsAndJournalist(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist) + { + options_ = options; + roptions_ = roptions; + journalist_ = journalist; + } + + /** Initialize the options and the journalist.*/ + void initializeOptionsAndJournalist(); + /** @} */ + + /** @name Elements of the branch-and-bound setup.*/ + /** @{ */ + /** Pointer to the non-linear solver used.*/ + OsiTMINLPInterface * nonlinearSolver() + { + return nonlinearSolver_; + } + /** Pointer to the continuous solver to use for relaxations. */ + OsiSolverInterface * continuousSolver() + { + return continuousSolver_; + } + /** list of cutting planes methods to apply with their frequencies. */ + CuttingMethods& cutGenerators() + { + return cutGenerators_; + } + /** list of Heuristic methods to use. */ + HeuristicMethods& heuristics() + { + return heuristics_; + } + /** branching method to use. */ + OsiChooseVariable * branchingMethod() + { + return branchingMethod_; + } + /** Method used to compare nodes. */ + NodeComparison& nodeComparisonMethod() + { + return nodeComparisonMethod_; + } + /** Method used to traverse tree.*/ + TreeTraversal treeTraversalMethod() + { + return treeTraversalMethod_; + } + /** Return value of integer parameter. */ + int getIntParameter(const IntParameter &p) const + { + return intParam_[p]; + } + /** Return value of double parameter.*/ + double getDoubleParameter(const DoubleParameter &p) const + { + return doubleParam_[p]; + } + /** Return value of integer parameter. */ + void setIntParameter(const IntParameter &p, const int v) + { + intParam_[p] = v; + } + /** Return value of double parameter.*/ + void setDoubleParameter(const DoubleParameter &p, const double v) + { + doubleParam_[p] = v; + } + /** @} */ + + /** Get the values of base parameters from the options stored.*/ + void gatherParametersValues() + { + gatherParametersValues(options_); + } + /** Get the values of the base parameters from the passed options.*/ + void gatherParametersValues(Ipopt::SmartPtr<Ipopt::OptionsList> options); + /** Acces storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist() + { + return journalist_; + } + + /** Acces list of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options() + { + return options_; + } + + /** Access registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions() + { + return roptions_; + } + + /** Access to extra objects.*/ + const vector<OsiObject *>& objects() const + { + return objects_; + } + + /** Access to extra objects.*/ + vector<OsiObject *>& objects() + { + return objects_; + } + + void addCutGenerator(CuttingMethod & cg){ + cutGenerators_.push_back(cg); + } + + void set_linearizer(TMINLP2OsiLP * linearizer){ + linearizer_ = linearizer; + } + + protected: + /** Set the priorities into OsiTMINLPInterface when needed.*/ + void setPriorities(); + /** Add SOS constraints to OsiTMINLPInterface when needed.*/ + void addSos(); + + /** storage of integer parameters.*/ + int intParam_[NumberIntParam]; + /** default values for int parameters.*/ + static int defaultIntParam_[NumberIntParam]; + /** storage of double parameters. */ + double doubleParam_[NumberDoubleParam]; + /** default values for double parameters. */ + static double defaultDoubleParam_[NumberDoubleParam]; + /** Storage of the non-linear solver used.*/ + OsiTMINLPInterface * nonlinearSolver_; + /** Storage of continuous solver.*/ + OsiSolverInterface * continuousSolver_; + /** Method to linearize MINLPs */ + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer_; + /** Cut generation methods. */ + CuttingMethods cutGenerators_; + /** Heuristic methods. */ + HeuristicMethods heuristics_; + /** Branching method.*/ + OsiChooseVariable * branchingMethod_; + /** Node comparison method.*/ + NodeComparison nodeComparisonMethod_; + /** Tree traversal method.*/ + TreeTraversal treeTraversalMethod_; + /** Extra object to add to Cbc (not OsiObjects).*/ + vector<OsiObject *> objects_; + + + /** Storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist_; + + /** List of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + + /** Registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions_; + + /** flag to say if option file was read.*/ + bool readOptions_; + /** separate message handler.*/ + CoinMessageHandler * messageHandler_; + /** Prefix to use when reading options.*/ + std::string prefix_; + }; +}/* End namespace Bonmin. */ +#endif + diff --git a/thirdparty/linux/include/coin/BonBonminSetup.hpp b/thirdparty/linux/include/coin/BonBonminSetup.hpp new file mode 100644 index 0000000..c1ea003 --- /dev/null +++ b/thirdparty/linux/include/coin/BonBonminSetup.hpp @@ -0,0 +1,95 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/13/2007 +#ifndef BonminSetup_H +#define BonminSetup_H +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** Type of algorithms which can be used.*/ + enum Algorithm{ + Dummy=-1/** Dummy value before initialization.*/, + B_BB=0/** Bonmin's Branch-and-bound.*/, + B_OA=1/** Bonmin's Outer Approximation Decomposition.*/, + B_QG=2/** Bonmin's Quesada & Grossmann branch-and-cut.*/, + B_Hyb=3/** Bonmin's hybrid outer approximation.*/, + B_Ecp=4/** Bonmin's implemantation of ecp cuts based branch-and-cut a la FilMINT.*/, + B_IFP=5/** Bonmin's implemantation of iterated feasibility pump for MINLP.*/ + }; + /* Bonmin algorithm setup. */ + class BonminSetup : public BabSetupBase + { + public: + /** Default constructor. */ + BonminSetup(const CoinMessageHandler * handler = NULL); + /** Copy constructor. */ + BonminSetup(const BonminSetup & other); + + /** Copy but uses an other nlp.*/ + BonminSetup(const BonminSetup &setup, + OsiTMINLPInterface &nlp); + + /** Copy but uses another nlp and algorithm.*/ + BonminSetup(const BonminSetup &setup, + OsiTMINLPInterface &nlp, + const std::string & prefix); + /** virtual copy constructor. */ + virtual BabSetupBase * clone() const + { + return new BonminSetup(*this); + } + /** Make a copy with solver replace by one passed .*/ + // virtual BabSetupBase *clone(OsiTMINLPInterface&nlp)const{ + // return new BonminSetup(*this, nlp); + // } + /** Make a copy with solver replace by one passed .*/ + BonminSetup *clone(OsiTMINLPInterface&nlp)const{ + return new BonminSetup(*this, nlp); + } + /** Make a copy but take options with different prefix.*/ + BonminSetup *clone(OsiTMINLPInterface &nlp, const std::string & prefix)const{ + return new BonminSetup(*this, nlp, prefix); + } + virtual ~BonminSetup() + {} + /** @name Methods to instantiate: Registering and retrieving options and initializing everything. */ + /** @{ */ + /** Register all the options for this algorithm instance.*/ + virtual void registerOptions(); + /** Setup the defaults options for this algorithm. */ + virtual void setBabDefaultOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + {} + /** @} */ + /** Register all bonmin type executable options.*/ + static void registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + /** Initialize, read options and create appropriate bonmin setup.*/ + void initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver = true); + /** Initialize, read options and create appropriate bonmin setup.*/ + void initialize(const OsiTMINLPInterface& nlpSi, bool createContinuousSolver = true); + /** Get the algorithm used.*/ + Bonmin::Algorithm getAlgorithm(); + + void addCutGenerator(CuttingMethod & cg){ + BabSetupBase::addCutGenerator(cg); + } + protected: + /** Register standard MILP cut generators. */ + static void registerMilpCutGenerators(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + /** Add milp cut generators according to options.*/ + void addMilpCutGenerators(); + /** Initialize a plain branch-and-bound.*/ + void initializeBBB(); + /** Initialize a branch-and-cut with some OA.*/ + void initializeBHyb(bool createContinuousSolver = false); + private: + Algorithm algo_; + }; +}/** end namespace Bonmin*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonBranchingTQP.hpp b/thirdparty/linux/include/coin/BonBranchingTQP.hpp new file mode 100644 index 0000000..f718419 --- /dev/null +++ b/thirdparty/linux/include/coin/BonBranchingTQP.hpp @@ -0,0 +1,197 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2006, 2008 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Andreas Waechter, International Business Machines Corporation +// (derived from BonTMINLP2TNLP.hpp) 12/22/2006 + +#ifndef __BONBRANCHINGTQP_HPP__ +#define __BONBRANCHINGTQP_HPP__ + +#include "BonTMINLP2TNLP.hpp" + +namespace Bonmin +{ + /** This is an adapter class that converts a TMINLP2TNLP object into + * a TNLP, which is now just a QP. The QP is the linear quadratic + * of the TNLP at the optimal point. The purpose of the + * BranchingTQP is that it is used in a strong-branching framework, + * strong branching is only done for the QP approximation of the + * TNLP, not on the TNLP itself. The variables of the QP are the + * displacement from the reference point. + */ + class BranchingTQP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + BranchingTQP(Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp); + + /** Default destructor */ + virtual ~BranchingTQP(); + //@} + + /**@name methods to gather information about the NLP, only those + * that need to be overloaded from TNLP */ + //@{ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + /** Returns the constraint linearity. array should be alocated + * with length at least n. Since this is a QP, all constraints are + * linear.*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types); + /** Method called by Ipopt to get the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Accessor Methods for QP data */ + //@{ + const Ipopt::Number ObjVal() + { + return obj_val_; + } + const Ipopt::Number* ObjGrad() + { + return obj_grad_; + } + const Ipopt::Number* ObjHessVals() + { + return obj_hess_; + } + const Ipopt::Index* ObjHessIRow() + { + return obj_hess_irow_; + } + const Ipopt::Index* ObjHessJCol() + { + return obj_hess_jcol_; + } + const Ipopt::Number* ConstrRhs() + { + return g_vals_; + } + const Ipopt::Number* ConstrJacVals() + { + return g_jac_; + } + const Ipopt::Index* ConstrJacIRow() + { + return g_jac_irow_; + } + const Ipopt::Index* ConstrJacJCol() + { + return g_jac_jcol_; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + BranchingTQP(); + + /** Copy Constructor */ + BranchingTQP(const BranchingTQP&); + + /** Overloaded Equals Operator */ + void operator=(const BranchingTQP&); + //@} + + /** @name static information about the QP's constraints and + * objective function */ + //@{ + Ipopt::Number obj_val_; + Ipopt::Number* obj_grad_; + Ipopt::Number* obj_hess_; + Ipopt::Index* obj_hess_irow_; + Ipopt::Index* obj_hess_jcol_; + Ipopt::Number* g_vals_; + Ipopt::Number* g_jac_; + Ipopt::Index* g_jac_irow_; + Ipopt::Index* g_jac_jcol_; + //@} + + /** @name Data from the MINLP */ + //@{ + Ipopt::Index n_; + Ipopt::Index m_; + Ipopt::Index nnz_jac_g_; + Ipopt::Index nnz_h_lag_; + Ipopt::TNLP::IndexStyleEnum index_style_; + //@} + + /** Copy of original x_sol_. x_sol_ is changed after the first QP + * has been solved once. */ + Ipopt::Number* x_sol_copy_; + + /** Copy of original duals_sol_. duals_sol_ is changed after the + * first QP has been solved once. */ + Ipopt::Number* duals_sol_copy_; + + /** Pointer to the TMINLP2TNLP model which stores the bounds + * information */ + Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/BonCbc.hpp b/thirdparty/linux/include/coin/BonCbc.hpp new file mode 100644 index 0000000..caa178e --- /dev/null +++ b/thirdparty/linux/include/coin/BonCbc.hpp @@ -0,0 +1,127 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/19/2007 + +#ifndef BonCbc_H +#define BonCbc_H + +//#include "BonBabSetupBase.hpp" +#include "CbcModel.hpp" + +namespace Bonmin +{ + class BabSetupBase; + class Bab + { + public: + /** Integer optimization return codes.*/ + enum MipStatuses {FeasibleOptimal /** Optimum solution has been found and its optimality proved.*/, + ProvenInfeasible /** Problem has been proven to be infeasible.*/, + Feasible /** An integer solution to the problem has been found.*/, + UnboundedOrInfeasible /*Coninuous relaxation is unbounded.*/, + NoSolutionKnown/** No feasible solution to the problem is known*/, + NumMipStats}; + + + /** Constructor.*/ + Bab(); + /** destructor.*/ + virtual ~Bab(); + /** Perform a branch-and-bound using given setup.*/ + virtual void branchAndBound(BabSetupBase & s); + + /**operator() performs the branchAndBound*/ + virtual void operator()(BabSetupBase & s); + + /**operator() performs the branchAndBound*/ + virtual void operator()(BabSetupBase * s){ + operator()(*s);} + + /** get the best solution known to the problem (is optimal if MipStatus is FeasibleOptimal). + if no solution is known returns NULL.*/ + const double * bestSolution() const + { + return bestSolution_; + } + /** return objective value of the bestSolution */ + double bestObj() const + { + return bestObj_; + } + + /** return Mip Status */ + MipStatuses mipStatus() const + { + return mipStatus_; + } + + /** return the best known lower bound on the objective value*/ + double bestBound(); + + /** return the total number of nodes explored.*/ + int numNodes() const + { + return numNodes_; + } + /** return the total number of iterations in the last mip solved.*/ + int iterationCount() + { + return mipIterationCount_; + } + /** returns the value of the continuous relaxation. */ + double continuousRelaxation() + { + return continuousRelaxation_; + } + + /** virtual callback function to eventually modify objects for integer variable + (replace with user set). This is called after CbcModel::findIntegers */ + virtual void replaceIntegers(OsiObject ** objects, int numberObjects) + {} + /** Get cbc model used to solve. */ + const CbcModel& model() const + { + return model_; + } + + /** Get cbc model used to solve as non-const, in case we want to + change options before things happen */ + CbcModel& model() + { + return model_; + } + + protected: + /** Stores the solution of MIP. */ + double * bestSolution_; + + /** Status of the mip solved*/ + MipStatuses mipStatus_; + /** objValue of MIP */ + double bestObj_; + /** best known (lower) bound.*/ + double bestBound_; + /** Continuous relaxation of the problem */ + double continuousRelaxation_; + /** Number of nodes enumerated.*/ + int numNodes_; + /** get total number of iterations in last mip solved.*/ + int mipIterationCount_; + /** CbcModel used to solve problem.*/ + CbcModel model_; + /** Message handler for CbcModel. */ + CoinMessageHandler * modelHandler_; + /** \brief OsiObjects of the model. + * this is not null if and only if there are some non-simple-integer branching objects such as SOS constraints. + * It is up to Bab to pass them over to appropriate components of the algorithm. */ + OsiObject** objects_; + /** number of objects.*/ + int nObjects_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonCbcLpStrategy.hpp b/thirdparty/linux/include/coin/BonCbcLpStrategy.hpp new file mode 100644 index 0000000..6d16e91 --- /dev/null +++ b/thirdparty/linux/include/coin/BonCbcLpStrategy.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + + +#ifndef CbcOaStrategy_HPP +#define CbcOaStrategy_HPP + +#include "CbcStrategy.hpp" +#include <string> +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** A class to setup default strategy for Cbc specifying which cut generators to use.*/ + class CbcStrategyChooseCuts : public CbcStrategyDefault { + public: + /** Default constructor.*/ + CbcStrategyChooseCuts(); + /** Constructor with a setup. */ + CbcStrategyChooseCuts(BabSetupBase &s, const std::string & prefix); + /** Copy constructor.*/ + CbcStrategyChooseCuts(const CbcStrategyChooseCuts &other); + /** Virtual copy constructor.*/ + CbcStrategy * clone() const{ + return new CbcStrategyChooseCuts(*this); + } + /** Setup strategy.*/ + void setup(BabSetupBase &s, const std::string &prefix); + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + + private: + /** Generators frequencies.*/ + int gen_freqs_[6]; + /** Flag to say which cut generators to use.*/ + int genFlag_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonCbcNlpStrategy.hpp b/thirdparty/linux/include/coin/BonCbcNlpStrategy.hpp new file mode 100644 index 0000000..b642ad0 --- /dev/null +++ b/thirdparty/linux/include/coin/BonCbcNlpStrategy.hpp @@ -0,0 +1,98 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// John J. Forrest, International Business Machines Corporation +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + +#ifndef BonCbcNlpStrategy_H +#define BonCbcNlpStrategy_H + +#include "CbcStrategy.hpp" +class CglPreProcess; +class CbcNodeInfo; +class CbcNode; +class CoinWarmStartDiff; + + +namespace Bonmin +{ + class CbcNlpStrategy : public CbcStrategy + { + public: + + // Default Constructor + CbcNlpStrategy (int maxFailures, + int maxInfeasibles, + int pretendFailIsInfeasible); + + // Copy constructor + CbcNlpStrategy ( const CbcNlpStrategy &); + + // Destructor + virtual ~CbcNlpStrategy (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Return a new Full node information pointer (descendant of CbcFullNodeInfo) + virtual CbcNodeInfo * fullNodeInfo(CbcModel * model,int numberRowsAtContinuous) const; + /// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo) + virtual CbcNodeInfo * partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds,const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) const; + /** After a CbcModel::resolve this can return a status + -1 no effect + 0 treat as optimal + 1 as 0 but do not do any more resolves (i.e. no more cuts) + 2 treat as infeasible + */ + virtual int status(CbcModel * model, CbcNodeInfo * parent, int whereFrom); + /// set maximum number of consecutive failures in a branch before giving up + inline void setMaxFailure(int value) + { + maxFailure_ = value; + } + /// maximum number of consecutive infeasible nodes before giving up + inline void setMaxInfeasible(int value) + { + maxInfeasible_ = value; + } + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model,int modelLogLevel); + /// Other stuff e.g. strong branching and preprocessing + virtual void setupOther(CbcModel & model); + + bool hasFailed() + { + return hasFailed_; + } + protected: + // Data + /// did we fail? + bool hasFailed_; + /// maximum number of consecutive failures in a branch before giving up + int maxFailure_; + /// maximum number of consecutive infeasible nodes before giving up + int maxInfeasible_; + /** If yes when a problem is not solved (failed to be solved) + will pretend that it is infeasible. */ + int pretendFailIsInfeasible_; + + private: + /// Illegal Assignment operator + CbcNlpStrategy & operator=(const CbcNlpStrategy& rhs); + + }; +} + +#endif diff --git a/thirdparty/linux/include/coin/BonCbcNode.hpp b/thirdparty/linux/include/coin/BonCbcNode.hpp new file mode 100644 index 0000000..9594124 --- /dev/null +++ b/thirdparty/linux/include/coin/BonCbcNode.hpp @@ -0,0 +1,133 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// John J. Forrest, International Business Machines Corporation +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + +#ifndef BonminCbcNode_H +#define BonminCbcNode_H + +#include "CbcNode.hpp" +#include "BonRegisteredOptions.hpp" + + +namespace Bonmin +{ + /** \brief Holds information for recreating a subproblem by incremental change + from the parent for Bonmin + + A BonminBonminCbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. + */ + + class BonCbcFullNodeInfo : public CbcFullNodeInfo + { + + public: + friend class BonCbcPartialNodeInfo; + // Default Constructor + BonCbcFullNodeInfo (); + + // Constructor from current state + BonCbcFullNodeInfo (CbcModel * model, int numberRowsAtContinuous); + + // Copy constructor + BonCbcFullNodeInfo ( const BonCbcFullNodeInfo &); + + // Destructor + ~BonCbcFullNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + + /**Method called when all direct sons have been explored to flush + useless warm start information.*/ + virtual void allBranchesGone(); + + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + inline int getSequenceOfInfeasiblesSize() + { + return sequenceOfInfeasiblesSize_; + } + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + inline int getSequenceOfUnsolvedSize() + { + return sequenceOfUnsolvedSize_; + } + /** Register all the options for class instance.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /* Data values */ + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + int sequenceOfInfeasiblesSize_; + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + int sequenceOfUnsolvedSize_; + private: + + /// Illegal Assignment operator + BonCbcFullNodeInfo & operator=(const BonCbcFullNodeInfo& rhs); + }; + + /** \brief Holds information for recreating a subproblem by incremental change + from the parent for + + A BonminCbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. + */ + + class BonCbcPartialNodeInfo : public CbcPartialNodeInfo + { + + public: + // Default Constructor + BonCbcPartialNodeInfo (); + + // Constructor from current state + BonCbcPartialNodeInfo (CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds,const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) ; + + // Copy constructor + BonCbcPartialNodeInfo ( const BonCbcPartialNodeInfo &); + + // Destructor + ~BonCbcPartialNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + + /**Method called when all direct sons have been explored to flush + useless warm start information.*/ + virtual void allBranchesGone(); + + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + inline int getSequenceOfInfeasiblesSize() + { + return sequenceOfInfeasiblesSize_; + } + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + inline int getSequenceOfUnsolvedSize() + { + return sequenceOfUnsolvedSize_; + } + private: + /* Data values */ + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + int sequenceOfInfeasiblesSize_; + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + int sequenceOfUnsolvedSize_; + private: + + /// Illegal Assignment operator + BonCbcPartialNodeInfo & operator=(const Bonmin::BonCbcPartialNodeInfo& rhs); + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonChooseVariable.hpp b/thirdparty/linux/include/coin/BonChooseVariable.hpp new file mode 100644 index 0000000..82e7575 --- /dev/null +++ b/thirdparty/linux/include/coin/BonChooseVariable.hpp @@ -0,0 +1,345 @@ +// Copyright (C) 2006, 2008 International Business Machines +// Corporation and others. All Rights Reserved. +#ifndef BonChooseVariable_H +#define BonChooseVariable_H + +#include "OsiChooseVariable.hpp" +#ifdef BONMIN_CURVATURE_BRANCHING +#include "BonCurvatureEstimator.hpp" +#endif +#include "BonOsiTMINLPInterface.hpp" +#include "CoinMessageHandler.hpp" +#include "BonBabSetupBase.hpp" +// Forward declaration +class CbcModel; + +#define OLD_USEFULLNESS + +namespace Bonmin +{ + + class HotInfo : public OsiHotInfo { + public: + /// Default constructor + HotInfo(); + + /// Constructor from usefull information + HotInfo( OsiSolverInterface * solver, + const OsiBranchingInformation *info, + const OsiObject * const * objects, int whichObject); + + /// Copy constructor + HotInfo(const HotInfo & other); + + /// Assignment operator + HotInfo & operator=(const HotInfo & rhs); + + /// Clone + virtual OsiHotInfo * clone() const; + + /// Destructor + virtual ~HotInfo(); + + /// Fill in some usefull information after a strong branching is done: + int updateInformation( const OsiSolverInterface * solver, const OsiBranchingInformation * info, + OsiChooseVariable * choose); + + /// up infeasibility + double upInfeasibility() const{ + return infeasibilities_[1]; + } + + /// down infeasibility + double downInfeasibility() const{ + return infeasibilities_[0]; + } + + + /// Set the down infeasibility + void setUpInfeasibility(double x){ + assert(branchingObject_->numberBranches()==2); + infeasibilities_[1] = x; + } + + /// Set the down infeasibility + void setDownInfeasibility(double x){ + assert(branchingObject_->numberBranches()==2); + infeasibilities_[0] = x; + } + private: + /// infeasibilities of children + vector<double> infeasibilities_; + }; + + /** This class chooses a variable to branch on + + This is the base class for the branching rules in Bonmin (inherits + from OsiChooseVariable). This class implements a simple strong branching algorithm where the changes in the objective + value induced by branching on a specific object are estimated with the pure virtual function fill_changes. + */ + + class BonChooseVariable : public OsiChooseVariable + { + protected: + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + virtual int doStrongBranching( OsiSolverInterface * solver, + OsiBranchingInformation *info, + int numberToDo, int returnCriterion); +#ifndef OLD_USEFULLNESS + /** Criterion applied to sort candidates.*/ + enum CandidateSortCriterion { + DecrPs = 0, + IncrPs, + DecrInfeas, + IncrInfeas}; +#endif + + /** Statuses for strong branching candidates.*/ + enum StrongStatus{ + NotDone=-1, + Feasible/** Child is proven feasible.*/, + Infeasible /** Child is proven infeasible.*/, + NotFinished /** Child is not finished.*/}; + public: + /** \name Message handling.*/ + /** @{ */ + enum Messages_Types { + PS_COST_HISTORY = 0, + PS_COST_MULT, + PS_COST_ESTIMATES, + CANDIDATE_LIST, + CANDIDATE_LIST2, + CANDIDATE_LIST3, + SB_START, + SB_HEADER, + SB_RES, + BRANCH_VAR, + CHOSEN_VAR, + UPDATE_PS_COST, + BON_CHOOSE_MESSAGES_DUMMY_END + }; + + class Messages : public CoinMessages + { + public: + Messages(); + }; + + void passInMessageHandler(CoinMessageHandler * handler) { + int logLevel = handler_->logLevel(); + delete handler_; + handler_ = handler->clone(); + handler_->setLogLevel(logLevel); + } + + CoinMessageHandler& message(Messages_Types type) const { + return handler_->message(type, messages_); + } + /** @} */ + + + + enum DoStrongReturnStatuses{ + provenInfeasible = -1 /** One branch has two infeasible children.*/, + doneNoFixing /** All done no variable can be fixed.*/, + doneCanFix /** Several variable can be fixed.*/, + interuptedCanFix /** Interupted and found a variable to fix.*/, + maxTime /** Interupted because of time limit.*/}; + + /** Return statuses for chooseVariable.*/ + enum chooseVariableReturnStatuses{ + infeasibleNode = -1/** Node has been proven infeasible.*/, + hasCandidate /** Normal termination, found a variable to branch on.*/, + feasibleNode /** All variable are feasible, the node is feasible.*/, + canFixAndStrongBranch /** Found variable to fix and also has remaining candidate for strong branching.*/, + canFixAndBranch/** Found variable to fix and also has a (non-strong) branching candidate.*/, + canFixNoCandidate /** Can fix variables but does not have strong branching candidates.*/ + }; + /// Constructor from solver (so we can set up arrays etc) + BonChooseVariable (BabSetupBase& b, const OsiSolverInterface* solver); + + /// Copy constructor + BonChooseVariable (const BonChooseVariable &); + + /// Assignment operator + BonChooseVariable & operator= (const BonChooseVariable& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~BonChooseVariable (); + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Helper functions for setupList and chooseVariable */ + double maxminCrit(const OsiBranchingInformation* info) const; + void computeMultipliers(double& upMult, double& downMult) const; + double computeUsefulness(const double MAXMIN_CRITERION, + const double upMult, const double dowMult, + const double value, + const OsiObject* object, int i, + double& value2) const; + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation(const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif + + /** Method for setting CbcModel, which is used to get statusOfSearch */ + void setCbcModel(CbcModel* cbc_model) + { + cbc_model_ = cbc_model; + } + + void setOnlyPseudoWhenTrusted(bool only_pseudo_when_trusted) + { + only_pseudo_when_trusted_ = only_pseudo_when_trusted; + } + + + /** Access to pseudo costs storage.*/ + const OsiPseudoCosts & pseudoCosts() const{ + return pseudoCosts_;} + + /** Access to pseudo costs storage.*/ + OsiPseudoCosts & pseudoCosts() { + return pseudoCosts_;} + protected: + + /// Holding on the a pointer to the journalist + Ipopt::SmartPtr<Ipopt::Journalist> jnlst_; + + /// verbosity level + int bb_log_level_; + + /** Stores strong branching results.*/ + vector<HotInfo> results_; + + /** Determine status of strong branching solution.*/ + int determineStatus(OsiSolverInterface * solver) const { + if (solver->isProvenOptimal()) + return 0; // optimal + else if (solver->isIterationLimitReached() + &&!solver->isDualObjectiveLimitReached()) + return 2; // unknown + else + return 1; // infeasible + } + + private: + /** Default Constructor, forbiden for some reason.*/ + BonChooseVariable (); + + /** Global time limit for algorithm. */ + double time_limit_; + + /** Starting time of algorithm.*/ + double start_time_; + protected: + /// CbcModel, used to get status of search + CbcModel* cbc_model_; + + /** Flag indicating whether we don't want to mix strong branching + * and pseudo costs during the decision which variable to branch + * on */ + bool only_pseudo_when_trusted_; + + /** Number of variables put into the list because there were not + * trusted */ + int number_not_trusted_; + + /** Message handler.*/ + CoinMessageHandler * handler_; + + /** Messages.*/ + Messages messages_; + // ToDo: Make this options + /** @name Algoirithmic options */ + //@{ + /** maxmin weight in branching decision when no solution has been + * found yet */ + double maxmin_crit_no_sol_; + /** maxmin weight in branching decision when no solution has been + * found yet */ + double maxmin_crit_have_sol_; + /** fraction of branching candidates that are not trusted yet */ + double setup_pseudo_frac_; + /** number of times a branch has to happen so that it is trusted in + * setupList */ + int numberBeforeTrustedList_; + /** number of strong branching points at root node */ + int numberStrongRoot_; + /** backup of numberStrong_ before Root node solve */ + int numberStrongBackup_; + /** number of look-ahead strong-branching steps */ + int numberLookAhead_; +#ifndef OLD_USEFULLNESS + /** Criterion to use in setup list.*/ + CandidateSortCriterion sortCrit_; +#endif + /** Always strong branch that many first candidate in the list regardless of numberTrusted.*/ + int minNumberStrongBranch_; + /** Stores the pseudo costs. */ + OsiPseudoCosts pseudoCosts_; + /** Wether or not to trust strong branching results for updating pseudo costs.*/ + int trustStrongForPseudoCosts_; + + //@} + + /** detecting if this is root node */ + bool isRootNode(const OsiBranchingInformation *info) const; + + /** Stores the class name for throwing errors.*/ + static const std::string CNAME; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/BonCurvBranchingSolver.hpp b/thirdparty/linux/include/coin/BonCurvBranchingSolver.hpp new file mode 100644 index 0000000..83be1ac --- /dev/null +++ b/thirdparty/linux/include/coin/BonCurvBranchingSolver.hpp @@ -0,0 +1,77 @@ +// Copyright (C) 2006, 2007 International Business Machines +// Corporation and others. All Rights Reserved. +// +// +#error "BonCurvBranchingSolver not supported anymore" +#ifndef BonCurvBranchingSolver_H +#define BonCurvBranchingSolver_H + +#include "BonStrongBranchingSolver.hpp" +#include "BonCurvatureEstimator.hpp" + +namespace Bonmin +{ + + /** Implementation of BonChooseVariable for curvature-based braching. + */ + + class CurvBranchingSolver : public StrongBranchingSolver + { + + public: + + /// Constructor from solver (so we can set up arrays etc) + CurvBranchingSolver (OsiTMINLPInterface * solver); + + /// Copy constructor + CurvBranchingSolver (const CurvBranchingSolver &); + + /// Assignment operator + CurvBranchingSolver & operator= (const CurvBranchingSolver& rhs); + + /// Destructor + virtual ~CurvBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface); + + private: + /// Default Constructor + CurvBranchingSolver (); + + SmartPtr<CurvatureEstimator> cur_estimator_; + + /** @name Stuff for the curvature estimator */ + //@{ + bool new_bounds_; + bool new_x_; + bool new_mults_; + double* orig_d_; + double* projected_d_; + Number* x_l_orig_; + Number* x_u_orig_; + Number* g_l_orig_; + Number* g_u_orig_; + //@} + + /** @name Information about the problem */ + //@{ + int numCols_; + int numRows_; + const double* solution_; + const double* duals_; + double obj_value_; + //@} + + }; + +} + +#endif diff --git a/thirdparty/linux/include/coin/BonCutStrengthener.hpp b/thirdparty/linux/include/coin/BonCutStrengthener.hpp new file mode 100644 index 0000000..7e2b92f --- /dev/null +++ b/thirdparty/linux/include/coin/BonCutStrengthener.hpp @@ -0,0 +1,244 @@ +// Copyright (C) 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: BonCutStrengthener.hpp 2106 2015-01-20 10:33:55Z stefan $ +// +// Author: Andreas Waechter IBM 2007-03-29 + +#ifndef __BONCUTSTRENGTHENER_HPP__ +#define __BONCUTSTRENGTHENER_HPP__ + +#include "BonTMINLP.hpp" +#include "CoinPackedVector.hpp" +#include "BonTNLPSolver.hpp" + +namespace Bonmin +{ + enum CutStrengtheningType{ + CS_None=0, + CS_StrengthenedGlobal=1, + CS_UnstrengthenedGlobal_StrengthenedLocal=2, + CS_StrengthenedGlobal_StrengthenedLocal=3 + }; + + enum DisjunctiveCutType{ + DC_None=0, + DC_MostFractional=1 + }; + + /** Class for strengthening OA cuts, and generating additional ones. + */ + class CutStrengthener: public Ipopt::ReferencedObject + { + /** Class implementing the TNLP for strengthening one cut. We + * assume that the cut has a lower bound. */ + class StrengtheningTNLP: public Ipopt::TNLP { + public: + /** Contructor */ + StrengtheningTNLP(Ipopt::SmartPtr<TMINLP> tminlp, + const CoinPackedVector& cut, + bool lower_bound, + Ipopt::Index n, + const Ipopt::Number* starting_point, + const double* x_l_orig, + const double* x_u_orig, + Ipopt::Index constr_index, + Ipopt::Index nvar_constr /** Ipopt::Number of variables in constraint */, + const Ipopt::Index* jCol); + + /** Destructor */ + ~StrengtheningTNLP(); + + /**@name Overloaded from TNLP */ + //@{ + /** Method to return some info about the nlp */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + + /** Method to return the bounds for my problem */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Method to return the starting point for the algorithm */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method to return the objective value */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number& obj_value); + + /** Method to return the gradient of the objective */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number* grad_f); + + /** Method to return the constraint residuals */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Index m, Ipopt::Number* g); + + /** Method to return: + * 1) The structure of the jacobian (if "values" is NULL) + * 2) The values of the jacobian (if "values" is not NULL) + */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol, + Ipopt::Number* values); + + /** Method to return: + * 1) The structure of the hessian of the lagrangian (if "values" is NULL) + * 2) The values of the hessian of the lagrangian (if "values" is not NULL) + */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index* iRow, + Ipopt::Index* jCol, Ipopt::Number* values); + + //@} + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method for asking for the strengthened bound. */ + Ipopt::Number StrengthenedBound() const; + + private: + /**@name Methods to block default compiler methods. */ + //@{ + StrengtheningTNLP(); + StrengtheningTNLP(const StrengtheningTNLP&); + StrengtheningTNLP& operator=(const StrengtheningTNLP&); + //@} + + /** TMINLP (with current bounds) for which the cut it to be + * generated */ + const Ipopt::SmartPtr<TMINLP> tminlp_; + + /** Gradient of the (linear) objective function */ + Ipopt::Number* obj_grad_; + + /** Dimension of original problem */ + const Ipopt::Index n_orig_; + + /** Ipopt::Number of constraints in original problem */ + Ipopt::Index m_orig_; + + /** Starting point */ + Ipopt::Number* starting_point_; + + /** Full dimentional x which is used to call the TMINLP + * evaluation routines */ + Ipopt::Number* x_full_; + + /** Lower bounds for constraint variables */ + Ipopt::Number* x_l_; + + /** Upper bounds for constraint variables */ + Ipopt::Number* x_u_; + + /** Ipopt::Index of the constraint */ + const Ipopt::Index constr_index_; + + /** Ipopt::Number of variables appearing in the constraint */ + const Ipopt::Index nvar_constr_; + + /** List of variables appearing on the constraints */ + Ipopt::Index* var_indices_; + + /** Flag indicating if the cut has a lower or upper bound */ + bool lower_bound_; + + /** Flag indicating if we TNLP has been solved successfully */ + bool have_final_bound_; + + /** Final strengthened bound */ + Ipopt::Number strengthened_bound_; + + /** space for original gradient if objective function is handled */ + Ipopt::Number* grad_f_; + + /** Auxilliary method for updating the full x variable */ + void update_x_full(const Ipopt::Number *x); + }; + + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It is given a TNLP solver to solve the internal + * NLPs. */ + CutStrengthener(Ipopt::SmartPtr<TNLPSolver> tnlp_solver, + Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /** Destructor */ + virtual ~CutStrengthener(); + //@} + + /** Method for generating and strenghtening all desired cuts */ + bool ComputeCuts(OsiCuts &cs, + TMINLP* tminlp, + TMINLP2TNLP* problem, + const int gindex, CoinPackedVector& cut, + double& cut_lb, double& cut_ub, + const double g_val, const double g_lb, + const double g_ub, + int n, const double* x, + double infty); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CutStrengthener(); + + /** Copy Constructor */ + CutStrengthener(const CutStrengthener&); + + /** Overloaded Equals Operator */ + void operator=(const CutStrengthener&); + //@} + + /** Method for strengthening one cut. */ + bool StrengthenCut(Ipopt::SmartPtr<TMINLP> tminlp /** current TMINLP */, + int constr_index /** Ipopt::Index number of the constraint to be strengthened, -1 means objective function */, + const CoinPackedVector& row /** Cut to be strengthened */, + int n /** Ipopt::Number of variables */, + const double* x /** solution from node */, + const double* x_l /** Lower bounds for x in which should be valid. */, + const double* x_u /** Upper bounds for x in which should be valid. */, + double& lb, + double& ub); + + /** Method for generating one type of cut (strengthened or disjunctive) */ + bool HandleOneCut(bool is_tight, TMINLP* tminlp, + TMINLP2TNLP* problem, + const double* minlp_lb, + const double* minlp_ub, + const int gindex, CoinPackedVector& cut, + double& cut_lb, double& cut_ub, + int n, const double* x, + double infty); + + /** Object for solving the TNLPs */ + Ipopt::SmartPtr<TNLPSolver> tnlp_solver_; + + /** Type of OA cut strengthener */ + int cut_strengthening_type_; + /** What kind of disjuntion should be done */ + int disjunctive_cut_type_; + /** verbosity level for OA-related output */ + int oa_log_level_; + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/BonDiver.hpp b/thirdparty/linux/include/coin/BonDiver.hpp new file mode 100644 index 0000000..20a9fa6 --- /dev/null +++ b/thirdparty/linux/include/coin/BonDiver.hpp @@ -0,0 +1,424 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 09/01/2007 + +#ifndef BonDiver_H +#define BonDiver_H + +#include "BonminConfig.h" +#include "CbcCompareBase.hpp" +#include "CbcTree.hpp" +#include "IpRegOptions.hpp" +#include "IpOptionsList.hpp" +#include "CbcCompareActual.hpp" +#include "BonRegisteredOptions.hpp" +#include <list> +namespace Bonmin +{ + class BabSetupBase; + /** Class to do diving in the tree. Principle is that branch-and-bound follows current branch of the tree untill it + hits the bottom at which point it goes to the best candidate (according to CbcCompare) on the heap.*/ + class CbcDiver : public CbcTree + { + public: + /// Default constructor. + CbcDiver(); + + ///Copy constructor. + CbcDiver(const CbcDiver &rhs); + + /// Assignment operator. + CbcDiver & operator=(const CbcDiver &rhs); + + /// Destructor. + virtual ~CbcDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return (static_cast<int>(nodes_.size()) + (nextOnBranch_ != NULL) ); + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + + ///Don't know what this is yet? + virtual void endSearch() + { + nextOnBranch_ = NULL; + } + + ///Register the options of the method. + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); + + private: + /** Say if we are cleaning the tree (then only call CbcTree functions).*/ + bool treeCleaning_; + /** Noext node on the branch.*/ + CbcNode * nextOnBranch_; + /** Flag indicating if we want to stop diving based on the guessed + objective value and the cutoff value */ + bool stop_diving_on_cutoff_; + }; + + + /** Class to do probed diving in the tree. + * Principle is that branch-and-bound follows current branch of the tree by exploring the two children at each level + * and continuing the dive on the best one of the two. Untill it + * hits the bottom at which point it goes to the best candidate (according to CbcCompare) on the heap.*/ + class CbcProbedDiver : public CbcTree + { + public: + /// Default constructor. + CbcProbedDiver(); + + ///Copy constructor. + CbcProbedDiver(const CbcProbedDiver &rhs); + + /// Assignment operator. + CbcProbedDiver & operator=(const CbcProbedDiver &rhs); + + /// Destructor. + virtual ~CbcProbedDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return (static_cast<int>(nodes_.size()) + (nextOnBranch_ != NULL) + (candidateChild_ != NULL) ); + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + + ///Don't know what this is yet? + virtual void endSearch() + { + nextOnBranch_ = NULL; + } + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); + + private: + /** Say if we are cleaning the tree (then only call CbcTree functions).*/ + bool treeCleaning_; + /** Next node on the branch.*/ + CbcNode * nextOnBranch_; + /** Candidate child explored.*/ + CbcNode * candidateChild_; + /** Flag indicating if we want to stop diving based on the guessed + objective value and the cutoff value */ + bool stop_diving_on_cutoff_; + }; + + + /** A more elaborate diving class. First there are several modes which can be commanded by the Comparison class below. + In particular can command to dive to find solutions, to try to close the bound as possible or to limit the size of + the tree. + + The diving goes into the tree doing depth-first search until one of the following happens: + \li A prescibed \c maxDiveBacktrack_ number of backtracking are performed. + \li The guessed objective value of the current node is worst than the best incumbent. + \li The depth of the dive is bigger than \c maxDiveDepth_ + + In the first case all the nodes are put on the tree and the next node on top will be the top of the heap, in the + two latter case we just put the node on the tree and backtrack in the list of depth-first search nodes. + + \bug This won't work in a non-convex problem where objective does not decrease down branches. + */ + class CbcDfsDiver :public CbcTree + { + public: + enum ComparisonModes{ + Enlarge/** At the very beginning we might want to enlarge the tree just a bit*/, + FindSolutions, + CloseBound, + LimitTreeSize}; + /// Default constructor. + CbcDfsDiver(); + + ///Copy constructor. + CbcDfsDiver(const CbcDfsDiver &rhs); + + /// Assignment operator. + CbcDfsDiver & operator=(const CbcDfsDiver &rhs); + + /// Destructor. + virtual ~CbcDfsDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return static_cast<int>(nodes_.size()) + diveListSize_; + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + \bug This won't work in a non-convex problem where objective does not decrease down branches. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + +//#ifdef COIN_HAS_BONMIN + ///Register the options of the method. + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); +//#endif + ///Don't know what this is yet? + virtual void endSearch() + {} + + /** Changes the mode of comparison of the tree for "safety reasons" if the mode really changes we always + finish the current dive and put all the node back onto the heap.*/ + void setComparisonMode(ComparisonModes newMode); + /** get the mode of comparison of the tree.*/ + ComparisonModes getComparisonMode() + { + return mode_; + } + protected: + /**Flag to say that we are currently cleaning the tree and should work only + on the heap.*/ + int treeCleaning_; + /** List of the nodes in the current dive.*/ + std::list<CbcNode *> dive_; + /** Record dive list size for constant time access.*/ + int diveListSize_; + /** Depth of the node from which diving was started (we call this node the diving board).*/ + int divingBoardDepth_; + /** Last reported cutoff.*/ + double cutoff_; + /** number of backtracks done in current dive.*/ + int nBacktracks_; + /** \name Parameters of the method.*/ + /** @{ */ + /** Maximum depth until which we'll do a bredth-first-search.*/ + int maxDepthBFS_; + /** Maximum number of backtrack in one dive.*/ + int maxDiveBacktracks_; + /** Maximum depth to go from divingBoard.*/ + int maxDiveDepth_; + /** Current mode of the diving strategy.*/ + ComparisonModes mode_; + /** @} */ + private: + /** Pushes onto heap all the nodes with objective value > cutoff. */ + void pushDiveOntoHeap(double cutoff); + + }; + + class DiverCompare : public CbcCompareBase + { + public: + // Default Constructor + DiverCompare (): + CbcCompareBase(), + diver_(NULL), + numberSolToStopDive_(5), + numberNodesToLimitTreeSize_(1000000), + comparisonDive_(NULL), + comparisonBound_(NULL) + {} + + + virtual ~DiverCompare() + { + delete comparisonDive_; + delete comparisonBound_; + } + + // Copy constructor + DiverCompare ( const DiverCompare & rhs): + CbcCompareBase(rhs), + diver_(rhs.diver_), + numberSolToStopDive_(rhs.numberSolToStopDive_), + numberNodesToLimitTreeSize_(rhs.numberNodesToLimitTreeSize_), + comparisonDive_(rhs.comparisonDive_->clone()), + comparisonBound_(rhs.comparisonBound_->clone()) + {} + + // Assignment operator + DiverCompare & operator=( const DiverCompare& rhs) + { + if (this != &rhs) { + CbcCompareBase::operator=(rhs); + diver_ = rhs.diver_; + numberSolToStopDive_ = rhs.numberSolToStopDive_; + numberNodesToLimitTreeSize_ = rhs.numberNodesToLimitTreeSize_; + delete comparisonDive_; + delete comparisonBound_; + comparisonDive_ = NULL; + comparisonBound_ = NULL; + if (rhs.comparisonDive_) comparisonDive_ = rhs.comparisonDive_->clone(); + if (rhs.comparisonBound_) comparisonBound_ = rhs.comparisonBound_->clone(); + } + return *this; + } + + /// Clone + virtual CbcCompareBase * clone() const + { + return new DiverCompare(*this); + } + + /// This is test function + virtual bool test (CbcNode * x, CbcNode * y); + + /// Called after each new solution + virtual bool newSolution(CbcModel * model); + + /// Called after each new solution + virtual bool newSolution(CbcModel * model, + double objectiveAtContinuous, + int numberInfeasibilitiesAtContinuous); + + /** Called 1000 nodes. + * Return true if want tree re-sorted.*/ + virtual bool every1000Nodes(CbcModel * model,int numberNodes); + + /** Set the dfs diver to use.*/ + void setDiver(CbcDfsDiver * diver) + { + diver_ = diver; + } + + /** Set numberSolToStopDive_ */ + void setNumberSolToStopDive(int val) + { + numberSolToStopDive_ = val; + } + + /** Set numberNodesToLimitTreeSize_.*/ + void setNumberNodesToLimitTreeSize(int val) + { + numberNodesToLimitTreeSize_ = val; + } + + /** Set comparison method when diving.*/ + void setComparisonDive(const CbcCompareBase & val) + { + comparisonDive_ = val.clone(); + } + /** Set comparison method when closing bound.*/ + void setComparisonBound(const CbcCompareBase & val) + { + comparisonBound_ = val.clone(); + } + private: + /** Pointer to the CbcDfsDiver handling the tree.*/ + CbcDfsDiver * diver_; + /** Number of solution before we command diver_ to stop diving.*/ + int numberSolToStopDive_; + /** Number of nodes before we command diver_ to limit the tree size.*/ + int numberNodesToLimitTreeSize_; + /** Comparison method used in diving mode*/ + CbcCompareBase * comparisonDive_; + /** Comparison method used bound mode*/ + CbcCompareBase * comparisonBound_; + /** Comparison method used when limit tree size.*/ + CbcCompareDepth comparisonDepth_; + }; + +}/* Ends bonmin namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonDummyHeuristic.hpp b/thirdparty/linux/include/coin/BonDummyHeuristic.hpp new file mode 100644 index 0000000..5c3d7fa --- /dev/null +++ b/thirdparty/linux/include/coin/BonDummyHeuristic.hpp @@ -0,0 +1,53 @@ +// (C) Copyright Carnegie Mellon University 2005 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + +#ifndef BonDummyHeuristic_HPP +#define BonDummyHeuristic_HPP +#include "BonOsiTMINLPInterface.hpp" + +#include "CbcHeuristic.hpp" +namespace Bonmin +{ + class DummyHeuristic : public CbcHeuristic + { + public: + /// Default constructor + DummyHeuristic(OsiTMINLPInterface * si = NULL); + /// Usefull constructor + DummyHeuristic(CbcModel &model, OsiTMINLPInterface * si = NULL); + ///Copy constructor + DummyHeuristic( const DummyHeuristic ©): + CbcHeuristic(copy), + nlp_(copy.nlp_), + knowsSolution(copy.knowsSolution) + {} + /// Set nlp_ + void setNlp(OsiTMINLPInterface * si); + /// heuristic method + virtual int solution(double &solutionValue, double *betterSolution); + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + virtual CbcHeuristic * clone()const + { + return new DummyHeuristic(*this); + } + virtual void resetModel(CbcModel*) + {} + virtual bool shouldHeurRun(int whereFrom){ + return true;} + private: + /// Pointer to the Ipopt interface + OsiTMINLPInterface * nlp_; + /// Do I have a solution? + bool knowsSolution; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonDummyPump.hpp b/thirdparty/linux/include/coin/BonDummyPump.hpp new file mode 100644 index 0000000..45316c0 --- /dev/null +++ b/thirdparty/linux/include/coin/BonDummyPump.hpp @@ -0,0 +1,43 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonDummyPump_H +#define BonDummyPump_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class DummyPump:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + DummyPump(); + /** Constructor with setup.*/ + DummyPump(BonminSetup * setup); + + /** Copy constructor.*/ + DummyPump(const DummyPump &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new DummyPump(*this); + } + + /** Destructor*/ + virtual ~DummyPump(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/BonEcpCuts.hpp b/thirdparty/linux/include/coin/BonEcpCuts.hpp new file mode 100644 index 0000000..8f57038 --- /dev/null +++ b/thirdparty/linux/include/coin/BonEcpCuts.hpp @@ -0,0 +1,97 @@ +// (C) Copyright International Business Machines (IBM) 2006, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/20/2006 + +#ifndef BonECPCuts_HPP +#define BonECPCuts_HPP + +#include "BonOaDecBase.hpp" +#include "CglCutGenerator.hpp" +namespace Bonmin +{ + class EcpCuts: public OaDecompositionBase + { + public: + EcpCuts(BabSetupBase & b); + + /// Copy constructor + EcpCuts(const EcpCuts & copy): + OaDecompositionBase(copy), + objValue_(copy.objValue_), + numRounds_(copy.numRounds_), + abs_violation_tol_(copy.abs_violation_tol_), + rel_violation_tol_(copy.rel_violation_tol_), + beta_(copy.beta_) + {} + + /// clone + CglCutGenerator * clone() const + { + return new EcpCuts(*this); + } + + /// Destructor + virtual ~EcpCuts() + {} + /** Standard cut generation methods. */ + virtual void generateCuts(const OsiSolverInterface &si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()) const; + double doEcpRounds(OsiSolverInterface &si, + bool leaveSiUnchanged, + double* violation = NULL); + + void setNumRounds(int value) + { + numRounds_ = value; + } + + void setPropabilityFactor(double value) + { + beta_ = value; + } + + void setAbsViolationTolerance(double value) + { + abs_violation_tol_ = value; + } + void setRelViolationTolerance(double value) + { + rel_violation_tol_ = value; + } + + /** Register ecp cuts options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo &info) const + { + throw -1; + } + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const + { + return 0; + } + private: + /** Record obj value at final point of Ecp. */ + mutable double objValue_; + /** Record NLP infeasibility at final point of Ecp */ + mutable double violation_; + /** maximum number of iterations of generation. */ + int numRounds_; + /** absolute tolerance for NLP constraint violation to stop ECP rounds */ + double abs_violation_tol_; + /** relative tolerance for NLP constraint violation to stop ECP rounds */ + double rel_violation_tol_; + /** Factor for probability for skipping cuts */ + double beta_; + }; +} /* end namespace Bonmin.*/ +#endif diff --git a/thirdparty/linux/include/coin/BonExitCodes.hpp b/thirdparty/linux/include/coin/BonExitCodes.hpp new file mode 100644 index 0000000..74234b1 --- /dev/null +++ b/thirdparty/linux/include/coin/BonExitCodes.hpp @@ -0,0 +1,12 @@ +#ifndef BonExitCodes_H +#define BonExitCodes_H + + +namespace Bonmin{ + /** Some error codes for uncatachable errors.*/ +enum ErrorCodes{ + ERROR_IN_AMPL_SUFFIXES = 111, + UNSUPPORTED_CBC_OBJECT/** There is a CbcObject in the model which is not understood by Bonmin.*/ +}; +} +#endif diff --git a/thirdparty/linux/include/coin/BonFixAndSolveHeuristic.hpp b/thirdparty/linux/include/coin/BonFixAndSolveHeuristic.hpp new file mode 100644 index 0000000..e0c35ea --- /dev/null +++ b/thirdparty/linux/include/coin/BonFixAndSolveHeuristic.hpp @@ -0,0 +1,43 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonFixAndSolveHeuristic_H +#define BonFixAndSolveHeuristic_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class FixAndSolveHeuristic:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + FixAndSolveHeuristic(); + /** Constructor with setup.*/ + FixAndSolveHeuristic(BonminSetup * setup); + + /** Copy constructor.*/ + FixAndSolveHeuristic(const FixAndSolveHeuristic &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new FixAndSolveHeuristic(*this); + } + + /** Destructor*/ + virtual ~FixAndSolveHeuristic(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/BonGuessHeuristic.hpp b/thirdparty/linux/include/coin/BonGuessHeuristic.hpp new file mode 100644 index 0000000..c8c4e6f --- /dev/null +++ b/thirdparty/linux/include/coin/BonGuessHeuristic.hpp @@ -0,0 +1,46 @@ +// (C) Copyright International Business Machines 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Andreas Waechter IBM 2007-09-01 + +#ifndef BonGuessHeuristic_HPP +#define BonGuessHeuristic_HPP +#include "BonOsiTMINLPInterface.hpp" + +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class GuessHeuristic : public CbcHeuristic + { + public: + /// Usefull constructor + GuessHeuristic(CbcModel &model); + ///Copy constructor + GuessHeuristic( const GuessHeuristic ©): + CbcHeuristic(copy) + {} + + /// heuristic method providing guess, based on pseudo costs + virtual int solution(double &solutionValue, double *betterSolution); + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + virtual CbcHeuristic * clone()const + { + return new GuessHeuristic(*this); + } + virtual void resetModel(CbcModel*) + {} + private: + /// Default constructor + GuessHeuristic(); + + /// Assignment operator + GuessHeuristic & operator=(const GuessHeuristic& rhs); + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDive.hpp b/thirdparty/linux/include/coin/BonHeuristicDive.hpp new file mode 100644 index 0000000..71039d8 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDive.hpp @@ -0,0 +1,88 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDive_HPP +#define BonHeuristicDive_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class HeuristicDive : public CbcHeuristic + { + public: + /// Default constructor + HeuristicDive(); + + /// Constructor with setup + HeuristicDive(BonminSetup * setup); + + /// Copy constructor + HeuristicDive(const HeuristicDive ©); + + /// Destructor + ~HeuristicDive() {} + + /// Assignment operator + HeuristicDive & operator=(const HeuristicDive & rhs); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Set percentage of integer variables to fix at bounds + void setPercentageToFix(double value) + { percentageToFix_ = value; } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp) = 0; + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + /// Percentage of integer variables to fix at bounds + double percentageToFix_; + + private: + /// How often to do (code can change) + int howOften_; + + }; + + /// checks if the NLP relaxation of the problem is feasible + bool isNlpFeasible(TMINLP2TNLP* minlp, const double primalTolerance); + + /// Adjusts the primalTolerance in case some of the constraints are violated + void adjustPrimalTolerance(TMINLP2TNLP* minlp, double & primalTolerance); +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDiveFractional.hpp b/thirdparty/linux/include/coin/BonHeuristicDiveFractional.hpp new file mode 100644 index 0000000..a5efbc6 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDiveFractional.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveFractional_H +#define BonHeuristicDiveFractional_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDive.hpp" + +/** DiveFractional class + */ + +namespace Bonmin +{ + class HeuristicDiveFractional : public HeuristicDive { + public: + /// Default Constructor + HeuristicDiveFractional (); + + /// Constructor with setup + HeuristicDiveFractional(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveFractional(const HeuristicDiveFractional ©); + + /// Destructor + ~HeuristicDiveFractional() {} + + /// Assignment operator + HeuristicDiveFractional & operator=(const HeuristicDiveFractional & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDive::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDiveMIP.hpp b/thirdparty/linux/include/coin/BonHeuristicDiveMIP.hpp new file mode 100644 index 0000000..11da60a --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDiveMIP.hpp @@ -0,0 +1,83 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIP_HPP +#define BonHeuristicDiveMIP_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" +#include "CbcStrategy.hpp" +namespace Bonmin +{ + class SubMipSolver; + class HeuristicDiveMIP : public CbcHeuristic + { + public: +#if 0 + /// Default constructor + HeuristicDiveMIP(); +#endif + + /// Constructor with setup + HeuristicDiveMIP(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIP(const HeuristicDiveMIP ©); + + /// Destructor + ~HeuristicDiveMIP(); + + /// Assignment operator + HeuristicDiveMIP & operator=(const HeuristicDiveMIP & rhs); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Initialize method + void Initialize(BonminSetup * setup); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp) = 0; + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + private: + /// How often to do (code can change) + int howOften_; + /// A subsolver for MIP + SubMipSolver * mip_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDiveMIPFractional.hpp b/thirdparty/linux/include/coin/BonHeuristicDiveMIPFractional.hpp new file mode 100644 index 0000000..dae7b3f --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDiveMIPFractional.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIPFractional_H +#define BonHeuristicDiveMIPFractional_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDiveMIP.hpp" + +/** DiveMIPFractional class + */ + +namespace Bonmin +{ + class HeuristicDiveMIPFractional : public HeuristicDiveMIP { + public: + /// Default Constructor + HeuristicDiveMIPFractional (); + + /// Constructor with setup + HeuristicDiveMIPFractional(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIPFractional(const HeuristicDiveMIPFractional ©); + + /// Destructor + ~HeuristicDiveMIPFractional() {} + + /// Assignment operator + HeuristicDiveMIPFractional & operator=(const HeuristicDiveMIPFractional & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDiveMIP::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDiveMIPVectorLength.hpp b/thirdparty/linux/include/coin/BonHeuristicDiveMIPVectorLength.hpp new file mode 100644 index 0000000..c14ba30 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDiveMIPVectorLength.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIPVectorLength_H +#define BonHeuristicDiveMIPVectorLength_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDiveMIP.hpp" + +/** DiveMIPVectorLength class + */ + +namespace Bonmin +{ + class HeuristicDiveMIPVectorLength : public HeuristicDiveMIP { + public: + /// Default Constructor + HeuristicDiveMIPVectorLength (); + + /// Constructor with setup + HeuristicDiveMIPVectorLength(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIPVectorLength(const HeuristicDiveMIPVectorLength ©); + + /// Destructor + ~HeuristicDiveMIPVectorLength() + { + delete [] columnLength_; + } + + /// Assignment operator + HeuristicDiveMIPVectorLength & operator=(const HeuristicDiveMIPVectorLength & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDiveMIP::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// the number of nonzero elements in each column + int* columnLength_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicDiveVectorLength.hpp b/thirdparty/linux/include/coin/BonHeuristicDiveVectorLength.hpp new file mode 100644 index 0000000..90942a2 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicDiveVectorLength.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveVectorLength_H +#define BonHeuristicDiveVectorLength_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDive.hpp" + +/** DiveVectorLength class + */ + +namespace Bonmin +{ + class HeuristicDiveVectorLength : public HeuristicDive { + public: + /// Default Constructor + HeuristicDiveVectorLength (); + + /// Constructor with setup + HeuristicDiveVectorLength(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveVectorLength(const HeuristicDiveVectorLength ©); + + /// Destructor + ~HeuristicDiveVectorLength() + { + delete [] columnLength_; + } + + /// Assignment operator + HeuristicDiveVectorLength & operator=(const HeuristicDiveVectorLength & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDive::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// the number of nonzero elements in each column + int* columnLength_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicFPump.hpp b/thirdparty/linux/include/coin/BonHeuristicFPump.hpp new file mode 100644 index 0000000..e8381a0 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicFPump.hpp @@ -0,0 +1,111 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicFPump_HPP +#define BonHeuristicFPump_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class HeuristicFPump : public CbcHeuristic + { + public: + /// Default constructor + HeuristicFPump(); + + /// Constructor with setup + HeuristicFPump(BonminSetup * setup); + + /// Copy constructor + HeuristicFPump(const HeuristicFPump ©); + + /// Destructor + ~HeuristicFPump() {} + + /// Assignment operator + HeuristicFPump & operator=(const HeuristicFPump & rhs); + + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicFPump(*this); + } + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + void setSetup(BonminSetup * setup){ + setup_ = setup; + Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// Performs heuristic with add cust + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + + /** Register the options for this heuristic */ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + /** Norm of the objective function - either 1 or 2 */ + int objective_norm_; + + /// To enable advanced unstable stuff + int enableAdvanced_; + }; + + class RoundingFPump + { + public: + /// Default constructor + RoundingFPump(TMINLP2TNLP* minlp); + + /// Destructor + ~RoundingFPump(); + + /// Rounds the solution + void round(const double integerTolerance, + const double primalTolerance, + double* solution); + + private: + /// gutsOfConstructor + void gutsOfConstructor(); + + /// Pointer to problem + TMINLP2TNLP* minlp_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Jacobian of g + std::vector<std::pair<int, int> >* col_and_jac_g_; + + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/BonHeuristicLocalBranching.hpp b/thirdparty/linux/include/coin/BonHeuristicLocalBranching.hpp new file mode 100644 index 0000000..ac56a56 --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicLocalBranching.hpp @@ -0,0 +1,59 @@ +// (C) Copyright CNRS and International Business Machines Corporation +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// Joao Goncalves, International Business Machines Corporation +// +// Date : 06/18/2008 + +#ifndef BonHeuristicLocalBranching_H +#define BonHeuristicLocalBranching_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class HeuristicLocalBranching:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + HeuristicLocalBranching(); + /** Constructor with setup.*/ + HeuristicLocalBranching(BonminSetup * setup); + + /** Copy constructor.*/ + HeuristicLocalBranching(const HeuristicLocalBranching &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicLocalBranching(*this); + } + + /** Destructor*/ + virtual ~HeuristicLocalBranching(); + + /// Update model + virtual void setModel(CbcModel * model); + + /// Validate model i.e. sets when_ to 0 if necessary + virtual void validate(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// How often to do (code can change) + int howOften_; + /// Number of solutions so we can do something at solution + int numberSolutions_; + + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/BonHeuristicRINS.hpp b/thirdparty/linux/include/coin/BonHeuristicRINS.hpp new file mode 100644 index 0000000..5dcc68b --- /dev/null +++ b/thirdparty/linux/include/coin/BonHeuristicRINS.hpp @@ -0,0 +1,55 @@ +// (C) Copyright CNRS and International Business Machines Corporation +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// Joao Goncalves, International Business Machines Corporation +// +// Date : 06/18/2008 + +#ifndef BonHeuristicRINS_H +#define BonHeuristicRINS_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class HeuristicRINS:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + HeuristicRINS(); + /** Constructor with setup.*/ + HeuristicRINS(BonminSetup * setup); + + /** Copy constructor.*/ + HeuristicRINS(const HeuristicRINS &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicRINS(*this); + } + + /** Destructor*/ + virtual ~HeuristicRINS(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /// Sets how often to do it + inline void setHowOften(int value) + { howOften_=value;} + + private: + /// How often to do (code can change) + int howOften_; + /// Number of solutions so we can do something at solution + int numberSolutions_; + + }; + +}/* Ends Bonmin namepace.*/ +#endif diff --git a/thirdparty/linux/include/coin/BonIpoptInteriorWarmStarter.hpp b/thirdparty/linux/include/coin/BonIpoptInteriorWarmStarter.hpp new file mode 100644 index 0000000..d477548 --- /dev/null +++ b/thirdparty/linux/include/coin/BonIpoptInteriorWarmStarter.hpp @@ -0,0 +1,103 @@ +// (C) Copyright International Business Machines Corporation 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: BonIpoptInteriorWarmStarter.hpp 2106 2015-01-20 10:33:55Z stefan $ +// +// Authors: Andreas Waechter IBM 2006-03-02 + +#ifndef __IPOPTINTERIORWARMSTARTER_HPP__ +#define __IPOPTINTERIORWARMSTARTER_HPP__ + +#include "IpSmartPtr.hpp" +#include "IpNLP.hpp" +#include <vector> + +namespace Bonmin +{ + class IpoptInteriorWarmStarter : public Ipopt::ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor. We give it the values of the current bounds so that + * it can figure out which variables are fixed for this NLP. */ + IpoptInteriorWarmStarter(Ipopt::Index n, const Ipopt::Number* x_L, const Ipopt::Number* x_u, + Ipopt::Number nlp_lower_bound_inf, + Ipopt::Number nlp_upper_bound_inf, + bool store_several_iterates); + + /** Default destructor */ + ~IpoptInteriorWarmStarter(); + //@} + + /** Method for possibly storing another iterate during the current + * optimizatin for possible use for a warm start for a new + * problem */ + bool UpdateStoredIterates(Ipopt::AlgorithmMode mode, + const Ipopt::IpoptData& ip_data, + Ipopt::IpoptCalculatedQuantities& ip_cq); + + /** Method for doing whatever needs to be done after the parent NLP + * has been solved */ + bool Finalize(); + + /** Method for computing the initial point based on the stored + * information */ + bool WarmStartIterate(Ipopt::Index n, const Ipopt::Number* x_l_new, const Ipopt::Number* x_u_new, + Ipopt::IteratesVector& warm_start_iterate); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor. */ + IpoptInteriorWarmStarter(); + + /** Copy Constructor */ + IpoptInteriorWarmStarter(const IpoptInteriorWarmStarter&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptInteriorWarmStarter&); + //@} + + //@{ + /** Value for a lower bound that denotes -infinity */ + Ipopt::Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Ipopt::Number nlp_upper_bound_inf_; + /** Flag indicating whether more than one iterate is to be + * stored. */ + bool store_several_iterates_; + //@} + + /** @name Copy of the bounds for the previously solved NLP. This is + * required to find out the remapping for fixed variables, and it + * might also help to see how large the perturbation of the new + * problem is. */ + //@{ + Ipopt::Index n_; + Ipopt::Number* x_l_prev_; + Ipopt::Number* x_u_prev_; + //@} + + /** @name Selected Iterates and quantities from the previous + * optimization */ + //@{ + Ipopt::Index n_stored_iterates_; + std::vector<Ipopt::Index> stored_iter_; + std::vector<Ipopt::SmartPtr<const Ipopt::IteratesVector> > stored_iterates_; + std::vector<Ipopt::Number> stored_mu_; + std::vector<Ipopt::Number> stored_nlp_error_; + std::vector<Ipopt::Number> stored_primal_inf_; + std::vector<Ipopt::Number> stored_dual_inf_; + std::vector<Ipopt::Number> stored_compl_; + //@} + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonIpoptSolver.hpp b/thirdparty/linux/include/coin/BonIpoptSolver.hpp new file mode 100644 index 0000000..0f96693 --- /dev/null +++ b/thirdparty/linux/include/coin/BonIpoptSolver.hpp @@ -0,0 +1,188 @@ +// (C) Copyright International Business Machines (IBM) 2005, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, IBM +// +// Date : 26/09/2006 + +#ifndef IpoptSolver_HPP +#define IpoptSolver_HPP +#include "BonTNLPSolver.hpp" +#include "IpIpoptApplication.hpp" + + +namespace Bonmin +{ + class IpoptSolver: public TNLPSolver + { + public: + class UnsolvedIpoptError: public TNLPSolver::UnsolvedError + { + public: + UnsolvedIpoptError(int errorNum, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name): + TNLPSolver::UnsolvedError(errorNum, problem, name) + {} + virtual const std::string& errorName() const; + + virtual const std::string& solverName() const; + virtual ~UnsolvedIpoptError() + {} + private: + static std::string errorNames [17]; + static std::string solverName_; + }; + + virtual UnsolvedError * newUnsolvedError(int num, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name) + { + return new UnsolvedIpoptError(num, problem, name); + } + + + + /// Constructor + IpoptSolver(bool createEmpty = false); + +/// Constructor with Passed in journalist, registered options, options + IpoptSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + +/// Constructor with Passed in journalist, registered options, options + IpoptSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist); + + /// Copy constructor + IpoptSolver(const IpoptSolver &other); + + ///virtual copy constructor + virtual Ipopt::SmartPtr<TNLPSolver> clone(); + + /// Virtual destructor + virtual ~IpoptSolver(); + + /** Initialize the TNLPSolver (read options from params_file) + */ + virtual bool Initialize(std::string params_file); + + /** Initialize the TNLPSolver (read options from istream is) + */ + virtual bool Initialize(std::istream& is); + + /** @name Solve methods */ + //@{ + /// Solves a problem expresses as a TNLP + virtual TNLPSolver::ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp); + + /// Resolves a problem expresses as a TNLP + virtual TNLPSolver::ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp); + + /// Set the warm start in the solver + virtual bool setWarmStart(const CoinWarmStart * warm, + Ipopt::SmartPtr<TMINLP2TNLP> tnlp); + + /// Get warm start used in last optimization + virtual CoinWarmStart * getUsedWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const; + + + /// Get the warm start form the solver + virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr<Bonmin::TMINLP2TNLP> tnlp) const; + + virtual CoinWarmStart * getEmptyWarmStart() const; + + /** Check that warm start object is valid.*/ + virtual bool warmStartIsValid(const CoinWarmStart * ws) const; + + /// Enable the warm start options in the solver + virtual void enableWarmStart(); + + /// Disable the warm start options in the solver + virtual void disableWarmStart(); + + //@} + + /// Get the CpuTime of the last optimization. + virtual double CPUTime(); + + /// Get the iteration count of the last optimization. + virtual int IterationCount(); + + /// turn off all output from the solver + virtual void setOutputToDefault(); + /// turn on all output from the solver + virtual void forceSolverOutput(int log_level); + + /// Get the solver name + virtual std::string & solverName() + { + return solverName_; + } + + /// Register this solver options into passed roptions + static void RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + { + Ipopt::IpoptApplication::RegisterAllIpoptOptions(GetRawPtr(roptions)); + } + + + + /// Return status of last optimization + Ipopt::ApplicationReturnStatus getOptStatus() const + { + return optimizationStatus_; + } + + Ipopt::IpoptApplication& getIpoptApp() + { + return *app_; + } + + virtual int errorCode() const + { + return (int) optimizationStatus_; + } + private: + /** Set default Ipopt parameters for use in a MINLP */ + void setMinlpDefaults(Ipopt::SmartPtr< Ipopt::OptionsList> Options); + + /** get Bonmin return status from Ipopt one. */ + TNLPSolver::ReturnStatus solverReturnStatus(Ipopt::ApplicationReturnStatus optimization_status) const; + + /** Ipopt application */ + Ipopt::SmartPtr<Ipopt::IpoptApplication> app_; + /** return status of last optimization.*/ + Ipopt::ApplicationReturnStatus optimizationStatus_; + //@} + + + /** Flag to indicate if last problem solved had 0 dimension. (in this case Ipopt was not called).*/ + bool problemHadZeroDimension_; + + /** Warm start strategy : + <ol> + <li> no warm start,</li> + <li> simple warm start (optimal point),</li> + <li> more elaborate strategies (interior point...).</li> + </ol> + */ + int warmStartStrategy_; + + /** flag remembering if we want to use warm start option */ + bool enable_warm_start_; + + /** flag remembering if we have call the Optimize method of the + IpoptInterface before */ + bool optimized_before_; + //name of solver (Ipopt) + static std::string solverName_; + }; +} +#endif + diff --git a/thirdparty/linux/include/coin/BonIpoptWarmStart.hpp b/thirdparty/linux/include/coin/BonIpoptWarmStart.hpp new file mode 100644 index 0000000..fffc3e3 --- /dev/null +++ b/thirdparty/linux/include/coin/BonIpoptWarmStart.hpp @@ -0,0 +1,148 @@ +// (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 02/15/2006 + + +#ifndef IpoptWarmStart_HPP +#define IpoptWarmStart_HPP +#include "CoinWarmStartBasis.hpp" +#include "CoinWarmStartPrimalDual.hpp" +#include "BonIpoptInteriorWarmStarter.hpp" + + +namespace Bonmin +{ + class TMINLP2TNLP; + + /** \brief Class for storing warm start informations for Ipopt.<br> + * This class inherits from CoinWarmStartPrimalDual, because that's what + * this warmstart really is. <br> + * For practical reason (integration in Cbc) this class also inherits from + * CoinWarmStartBasis. <br> + * This class stores a starting point (primal and dual values) for Ipopt. + * <br> + * <p> + * The primal part of the base class contains the value of each primal + * variable. + * <p> + * The dual part of the base class consists of three sections (the number of + * values is 2*numcols+numrows): + <UL> + <li> First, values for dual variables associated with the lower bound + constraints on structurals, i.e., primal variables (constraints + \f$ l \leq x \f$); + <li> Then values for dual variables associated with upper bound + constraints on structurals (constraints \f$ x \leq u\f$). + <li> the values for dual variables associated with regular constraints + (constraints \f$ g(x) \leq 0 \f$) + </UL> + */ + class IpoptWarmStart : + public virtual CoinWarmStartPrimalDual, public virtual CoinWarmStartBasis + { + public: + + /// Default constructor + IpoptWarmStart(bool empty = 1, int numvars = 0, int numcont = 0); + /// Usefull constructor, stores the current optimum of ipopt + IpoptWarmStart(const Ipopt::SmartPtr<TMINLP2TNLP> tnlp, + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter); + /// Another usefull constructor, stores the passed point + IpoptWarmStart(int primal_size, int dual_size, + const double * primal, const double * dual); + /// Copy constructor + IpoptWarmStart( const IpoptWarmStart &other, bool ownValues = 1); + /// A constructor from a CoinWarmStartPrimalDual + IpoptWarmStart(const CoinWarmStartPrimalDual& pdws); + /// Abstract destructor + virtual ~IpoptWarmStart(); + + /// `Virtual constructor' + virtual CoinWarmStart *clone() const + { + return new IpoptWarmStart(*this,1); + } + + /** Generate the "differences" between two IpoptWarmStart.*/ + virtual CoinWarmStartDiff* + generateDiff(const CoinWarmStart *const oldCWS) const; + /** \brief Apply 'differences' to an Ipopt warm start. + * What this actually does is get a copy to the vector of values stored + in IpoptWarmStartDiff.*/ + virtual void + applyDiff (const CoinWarmStartDiff *const cwsdDiff); + + /** Accessor to warm start information obecjt */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const + { + return warm_starter_; + } + + /// flush the starting point + void flushPoint(); + + ///Is this an empty warm start? + bool empty() const + { + return empty_; + } + private: + /** warm start information object */ + mutable Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_; + ///Say if warm start is empty + bool empty_; + }; + + //########################################################################### + + /** \brief Diff class for IpoptWarmStart. + * Actually get the differences from CoinWarmStartBasis and stores the + whole vector of values. + \todo Find a way to free unused values. + */ + class IpoptWarmStartDiff : public CoinWarmStartPrimalDualDiff + { + public: + friend class IpoptWarmStart; + /** Useful constructor; takes over the data in \c diff */ + IpoptWarmStartDiff(CoinWarmStartPrimalDualDiff * diff, + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter): + CoinWarmStartPrimalDualDiff(), + warm_starter_(NULL)//(warm_starter) + { + CoinWarmStartPrimalDualDiff::swap(*diff); + } + /** Copy constructor. */ + IpoptWarmStartDiff(const IpoptWarmStartDiff &other): + CoinWarmStartPrimalDualDiff(other), + warm_starter_(NULL /*other.warm_starter_*/) {} + + /// Abstract destructor + virtual ~IpoptWarmStartDiff() {} + + /// `Virtual constructor' + virtual CoinWarmStartDiff *clone() const + { + return new IpoptWarmStartDiff(*this); + } + + /** Accessor to warm start information obecjt */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const + { + return warm_starter_; + } + void flushPoint(); + private: + + /** warm start information object */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/BonLinearCutsGenerator.hpp b/thirdparty/linux/include/coin/BonLinearCutsGenerator.hpp new file mode 100644 index 0000000..4c80719 --- /dev/null +++ b/thirdparty/linux/include/coin/BonLinearCutsGenerator.hpp @@ -0,0 +1,75 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonLinearCutsGenerator_H +#define BonLinearCutsGenerator_H + +#include "CglCutGenerator.hpp" +#include "CoinSmartPtr.hpp" +#include "BonOuterApprox.hpp" +#include "BonBonminSetup.hpp" +#include <list> + +namespace Bonmin { +class LinearCutsGenerator : public CglCutGenerator { + public: + /** Type for cut generation method with its frequency and string identification. */ + struct CuttingMethod : public Coin::ReferencedObject + { + int frequency; + std::string id; + CglCutGenerator * cgl; + bool atSolution; + bool normal; + CuttingMethod(): + atSolution(false), + normal(true) + {} + + CuttingMethod(const CuttingMethod & other): + frequency(other.frequency), + id(other.id), + cgl(other.cgl), + atSolution(other.atSolution), + normal(other.normal) + {} + }; + LinearCutsGenerator(): + CglCutGenerator(), + methods_(){ + } + + + LinearCutsGenerator(const LinearCutsGenerator & other): + CglCutGenerator(other), + methods_(other.methods_){ + } + + CglCutGenerator * clone() const { + return new LinearCutsGenerator(*this); + } + + virtual ~LinearCutsGenerator(){ + } + + bool needsOptimalBasis() { return false;} + + void initialize(BabSetupBase& s); + + void generateCuts(const OsiSolverInterface &solver, OsiCuts &cs, + const CglTreeInfo info = CglTreeInfo()); + + private: + std::list<Coin::SmartPtr<CuttingMethod> > methods_; +}; + +}/* Ends Bonmin namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonLocalSolverBasedHeuristic.hpp b/thirdparty/linux/include/coin/BonLocalSolverBasedHeuristic.hpp new file mode 100644 index 0000000..3f935e6 --- /dev/null +++ b/thirdparty/linux/include/coin/BonLocalSolverBasedHeuristic.hpp @@ -0,0 +1,102 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonLocalSolverBasedHeuristic_H +#define BonLocalSolverBasedHeuristic_H +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin { + class LocalSolverBasedHeuristic : public CbcHeuristic { + public: + /** Default constructor.*/ + LocalSolverBasedHeuristic(); + + /** Constructor with setup.*/ + LocalSolverBasedHeuristic(BonminSetup * setup); + + /** Copy constructor.*/ + LocalSolverBasedHeuristic(const LocalSolverBasedHeuristic & other); + + /** Destructor.*/ + ~LocalSolverBasedHeuristic(); + + /** Virtual copy constructor.*/ + virtual CbcHeuristic * clone() const = 0; + + /// Assignment operator + LocalSolverBasedHeuristic & operator=(const LocalSolverBasedHeuristic& rhs); + +#if 0 + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model){throw -1;} +#endif + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + void setSetup(BonminSetup * setup){ + setup_ = setup; + Initialize(setup_->options()); + } + /** Performs heuristic */ + virtual int solution(double & objectiveValue, + double * newSolution)=0; + + /** Performs heuristic which adds cuts */ + virtual int solution(double & objectiveValue, + double * newSolution, + OsiCuts & cs) {return 0;} + + + /** Do a local search based on setup and passed solver.*/ + int doLocalSearch(OsiTMINLPInterface * solver, + double *solution, + double & solValue, + double cutoff, std::string prefix = "local_solver.") const; + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Setup the defaults.*/ + virtual void setupDefaults(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const std::string &value); + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const double &value); + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const int &value); + private: + /** Time limit in local search.*/ + double time_limit_; + /** maximal number of nodes in local search.*/ + int max_number_nodes_; + /** Maximal number of solutions in local search.*/ + int max_number_solutions_; + }; +} /** ends namespace Bonmin.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonLpBranchingSolver.hpp b/thirdparty/linux/include/coin/BonLpBranchingSolver.hpp new file mode 100644 index 0000000..9e10172 --- /dev/null +++ b/thirdparty/linux/include/coin/BonLpBranchingSolver.hpp @@ -0,0 +1,80 @@ +// Copyright (C) 2006, 2007 International Business Machines +// Corporation and others. All Rights Reserved. +#ifndef BonLpBranchingSolver_H +#define BonLpBranchingSolver_H + +#include "BonStrongBranchingSolver.hpp" +#include "BonEcpCuts.hpp" + +namespace Bonmin +{ + + /** Implementation of BonChooseVariable for curvature-based braching. + */ + + class LpBranchingSolver : public StrongBranchingSolver + { + + public: + + /// Constructor from setup + LpBranchingSolver (BabSetupBase *b); + /// Copy constructor + LpBranchingSolver (const LpBranchingSolver &); + + /// Assignment operator + LpBranchingSolver & operator= (const LpBranchingSolver& rhs); + + /// Destructor + virtual ~LpBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface); + + void setMaxCuttingPlaneIter(int num) + { + maxCuttingPlaneIterations_ = num; + } + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /// Default Constructor + LpBranchingSolver (); + + /// Linear solver + OsiSolverInterface* lin_; + + /// Warm start object for linear solver + CoinWarmStart* warm_; + + /// Ecp cut generate + EcpCuts* ecp_; + + /// Number of maximal ECP cuts + int maxCuttingPlaneIterations_; + + /// absolute tolerance for ECP cuts + double abs_ecp_tol_; + + /// relative tolerance for ECP cuts + double rel_ecp_tol_; + + + enum WarmStartMethod { + Basis=0 /** Use basis*/, + Clone /** clone problem*/ + }; + /// Way problems are warm started + WarmStartMethod warm_start_mode_; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/BonMilpRounding.hpp b/thirdparty/linux/include/coin/BonMilpRounding.hpp new file mode 100644 index 0000000..94f8723 --- /dev/null +++ b/thirdparty/linux/include/coin/BonMilpRounding.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2010, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami CNRS +// +// Date : May, 26 2010 + +#ifndef BonMilpRounding_HPP +#define BonMilpRounding_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" +#include "CbcStrategy.hpp" +#include "OsiCuts.hpp" + +namespace Bonmin +{ + class SubMipSolver; + class MilpRounding : public CbcHeuristic + { + public: + + /// Constructor with setup + MilpRounding(BonminSetup * setup); + + /// Copy constructor + MilpRounding(const MilpRounding ©); + + /// Destructor + ~MilpRounding(); + + /// Assignment operator + MilpRounding & operator=(const MilpRounding & rhs); + + /// Clone + virtual CbcHeuristic * clone() const{ + return new MilpRounding(*this); + } + + /// Initialize method + void Initialize(BonminSetup * setup); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + private: + /// How often to do (code can change) + int howOften_; + /// A subsolver for MIP + SubMipSolver * mip_; + + OsiCuts noGoods; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonOACutGenerator2.hpp b/thirdparty/linux/include/coin/BonOACutGenerator2.hpp new file mode 100644 index 0000000..c098c9b --- /dev/null +++ b/thirdparty/linux/include/coin/BonOACutGenerator2.hpp @@ -0,0 +1,56 @@ +// (C) Copyright Carnegie Mellon University 2005 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + + +#ifndef BonOACutGenerator2_HPP +#define BonOACutGenerator2_HPP +#include "BonOaDecBase.hpp" + +namespace Bonmin +{ + /** Class to perform OA in its classical form.*/ + class OACutGenerator2 : public OaDecompositionBase + { + public: + /// Constructor with basic setup + OACutGenerator2(BabSetupBase & b); + + /// Copy constructor + OACutGenerator2(const OACutGenerator2 ©) + : + OaDecompositionBase(copy), + subMip_(new SubMipSolver (*copy.subMip_)) + {} + /// Destructor + ~OACutGenerator2(); + + void setStrategy(const CbcStrategy & strategy) + { + parameters_.setStrategy(strategy); + } + + virtual CglCutGenerator * clone() const + { + return new OACutGenerator2(*this); + } + /** Register OA options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo & info) const; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const; + + private: + SubMipSolver * subMip_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonOAMessages.hpp b/thirdparty/linux/include/coin/BonOAMessages.hpp new file mode 100644 index 0000000..cfe3272 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOAMessages.hpp @@ -0,0 +1,44 @@ +// (C) Copyright Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 07/15/2005 + +#ifndef OaMessages_H +#define OaMessages_H +#include "CoinMessage.hpp" + +namespace Bonmin +{ + enum OA_Message{ + FEASIBLE_NLP, + INFEASIBLE_NLP, + UPDATE_UB, + SOLVED_LOCAL_SEARCH, + LOCAL_SEARCH_ABORT, + UPDATE_LB, + ABORT, + OASUCCESS, + OAABORT, + OA_STATS, + LP_ERROR, + PERIODIC_MSG, + FP_DISTANCE, + FP_MILP_VAL, + FP_MAJOR_ITERATION, + FP_MINOR_ITERATION, + DUMMY_END + }; + + /** Output messages for Outer approximation cutting planes */ + class OaMessages : public CoinMessages + { + public: + OaMessages(); + }; + +} //end namespace Bonmin +#endif diff --git a/thirdparty/linux/include/coin/BonOaDecBase.hpp b/thirdparty/linux/include/coin/BonOaDecBase.hpp new file mode 100644 index 0000000..61156f7 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOaDecBase.hpp @@ -0,0 +1,297 @@ +// (C) Copyright International Business Machines (IBM) 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/07/2006 +#ifndef BonOaDecBase_HPP +#define BonOaDecBase_HPP +#include "BonSubMipSolver.hpp" +#include "CglCutGenerator.hpp" +#include "BonBabSetupBase.hpp" +#include "BonOAMessages.hpp" +#include "CbcModel.hpp" + +#include "CbcStrategy.hpp" + +#include "CoinTime.hpp" +#include "OsiAuxInfo.hpp" +#include "OsiBranchingObject.hpp" +#include <iostream> +#include "BonBabInfos.hpp" +namespace Bonmin +{ + /** Base class for OA algorithms.*/ + class OaDecompositionBase : public CglCutGenerator + { + public: + + + /** Small class to manipulatee various things in an OsiSolverInterface and restore them. + The OsiSolverInterface manipulated may already exist or may be cloned from another one.*/ + class solverManip + { + public: + /** Constructor. */ + solverManip(OsiSolverInterface *si , bool saveNumRows=true, + bool saveBasis=true, bool saveBounds=false, + bool saveCutoff = false, bool resolve=true); + + /** Constructor which clone an other interface. */ + solverManip(const OsiSolverInterface & si); + /** Destructor. */ + ~solverManip(); + /** Restore solver. */ + void restore(); + + /** Get pointer to solver interface. */ + OsiSolverInterface * si() + { + return si_; + } + + /** Set objects.*/ + void setObjects(OsiObject ** objects, int nObjects) + { + objects_ = objects; + nObjects_ = nObjects; + } + + private: + /** Interface saved. */ + OsiSolverInterface * si_; + /** Initial number of rows (-1 if don't save). */ + int initialNumberRows_; + + /** Initial lower bounds. */ + double * colLower_; + + /** Initial Upper bounds.*/ + double * colUpper_; + + /** Inital basis. */ + CoinWarmStart * warm_; + + /** Initial cutoff. */ + double cutoff_; + + /** delete si_ ? */ + bool deleteSolver_; + + /// Some objects the feasiblitiy of which to verify. + OsiObject * * objects_; + /// Number of objects.*/ + int nObjects_; + /** \name Cached info from solver interface.*/ + /** @{ */ + /** Number of columns. */ + int numcols_; + /** Number of rows. */ + int numrows_; + /** Lower bounds on variables.*/ + const double * siColLower_; + /** Upper bounds on variables. */ + const double * siColUpper_; + + void getCached(); + /** @} */ + }; + + /// New usefull constructor + OaDecompositionBase(BabSetupBase &b, bool leaveSiUnchanged, + bool reassignLpsolver); + + /// Copy constructor + OaDecompositionBase(const OaDecompositionBase & copy); + + + /// Destructor + virtual ~OaDecompositionBase(); + + /** Standard cut generation methods. */ + virtual void generateCuts(const OsiSolverInterface &si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Assign an OsiTMINLPInterface + void assignNlpInterface(OsiTMINLPInterface * nlp) + { + nlp_ = nlp; + } + + /// Assign an OsiTMINLPInterface + void assignLpInterface(OsiSolverInterface * si) + { + lp_ = si; + } + + bool reassignLpsolver() + { + return reassignLpsolver_; + } + /** Set objects.*/ + void setObjects(OsiObject ** objects, int nObjects) + { + objects_ = objects; + nObjects_ = nObjects; + } + /// Set whether to leave the solverinterface unchanged + inline void setLeaveSiUnchanged(bool yesno) + { + leaveSiUnchanged_ = yesno; + } + + /** Parameters for algorithm. */ + struct Parameters + { + /// Add cuts as global + bool global_; + /// Add only violated OA inequalities + bool addOnlyViolated_; + /// cutoff min increase (has to be intialized trhough Cbc) + double cbcCutoffIncrement_; + /// integer tolerance (has to be the same as Cbc's) + double cbcIntegerTolerance_; + /** setting for gap tolerance.*/ + double gap_tol_; + ///Total max number of local searches + int maxLocalSearch_; + /// maximum time for local searches + double maxLocalSearchTime_; + /** sub milp log level.*/ + int subMilpLogLevel_; + /** maximum number of solutions*/ + int maxSols_; + /** Frequency of log. */ + double logFrequency_; + + + /** Constructor with default values */ + Parameters(); + + /** Copy constructor */ + Parameters(const Parameters & other); + + /** Destructor */ + ~Parameters() + { + if (strategy_) delete strategy_; + } + + /** Strategy to apply when using Cbc as MILP sub-solver.*/ + void setStrategy(const CbcStrategy & strategy) + { + if (strategy_) delete strategy_; + strategy_ = strategy.clone(); + } + + const CbcStrategy * strategy() const + { + return strategy_; + } + +private: + /** Strategy to apply when using Cbc as MILP sub-solver.*/ + CbcStrategy * strategy_; + + }; + + Parameters& parameter() + { + return parameters_; + } + + const Parameters& parameter()const + { + return parameters_; + } + + void setLogLevel(int level) + { + handler_->setLogLevel(level); + } + + void setReassignLpSolver(bool v){ + reassignLpsolver_ = v; + } + void passInMessageHandler(CoinMessageHandler * handler); + protected: + void setupMipSolver(BabSetupBase &b, const std::string &prefix); + /// \name Protected helper functions + /**@{ */ + + /** Solve the nlp and do output. + \return true if feasible*/ + bool post_nlp_solve(BabInfo * babInfo, double cutoff) const; + /** @} */ + + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts &cs, solverManip &lpManip, + BabInfo * babInfo, double &, const CglTreeInfo & info) const = 0; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const = 0; + + /// \name Protected members + /** @{ */ + /// Pointer to nlp interface + mutable OsiTMINLPInterface * nlp_; + /// Pointer to setup + BabSetupBase * s_; + ///Number of nlp solved done + mutable int nSolve_; + /// A linear solver + mutable OsiSolverInterface * lp_; + /// Some objects the feasiblitiy of which to verify. + OsiObject * * objects_; + /// Number of objects.*/ + int nObjects_; + ///number of local searches performed + mutable int nLocalSearch_; + /** messages handler. */ + CoinMessageHandler * handler_; + /** Messages for OA */ + CoinMessages messages_; + /** Wether or not we should remove cuts at the end of the procedure */ + bool leaveSiUnchanged_; + /** Do we need to reassign the lp solver with Cbc.*/ + bool reassignLpsolver_; + /** time of construction*/ + double timeBegin_; + /** number of solutions found by OA_decomposition.*/ + mutable int numSols_; + + /** Parameters.*/ + Parameters parameters_; + + /** Saved cuts: in some cases when using OA to check feasible solution algorithm may loop because Cbc removes inactive cuts. + To overcome this we can impose that no OA cut can be discarded by Cbc but this consumes too much memory in some cases. + Here we do it another way: cuts generated at current node are saved if algorithm seems to enter a loop we impose the needed cuts to be kept.*/ + mutable OsiCuts savedCuts_; + /** Store the current node number.*/ + mutable int currentNodeNumber_; + /** @} */ + +#ifdef OA_DEBUG + class OaDebug + { + public: + bool checkInteger(const OsiSolverInterface&nlp, std::ostream & os) const; + + void printEndOfProcedureDebugMessage(const OsiCuts &cs, + bool foundSolution, + double solValue, + double milpBound, + bool isInteger, + bool feasible, + std::ostream & os) const; + }; + + /** debug object. */ + OaDebug debug_; + +#endif + }; +} +#endif + diff --git a/thirdparty/linux/include/coin/BonOaFeasChecker.hpp b/thirdparty/linux/include/coin/BonOaFeasChecker.hpp new file mode 100644 index 0000000..5ef8c14 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOaFeasChecker.hpp @@ -0,0 +1,73 @@ +// (C) Copyright International Business Machines 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 12/26/2006 + + +#ifndef BonOaFeasibilityChecker_HPP +#define BonOaFeasibilityChecker_HPP +#include "BonOaDecBase.hpp" + +namespace Bonmin +{ + /** Class to perform OA in its classical form.*/ + class OaFeasibilityChecker : public OaDecompositionBase + { + public: + /// New usefull constructor + OaFeasibilityChecker(BabSetupBase &b); + /// Copy constructor + OaFeasibilityChecker(const OaFeasibilityChecker ©) + : + OaDecompositionBase(copy), + pol_(copy.pol_), + type_(copy.type_), + cut_count_(copy.cut_count_), + maximum_oa_cuts_(copy.maximum_oa_cuts_) + {} + /// Destructor + ~OaFeasibilityChecker(); + + /** Register OA options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + virtual CglCutGenerator * clone() const + { + return new OaFeasibilityChecker(*this); + } + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo & info) const; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const + { + return 0; + } + + /** See documentation for feas_check_discard_policy option.*/ + enum CutsPolicies { + DetectCycles = 0, + KeepAll, + TreatAsNormal}; + /** Policy for keeping cuts.*/ + CutsPolicies pol_; + + /** See documentation for feas_check_cut_types option.*/ + enum CutsTypes { + OA = 0, + Benders}; + /** Type of cuts.*/ + CutsTypes type_; + + /** Count the total number of cuts generated.*/ + mutable unsigned int cut_count_; + /** maximum number of OA cuts.*/ + unsigned int maximum_oa_cuts_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonOaNlpOptim.hpp b/thirdparty/linux/include/coin/BonOaNlpOptim.hpp new file mode 100644 index 0000000..c157b66 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOaNlpOptim.hpp @@ -0,0 +1,116 @@ +// (C) Copyright Carnegie Mellon University 2005, 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + +#ifndef BonOaNlpOptim_HPP +#define BonOaNlpOptim_HPP +#include "CglCutGenerator.hpp" +#include "BonOsiTMINLPInterface.hpp" +#include "BonOAMessages.hpp" +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** Generate cuts for the nlp corresponding to continuous relaxation at a node.*/ + class OaNlpOptim : public CglCutGenerator + { + public: + /// Default constructor + OaNlpOptim(OsiTMINLPInterface * si = NULL, + int maxDepth = 10, bool addOnlyViolated = false, + bool globalCuts = true); + + /// Constructor with basic setup + OaNlpOptim(BabSetupBase &b); + /// Copy constructor + OaNlpOptim(const OaNlpOptim ©) + : + CglCutGenerator(copy), + nlp_(copy.nlp_), + maxDepth_(copy.maxDepth_), + nSolve_(0), + addOnlyViolated_(copy.addOnlyViolated_), + global_(copy.global_), + solves_per_level_(copy.solves_per_level_) + { + handler_ = new CoinMessageHandler(); + handler_ -> setLogLevel(copy.handler_->logLevel()); + messages_ = OaMessages(); + } + void passInMessageHandler(const CoinMessageHandler * handler) + { + delete handler_; + handler_ = handler->clone(); + } + ///Abstract constructor + virtual CglCutGenerator * clone() const + { + return new OaNlpOptim(*this); + } + + /** Desctructor */ + virtual ~OaNlpOptim() + { + if (handler_) + delete handler_; + } + + /// Assign an OsiTMINLPInterface + void assignInterface(OsiTMINLPInterface * si); + /// cut generation method + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info); + + + + inline void setMaxDepth(int value) + { + maxDepth_ = value; + } + inline void setAddOnlyViolated(bool yesno) + { + addOnlyViolated_ = yesno; + } + inline void setGlobalCuts(bool yesno) + { + global_ = yesno; + } + inline int getNSolve() + { + return nSolve_; + } + /**set log level */ + void setLogLevel(int value) + { + handler_->setLogLevel(value); + } + + /** Register OaNlpOptim options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /// Pointer to the Ipopt interface + OsiTMINLPInterface * nlp_; + + /** maximum depth at which generate cuts*/ + int maxDepth_; + + ///Number of NLP resolution done + mutable int nSolve_; + /** messages handler. */ + CoinMessageHandler * handler_; + /** handler */ + CoinMessages messages_; + /** Add only violated cuts?*/ + bool addOnlyViolated_; + /** Add cuts as global?*/ + bool global_; + /** Average number of nodes per level in tree */ + double solves_per_level_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/BonOsiTMINLPInterface.hpp b/thirdparty/linux/include/coin/BonOsiTMINLPInterface.hpp new file mode 100644 index 0000000..3d95545 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOsiTMINLPInterface.hpp @@ -0,0 +1,1342 @@ +// (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2004, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + + +#ifndef OsiTMINLPInterface_H +#define OsiTMINLPInterface_H + +#define INT_BIAS 0e-8 + +#include <string> +#include <iostream> + +#include "OsiSolverInterface.hpp" +#include "CoinWarmStartBasis.hpp" + +#include "BonCutStrengthener.hpp" +//#include "BonRegisteredOptions.hpp" + +namespace Bonmin { + class TMINLP; + class TMINLP2TNLP; + class TMINLP2OsiLP; + class TNLP2FPNLP; + class TNLPSolver; + class RegisteredOptions; + class StrongBranchingSolver; + + /** Solvers for solving nonlinear programs.*/ + enum Solver{ + EIpopt=0 /** <a href="http://projects.coin-or.org/Ipopt"> Ipopt </a> interior point algorithm.*/, + EFilterSQP /** <a href="http://www-unix.mcs.anl.gov/~leyffer/solvers.html"> filterSQP </a> Sequential Quadratic Programming algorithm.*/, + EAll/** Use all solvers.*/ + }; +/** + This is class provides an Osi interface for a Mixed Integer Linear Program + expressed as a TMINLP + (so that we can use it for example as the continuous solver in Cbc). +*/ + +class OsiTMINLPInterface : public OsiSolverInterface +{ + friend class BonminParam; + +public: + + //############################################################################# + + /**Error class to throw exceptions from OsiTMINLPInterface. + * Inherited from CoinError, we just want to have a different class to be able to catch + * errors thrown by OsiTMINLPInterface. + */ +class SimpleError : public CoinError + { + private: + SimpleError(); + + public: + ///Alternate constructor using strings + SimpleError(std::string message, + std::string methodName, + std::string f = std::string(), + int l = -1) + : + CoinError(message,methodName,std::string("OsiTMINLPInterface"), f, l) + {} + } + ; + +#ifdef __LINE__ +#define SimpleError(x, y) SimpleError((x), (y), __FILE__, __LINE__) +#endif + + // Error when problem is not solved + TNLPSolver::UnsolvedError * newUnsolvedError(int num, Ipopt::SmartPtr<TMINLP2TNLP> problem, std::string name){ + return app_->newUnsolvedError(num, problem, name); + } + //############################################################################# + + enum WarmStartModes{ + None, + FakeBasis, + Optimum, + InteriorPoint}; + + /** Type of the messages specifically written by OsiTMINLPInterface.*/ + enum MessagesTypes{ + SOLUTION_FOUND/**found a feasible solution*/, + INFEASIBLE_SOLUTION_FOUND/**found an infeasible problem*/, + UNSOLVED_PROBLEM_FOUND/**found an unsolved problem*/, + WARNING_RESOLVING /** Warn that a problem is resolved*/, + WARN_SUCCESS_WS/** Problem not solved with warm start but solved without*/, + WARN_SUCCESS_RANDOM/** Subproblem not solve with warm start but solved with random point*/, + WARN_CONTINUING_ON_FAILURE/** a failure occured but is continuing*/, + SUSPECT_PROBLEM/** Output the number of the problem.*/, + SUSPECT_PROBLEM2/** Output the number of the problem.*/, + IPOPT_SUMMARY /** Output summary statistics on Ipopt solution.*/, + BETTER_SOL /** Found a better solution with random values.*/, + LOG_HEAD/** Head of "civilized" log.*/, + LOG_FIRST_LINE/** First line (first solve) of log.*/, + LOG_LINE/**standard line (retry solving) of log.*/, + ALTERNATE_OBJECTIVE/** Recomputed integer feasible with alternate objective function*/, + WARN_RESOLVE_BEFORE_INITIAL_SOLVE /** resolve() has been called but there + was no previous call to initialSolve(). + */, + ERROR_NO_TNLPSOLVER /** Trying to access non-existent TNLPSolver*/, + WARNING_NON_CONVEX_OA /** Warn that there are equality or ranged constraints and OA may works bad.*/, + SOLVER_DISAGREE_STATUS /** Different solver gives different status for problem.*/, + SOLVER_DISAGREE_VALUE /** Different solver gives different optimal value for problem.*/, + OSITMINLPINTERFACE_DUMMY_END + }; + + //############################################################################# + + + /** Messages written by an OsiTMINLPInterface. */ +class Messages : public CoinMessages + { + public: + /// Constructor + Messages(); + }; + + + //############################################################################# + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiTMINLPInterface(); + + /** Facilitator to initialize interface. */ + void initialize(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix, + Ipopt::SmartPtr<TMINLP> tminlp); + + /** Facilitator to initialize interface. */ + void initialize(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + Ipopt::SmartPtr<TMINLP> tminlp){ + initialize(roptions, options, journalist, "bonmin.", tminlp); + } + + /** Set the model to be solved by interface.*/ + void setModel(Ipopt::SmartPtr<TMINLP> tminlp); + /** Set the solver to be used by interface.*/ + void setSolver(Ipopt::SmartPtr<TNLPSolver> app); + /** Sets the TMINLP2TNLP to be used by the interface.*/ + void use(Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp); + /** Copy constructor + */ + OsiTMINLPInterface (const OsiTMINLPInterface &); + + /** Virtual copy constructor */ + OsiSolverInterface * clone(bool copyData = true) const; + + /// Assignment operator + OsiTMINLPInterface & operator=(const OsiTMINLPInterface& rhs); + + /// Destructor + virtual ~OsiTMINLPInterface (); + + + /// Read parameter file + void readOptionFile(const std::string & fileName); + + /// Retrieve OsiTMINLPApplication option list + const Ipopt::SmartPtr<Ipopt::OptionsList> options() const; + /// Retrieve OsiTMINLPApplication option list + Ipopt::SmartPtr<Ipopt::OptionsList> options(); + + const char * prefix() const{ + if(!IsValid(app_)) { + messageHandler()->message(ERROR_NO_TNLPSOLVER, messages_)<<CoinMessageEol; + return NULL; + } + else + return app_->prefix(); + } + //@} + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial continuous relaxation + virtual void initialSolve(); + + /// Solve initial continuous relaxation (precising from where) + virtual void initialSolve(const char * whereFrom); + + /** Resolve the continuous relaxation after problem modification. + initialSolve may or may not have been called before this is called. In + any case, this must solve the problem, and speed the process up if it + can reuse any remnants of data that might exist from a previous solve. + */ + virtual void resolve(); + + /** Resolve the continuous relaxation after problem modification. + initialSolve may or may not have been called before this is called. In + any case, this must solve the problem, and speed the process up if it + can reuse any remnants of data that might exist from a previous solve. + */ + virtual void resolve(const char * whereFrom); + + /** Resolve the problem with different random starting points to try to find + a better solution (only makes sense for a non-convex problem.*/ + virtual void resolveForCost(int numretry, bool keepWs); + + /** Method to be called when a problem has failed to be solved. Will try + to resolve it with different settings. + */ + virtual void resolveForRobustness(int numretry); + + /// Nescessary for compatibility with OsiSolverInterface but does nothing. + virtual void branchAndBound() + { + throw SimpleError("Function not implemented for OsiTMINLPInterface","branchAndBound()"); + } + //@} + + + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + + ///Warn solver that branch-and-bound is continuing after a failure + void continuingOnAFailure() + { + hasContinuedAfterNlpFailure_ = true; + } + + + //Added by Claudia + + double getNewCutoffDecr() + { + return newCutoffDecr; + } + + void setNewCutoffDecr(double d) + { + newCutoffDecr = d; + } + + + /// Did we continue on a failure + bool hasContinuedOnAFailure() + { + return hasContinuedAfterNlpFailure_; + } + /// tell to ignore the failures (don't throw, don't fathom, don't report) + void ignoreFailures() + { + pretendFailIsInfeasible_ = 2; + } + /// Force current solution to be infeasible + void forceInfeasible() + { + problem_->set_obj_value(1e200); + } + /// Force current solution to be branched on (make it fractionnal with small objective) + void forceBranchable() + { + problem_->set_obj_value(-1e200); + problem_->force_fractionnal_sol(); + } + //@} + + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the clp algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + + // Get the push values for starting point + inline double getPushFact() const + { + return pushValue_; + } + + //@} + + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + ///get name of variables + const OsiSolverInterface::OsiNameVec& getVarNames() ; + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const; + + /** Get objective function sense (1 for min (default), -1 for max) + * Always minimizes */ + virtual double getObjSense() const + { + return 1; + } + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + + /// Return true if column is binary + virtual bool isBinary(int columnNumber) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int columnNumber) const; + + /// Return true if column is general integer + virtual bool isIntegerNonBinary(int columnNumber) const; + + /// Return true if column is binary and not fixed at either bound + virtual bool isFreeBinary(int columnNumber) const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + + ///Get priorities on integer variables. + const int * getPriorities() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->priorities; + else return NULL; + } + ///get prefered branching directions + const int * getBranchingDirections() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->branchingDirections; + else return NULL; + } + const double * getUpPsCosts() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->upPsCosts; + else return NULL; + } + const double * getDownPsCosts() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->downPsCosts; + else return NULL; + } + + + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. + * \todo Figure out what it could mean for Ipopt. + */ + virtual int getIterationCount() const; + + /** get total number of calls to solve.*/ + int nCallOptimizeTNLP() + { + return nCallOptimizeTNLP_; + } + /** get total time taken to solve NLP's. */ + double totalNlpSolveTime() + { + return totalNlpSolveTime_; + } + /** get total number of iterations */ + int totalIterations() + { + return totalIterations_; + } + + + //@} + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + */ + //@{ + + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set the lower bounds for all columns + array [getNumCols()] is an array of values for the objective. + */ + virtual void setColLower(const double * array); + + /** Set the upper bounds for all columns + array [getNumCols()] is an array of values for the objective. + */ + virtual void setColUpper(const double * array); + + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ); + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + + /** \brief Set the objective function sense (disabled). + * (1 for min (default), -1 for max) + \todo Make it work. + \bug Can not treat maximisation problems. */ + virtual void setObjSense(double s); + + /** Set the primal solution variable values + Set the values for the starting point. + \warning getColSolution will never return this vector (unless it is optimal). + */ + virtual void setColSolution(const double *colsol); + + /** Set dual solution variable values. + set the values for the starting point. + \warning getRowPrice will never return this vector (unless it is optimal). + */ + virtual void setRowPrice(const double * rowprice); + + //@} + + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods (those should really do nothing for the moment)*/ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + virtual CoinWarmStart *getEmptyWarmStart () const; + + /** Get warmstarting information */ + virtual CoinWarmStart* getWarmStart() const; + + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + + void setWarmStartMode(int mode) { + warmStartMode_ = (WarmStartModes) mode; + } + WarmStartModes getWarmStartMode() { + return warmStartMode_; + } + + void randomStartingPoint(); + + //Returns true if a basis is available + virtual bool basisIsAvailable() const + { + // Throw an exception + throw SimpleError("Needs coding for this interface", "basisIsAvailable"); + } + + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + //@} + + //Set numIterationSuspect_ + void setNumIterationSuspect(int value) + { + numIterationSuspect_ = value; + } + + /**@name Dummy functions + * Functions which have to be implemented in an OsiSolverInterface, + * but which do not do anything (but throwing exceptions) here in the case of a + * minlp solved using an nlp solver for continuous relaxations */ + //@{ + + /** Cbc will understand that no matrix exsits if return -1 + */ + virtual int getNumElements() const + { + return -1; + } + + + /** This returns the objective function gradient at the current + * point. It seems to be required for Cbc's pseudo cost + * initialization + */ + virtual const double * getObjCoefficients() const; + + /** We have to keep this but it will return NULL. + */ + virtual const CoinPackedMatrix * getMatrixByRow() const + { + return NULL; + } + + + /** We have to keep this but it will return NULL. + */ + virtual const CoinPackedMatrix * getMatrixByCol() const + { + return NULL; + } + + /** We have to keep this but it will throw an error. + */ + virtual void setObjCoeff( int elementIndex, double elementValue ) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "setObjCoeff"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "addCol"); + } + /** We have to keep this but it will throw an error. + */ + virtual void deleteCols(const int num, const int * colIndices) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "deleteCols"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "addRow"); + } + /** We have to keep this but it will throw an error. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng) + { + throw SimpleError("OsiTMINLPInterface model does not implement this function.", + "addRow"); + } + /** We have to keep this but it will throw an error. + */ + virtual void deleteRows(const int num, const int * rowIndices) + { + if(num) + freeCachedRowRim(); + problem_->removeCuts(num, rowIndices); + } + + + /** We have to keep this but it will throw an error + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "assignProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "assignProblem"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const int numcols, const int numrows, + const int* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const int numcols, const int numrows, + const int* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) + { + throw SimpleError("OsiTMINLPInterface model does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual int readMps(const char *filename, + const char *extension = "mps") + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "readMps"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "writeMps"); + } + + /** Throws an error */ + virtual std::vector<double*> getDualRays(int maxNumRays, bool fullRay = false) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "getDualRays"); + } + + /** Throws an error */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "getPrimalRays"); + } + + //@} + + + + //--------------------------------------------------------------------------- + + + + /**@name Control of Ipopt output + */ + //@{ + void setSolverOutputToDefault(){ + app_->setOutputToDefault();} + void forceSolverOutput(int log_level){ + app_->forceSolverOutput(log_level);} + //@} + + /**@name Sets and Getss */ + //@{ + /// Get objective function value (can't use default) + virtual double getObjValue() const; + + //@} + + /** get pointer to the TMINLP2TNLP adapter */ + const TMINLP2TNLP * problem() const + { + return GetRawPtr(problem_); + } + + TMINLP2TNLP * problem() + { + return GetRawPtr(problem_); + } + + const TMINLP * model() const + { + return GetRawPtr(tminlp_); + } + + Bonmin::TMINLP * model() + { + return GetRawPtr(tminlp_); + } + + const Bonmin::TNLPSolver * solver() const + { + return GetRawPtr(app_); + } + + const std::list<Ipopt::SmartPtr<TNLPSolver> >& debug_apps() const{ + return debug_apps_; + } + + TNLPSolver * solver() + { + return GetRawPtr(app_); + } + /** \name Methods to build outer approximations */ + //@{ + /** \name Methods to build outer approximations */ + //@{ + /** \brief Extract a linear relaxation of the MINLP. + * Use user-provided point to build first-order outer-approximation constraints at the optimum. + * And put it in an OsiSolverInterface. + */ + virtual void extractLinearRelaxation(OsiSolverInterface &si, const double *x, + bool getObj = 1); + + /** Add constraint corresponding to objective function.*/ + virtual void addObjectiveFunction(OsiSolverInterface &si, const double * x); +#if 1 + /** \brief Extract a linear relaxation of the MINLP. + * Solve the continuous relaxation and takes first-order outer-approximation constraints at the optimum. + * The put everything in an OsiSolverInterface. + */ + virtual void extractLinearRelaxation(OsiSolverInterface &si, bool getObj = 1, + bool solveNlp = 1){ + if(solveNlp) + initialSolve("build initial OA"); + extractLinearRelaxation(si, getColSolution(), getObj); + if(solveNlp){ + app_->enableWarmStart(); + setColSolution(problem()->x_sol()); + setRowPrice(problem()->duals_sol()); + } + } +#endif + /** Get the outer approximation constraints at the current optimal point. + If x2 is different from NULL only add cuts violated by x2. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + void getOuterApproximation(OsiCuts &cs, int getObj, const double * x2, bool global) +{ + getOuterApproximation(cs, getColSolution(), getObj, x2, global); +} + + /** Get the outer approximation constraints at provided point. + If x2 is different from NULL only add cuts violated by x2. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + void getOuterApproximation(OsiCuts &cs, const double * x, int getObj, const double * x2, bool global){ + getOuterApproximation(cs, x, getObj, x2, 0., global);} + + /** Get the outer approximation constraints at provided point. + If x2 is different from NULL only add cuts violated by x2 by more than delta. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + virtual void getOuterApproximation(OsiCuts &cs, const double * x, int getObj, const double * x2, + double theta, bool global); + + /** Get the outer approximation at provided point for given constraint. */ + virtual void getConstraintOuterApproximation(OsiCuts & cs, int constraintNumber, + const double * x, + const double * x2, bool global); + + /** Get the outer approximation at current optimal point for given constraint. */ + void getConstraintOuterApproximation(OsiCuts & cs, int constraintNumber, + const double * x2, bool global){ + getConstraintOuterApproximation(cs, constraintNumber, getColSolution(),x2,global); + } + + +/** Get a benders cut from solution.*/ +void getBendersCut(OsiCuts &cs, bool global); + + /** Given a point x_bar this solves the problem of finding the point which minimize a convex + *combination between the distance to x_bar and the original objective function f(x): + * \f$ min a * (\sum\limits_{i=1}^n ||x_{ind[i]} -\overline{x}_i)||_L) + (1 - a)* s *f(x) \f$ + * \return Distance between feasibility set a x_bar on components in ind + * \param n number of elements in array x_bar and ind + * \param s scaling of the original objective. + * \param a Combination to take between feasibility and original objective (must be between 0 and 1). + * \param L L-norm to use (can be either 1 or 2). + */ + double solveFeasibilityProblem(size_t n, const double * x_bar, const int* ind, double a, double s, int L); + + /** Given a point x_bar this solves the problem of finding the point which minimize + * the distance to x_bar while satisfying the additional cutoff constraint: + * \f$ min \sum\limits_{i=1}^n ||x_{ind[i]} -\overline{x}_i)||_L$ + * \return Distance between feasibility set a x_bar on components in ind + * \param n number of elements in array x_bar and ind + * \param L L-norm to use (can be either 1 or 2). + * \param cutoff objective function value of a known integer feasible solution + */ + double solveFeasibilityProblem(size_t n, const double * x_bar, const int* ind, int L, double cutoff); + + /** Given a point x_bar setup feasibility problem and switch so that every call to initialSolve or resolve will + solve it.*/ + void switchToFeasibilityProblem(size_t n, const double * x_bar, const int* ind, double a, double s, int L); + + /** Given a point x_bar setup feasibility problem and switch so that every call to initialSolve or resolve will + solve it. This is to be used in the local branching heuristic */ + void switchToFeasibilityProblem(size_t n, const double * x_bar, const int* ind, + double rhs_local_branching_constraint); + + /** switch back to solving original problem.*/ + void switchToOriginalProblem(); + + /** round solution and check its feasibility.*/ + void round_and_check(double tolerance, + OsiObject ** objects = 0, int nObjects = -1){ + if(!problem_->check_solution(objects, nObjects)){ + optimizationStatus_ = TNLPSolver::provenInfeasible; + } + } + //@} + + /** \name output for OA cut generation + \todo All OA code here should be moved to a separate class sometime.*/ + //@{ + /** OA Messages types.*/ + enum OaMessagesTypes { + CUT_NOT_VIOLATED_ENOUGH = 0/** Says that one cut has been generarted, where from, which is the violation.*/, + VIOLATED_OA_CUT_GENERATED/** Cut is not violated enough, give violation.*/, + OA_CUT_GENERATED/** Print the cut which has been generated.*/, + OA_MESSAGES_DUMMY_END/** Dummy end.*/}; + /** Class to store OA Messages.*/ + class OaMessages :public CoinMessages{ + public: + /** Default constructor.*/ + OaMessages(); + }; + /** Like a CoinMessageHandler but can print a cut also.*/ + class OaMessageHandler : public CoinMessageHandler{ + public: + /** Default constructor.*/ + OaMessageHandler():CoinMessageHandler(){ + } + /** Constructor to put to file pointer (fp won't be closed).*/ + OaMessageHandler(FILE * fp):CoinMessageHandler(fp){ + } + /** Destructor.*/ + virtual ~OaMessageHandler(){ + } + /** Copy constructor.*/ + OaMessageHandler(const OaMessageHandler &other): + CoinMessageHandler(other){} + /** Constructor from a regular CoinMessageHandler.*/ + OaMessageHandler(const CoinMessageHandler &other): + CoinMessageHandler(other){} + /** Assignment operator.*/ + OaMessageHandler & operator=(const OaMessageHandler &rhs){ + CoinMessageHandler::operator=(rhs); + return *this;} + /** Virtual copy */ + virtual CoinMessageHandler* clone() const{ + return new OaMessageHandler(*this);} + /** print an OsiRowCut.*/ + void print(OsiRowCut &row); + }; + void setOaMessageHandler(const CoinMessageHandler &handler){ + delete oaHandler_; + oaHandler_ = new OaMessageHandler(handler); + } + //@} + + //----------------------------------------------------------------------- + /** Apply a collection of cuts. + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0){ + freeCachedRowRim(); + problem_->addCuts(cs); + ApplyCutsReturnCode rc; + return rc;} + + /** Add a collection of linear cuts to problem formulation.*/ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + + + /** Add a collection of linear cuts to the problem formulation */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts) + { + if(numberCuts) + freeCachedRowRim(); + problem_->addCuts(numberCuts, cuts); + } + + /** Get infinity norm of constraint violation for x. Put into + obj the objective value of x.*/ + double getConstraintsViolation(const double * x, double & obj); + + /** Get infinity norm of constraint violation for x and error in objective + value where obj is the estimated objective value of x.*/ + double getNonLinearitiesViolation(const double *x, const double obj); + +//--------------------------------------------------------------------------- + + void extractInterfaceParams(); + + + /** To set some application specific defaults. */ + virtual void setAppDefaultOptions(Ipopt::SmartPtr<Ipopt::OptionsList> Options); + + /** Register all possible options to Bonmin */ + static void registerOptions (Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + Ipopt::SmartPtr<Bonmin::RegisteredOptions> regOptions(){ + if(IsValid(app_)) + return app_->roptions(); + else + return NULL; + } + + /** @name Methods related to strong branching */ + //@{ + /// Set the strong branching solver + void SetStrongBrachingSolver(Ipopt::SmartPtr<StrongBranchingSolver> strong_branching_solver); + /// Create a hot start snapshot of the optimization process. In our + /// case, we initialize the StrongBrachingSolver. + virtual void markHotStart(); + /// Optimize starting from the hot start snapshot. In our case, we + /// call the StrongBranchingSolver to give us an approximate + /// solution for the current state of the bounds + virtual void solveFromHotStart(); + /// Delete the hot start snapshot. In our case we deactivate the + /// StrongBrachingSolver. + virtual void unmarkHotStart(); + //@} + + /// Get values of tiny_ and very_tiny_ + void get_tolerances(double &tiny, double&very_tiny, double &rhsRelax, double &infty){ + tiny = tiny_; + very_tiny = veryTiny_; + rhsRelax = rhsRelax_; + infty = infty_; + } + + void set_linearizer(Ipopt::SmartPtr<TMINLP2OsiLP> linearizer); + + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer(); +protected: + + //@} + + enum RandomGenerationType{ + uniform =0, perturb=1, perturb_suffix=2}; + /// Initialize data structures for storing the jacobian + int initializeJacobianArrays(); + + ///@name Virtual callbacks for application specific stuff + //@{ + virtual std::string appName() + { + return "bonmin"; + } + //@} + ///@name Protected methods + //@{ + + /** Call Ipopt to solve or resolve the problem and check for errors.*/ + void solveAndCheckErrors(bool doResolve, bool throwOnFailure, + const char * whereFrom); + + + /** Add a linear cut to the problem formulation. + */ + virtual void applyRowCut( const OsiRowCut & rc ) + { + const OsiRowCut * cut = &rc; + problem_->addCuts(1, &cut); + } + /** We have to keep this but it will throw an error. + */ + virtual void applyColCut( const OsiColCut & cc ) + { + throw SimpleError("Ipopt model does not implement this function.", + "applyColCut"); + } + +// /** Read the name of the variables in an ampl .col file. */ +// void readVarNames() const; + + //@} + + /**@name Model and solver */ + //@{ + /** TMINLP model.*/ + Ipopt::SmartPtr<TMINLP> tminlp_; + /** Adapter for a MINLP to a NLP */ + Ipopt::SmartPtr<TMINLP2TNLP> problem_; + /** Problem currently optimized (may be problem_ or feasibilityProblem_)*/ + Ipopt::SmartPtr<Ipopt::TNLP> problem_to_optimize_; + /** Is true if and only if in feasibility mode.*/ + bool feasibility_mode_; + /** Solver for a TMINLP. */ + Ipopt::SmartPtr<TNLPSolver> app_; + + /** Alternate solvers for TMINLP.*/ + std::list<Ipopt::SmartPtr<TNLPSolver> > debug_apps_; + /** Do we use the other solvers?*/ + bool testOthers_; + //@} + + /** Warmstart information for reoptimization */ + CoinWarmStart* warmstart_; + + /**@name Cached information on the problem */ + //@{ + /** Free cached data relative to variables */ + void freeCachedColRim(); + /** Free cached data relative to constraints */ + void freeCachedRowRim(); + /** Free all cached data*/ + void freeCachedData(); + /** Extract rowsense_ vector rhs_ vector and rowrange_ vector from the lower and upper bounds + * on the constraints */ + void extractSenseRhsAndRange() const; + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /// Pointer to dense vector of slack upper bounds for range constraints (undefined for non-range rows) + mutable double *rowrange_; + /** Pointer to dense vector of reduced costs + \warning Always 0. with Ipopt*/ + mutable double *reducedCosts_; + /** DualObjectiveLimit is used to store the cutoff in Cbc*/ + double OsiDualObjectiveLimit_; + /** does the file variable names exists (will check automatically).*/ + mutable bool hasVarNamesFile_; + //@} + /// number of time NLP has been solved + int nCallOptimizeTNLP_; + /// Total solution time of NLP + double totalNlpSolveTime_; + /// toatal number of iterations + int totalIterations_; + /// max radius for random point + double maxRandomRadius_; + /// Method to pick a random starting point. + int randomGenerationType_; + /// Maximum perturbation value + double max_perturbation_; + /// Ipopt value for pushing initial point inside the bounds + double pushValue_; + /// Number of times problem will be resolved in initialSolve (root node) + int numRetryInitial_; + /// Number of times problem will be resolved in resolve + int numRetryResolve_; + /// Number of times infeasible problem will be resolved. + int numRetryInfeasibles_; + /// Number of times problem will be resolved in case of a failure + int numRetryUnsolved_; + /// If infeasibility for a problem is less than this, let's be carrefull. It might be feasible + double infeasibility_epsilon_; + + + //Added by Claudia + /// Dynamic cutOff_ + int dynamicCutOff_; + /// coeff_var_threshold_ + double coeff_var_threshold_; + /// first_perc_for_cutoff_decr_ + double first_perc_for_cutoff_decr_; + /// second_perc_for_cutoff_decr_ + double second_perc_for_cutoff_decr_; + + + /** Messages specific to an OsiTMINLPInterface. */ + Messages messages_; + /** If not 0 when a problem is not solved (failed to be solved) + will pretend that it is infeasible. If == 1 will care + (i.e. record the fact issue messages to user), if ==2 don't care (somebody else will) */ + int pretendFailIsInfeasible_; + + mutable int pretendSucceededNext_; + + /** did we ever continue optimization ignoring a failure. */ + bool hasContinuedAfterNlpFailure_; + /** number iterations above which a problem is considered suspect (-1 is considered \f$+ \infty \f$). + If in a call to solve a problem takes more than that number of iterations it will be output to files.*/ + int numIterationSuspect_ ; + /** Has problem been optimized since last change (include setColSolution). + If yes getColSolution will return Ipopt point, otherwise will return + initial point.*/ + bool hasBeenOptimized_; + /** A fake objective function (all variables to 1) to please Cbc + pseudo costs initialization. AW: I changed this, it will now be + the objective gradient at current point. */ + mutable double * obj_; + /** flag to say wether options have been printed or not.*/ + static bool hasPrintedOptions; + + /** Adapter for TNLP to a feasibility problem */ + Ipopt::SmartPtr<TNLP2FPNLP> feasibilityProblem_; + + /** Adapter for TMINLP to an Osi LP */ + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer_; + + /** \name Arrays to store Jacobian matrix */ + //@{ + /** Row indices.*/ + int * jRow_; + /** Column indices.*/ + int * jCol_; + /** Values */ + double * jValues_; + /** Number of elements.*/ + int nnz_jac; + //@} + + ///Store the types of the constraints (linear and nonlinear). + Ipopt::TNLP::LinearityType * constTypes_; + /** Number of nonlinear constraint + */ + int nNonLinear_; + /** Value for small non-zero element which we will try to remove cleanly in OA cuts.*/ + double tiny_; + /** Value for small non-zero element which we will take the risk to ignore in OA cuts.*/ + double veryTiny_; + /** Amount by which to relax OA constraints RHSes*/ + double rhsRelax_; + /** Value for infinity. */ + double infty_; + /** status of last optimization. */ + TNLPSolver::ReturnStatus optimizationStatus_; + /** Flag indicating if the warm start methods actually do something.*/ + WarmStartModes warmStartMode_; + /** Is it the first solve (for random starting point at root options).*/ + bool firstSolve_; + /** Object for strengthening cuts */ + Ipopt::SmartPtr<CutStrengthener> cutStrengthener_; + + /** \name output for OA cut generation + \todo All OA code here should be moved to a separate class sometime.*/ + //@{ + /** OA Messages.*/ + OaMessages oaMessages_; + /** OA Message handler. */ + OaMessageHandler * oaHandler_; + //@} + + double newCutoffDecr; +protected: + /** Facilitator to create an application. */ + void createApplication(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + ///Constructor without model only for derived classes + OsiTMINLPInterface(Ipopt::SmartPtr<TNLPSolver> app); + + /** Internal set warm start.*/ + bool internal_setWarmStart(const CoinWarmStart* ws); + + /** internal get warm start.*/ + CoinWarmStart* internal_getWarmStart() const; + + /** Procedure that builds a fake basis. Only tries to make basis consistent with constraints activity.*/ + CoinWarmStart* build_fake_basis() const; +private: + + /** solver to be used for all strong branching solves */ + Ipopt::SmartPtr<StrongBranchingSolver> strong_branching_solver_; + /** status of last optimization before hot start was marked. */ + TNLPSolver::ReturnStatus optimizationStatusBeforeHotStart_; +static const char * OPT_SYMB; +static const char * FAILED_SYMB; +static const char * INFEAS_SYMB; +static const char * TIME_SYMB; +static const char * UNBOUND_SYMB; + /** Get status as a char * for log.*/ + const char * statusAsString(TNLPSolver::ReturnStatus r){ + if(r == TNLPSolver::solvedOptimal || r == TNLPSolver::solvedOptimalTol){ + return OPT_SYMB;} + else if(r == TNLPSolver::provenInfeasible){ + return INFEAS_SYMB;} + else if(r == TNLPSolver::unbounded){ + return UNBOUND_SYMB;} + else if(r == TNLPSolver::timeLimit){ + return TIME_SYMB;} + else return FAILED_SYMB; + } + const char * statusAsString(){ + return statusAsString(optimizationStatus_);} +}; +} +#endif diff --git a/thirdparty/linux/include/coin/BonOuterApprox.hpp b/thirdparty/linux/include/coin/BonOuterApprox.hpp new file mode 100644 index 0000000..5f24f61 --- /dev/null +++ b/thirdparty/linux/include/coin/BonOuterApprox.hpp @@ -0,0 +1,123 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/16/2007 +#ifndef BonminOuterApprox_H +#define BonminOuterApprox_H + +#include <cmath> + +namespace Bonmin{ + class OsiTMINLPInterface; + class BabSetupBase; +} +class OsiSolverInterface; +namespace Bonmin { + /** A class to build outer approximations.*/ + class OuterApprox{ + + public: + + /** Default constructor.*/ + OuterApprox(): + tiny_(-0.), + veryTiny_(-0.) + {} + + /** Copy constructor.*/ + OuterApprox(const OuterApprox & other): + tiny_(other.tiny_), + veryTiny_(other.veryTiny_){ + } + + + /** Assignment operator.*/ + OuterApprox & operator=(const OuterApprox& rhs){ + if(this != & rhs){ + tiny_ = rhs.tiny_; + veryTiny_ = rhs.veryTiny_;} + return (*this); + } + + /** Destructor.*/ + ~OuterApprox(){} + + /** Initialize using options.*/ + void initialize(Bonmin::BabSetupBase &b); + + /** Build the Outer approximation in minlp and put it in si.*/ + void extractLinearRelaxation(Bonmin::OsiTMINLPInterface &minlp, + OsiSolverInterface *si, + const double * x, bool getObj); + /** Operator() calls extractLinearRelaxation*/ + void operator()(Bonmin::OsiTMINLPInterface &minlp, + OsiSolverInterface *si, + const double * x, bool getObj){ + extractLinearRelaxation(minlp, si, x, getObj);} + + private: + /** Facilitator to clean up coefficient.*/ + inline bool cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny); + /** If constraint coefficient is below this, we try to remove it.*/ + double tiny_; + /** If constraint coefficient is below this, we neglect it.*/ + double veryTiny_; + /** Count the number of linear outer approximations taken.*/ + static int nTimesCalled; + }; + +//A procedure to try to remove small coefficients in OA cuts (or make it non small +inline +bool +OuterApprox::cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) +{ + if(fabs(value)>= tiny) return 1; + + if(fabs(value)<veryTiny) return 0;//Take the risk? + + //try and remove + double infty = 1e20; + bool colUpBounded = colUpper < 10000; + bool colLoBounded = colLower > -10000; + bool rowNotLoBounded = rowLower <= - infty; + bool rowNotUpBounded = rowUpper >= infty; + bool pos = value > 0; + + if(colLoBounded && pos && rowNotUpBounded) { + lb += value * (colsol - colLower); + return 0; + } + else + if(colLoBounded && !pos && rowNotLoBounded) { + ub += value * (colsol - colLower); + return 0; + } + else + if(colUpBounded && !pos && rowNotUpBounded) { + lb += value * (colsol - colUpper); + return 0; + } + else + if(colUpBounded && pos && rowNotLoBounded) { + ub += value * (colsol - colUpper); + return 0; + } + //can not remove coefficient increase it to smallest non zero + if(pos) value = tiny; + else + value = - tiny; + return 1; +} + +} + +#endif + diff --git a/thirdparty/linux/include/coin/BonPseudoCosts.hpp b/thirdparty/linux/include/coin/BonPseudoCosts.hpp new file mode 100644 index 0000000..b7934e5 --- /dev/null +++ b/thirdparty/linux/include/coin/BonPseudoCosts.hpp @@ -0,0 +1,91 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/12/2007 + +#ifndef BonPseudoCosts_H +#define BonPseudoCosts_H + +#include "OsiChooseVariable.hpp" +namespace Bonmin +{ + + class PseudoCosts: public OsiPseudoCosts + { + public: + /** Default constructor.*/ + PseudoCosts(); + + /** Copy constructor.*/ + PseudoCosts(const PseudoCosts & rhs); + + /** Assignment operator const version.*/ + PseudoCosts & operator=(const PseudoCosts&rhs); +#if 0 + /** Acces upTotalChange.*/ + inline double * upTotalChange() + { + return upTotalChange_; + } + + /** Acces downTotalChange.*/ + inline double * downTotalChange() + { + return downTotalChange_; + } + + /** Acces upNumber.*/ + inline int * upNumber() + { + return upNumber_; + } + + /** Acces downNumber.*/ + inline int * downNumber() + { + return downNumber_; + } + + /** Acces upTotalChange.*/ + inline const double * upTotalChange() const + { + return upTotalChange_; + } + + /** Acces downTotalChange.*/ + inline const double * downTotalChange() const + { + return downTotalChange_; + } + + /** Acces upNumber.*/ + inline const int * upNumber() const + { + return upNumber_; + } + + /** Acces downNumber.*/ + inline const int * downNumber() const + { + return downNumber_; + } + + /** Access number objects.*/ + inline int numberObjects() const + { + return numberObjects_; + } +#endif + /** Add a pseudo cost information.*/ + void addInfo(int way, double originalObj, double originalInfeas, + double newObj, double newInfeas, int status); + + }; + +}/* End Bonmin namespace.*/ + +#endif diff --git a/thirdparty/linux/include/coin/BonPumpForMinlp.hpp b/thirdparty/linux/include/coin/BonPumpForMinlp.hpp new file mode 100644 index 0000000..e2b7cb1 --- /dev/null +++ b/thirdparty/linux/include/coin/BonPumpForMinlp.hpp @@ -0,0 +1,45 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 02/18/2009 + +#ifndef BonPumpForMinlp_H +#define BonPumpForMinlp_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class PumpForMinlp:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + PumpForMinlp(); + /** Constructor with setup.*/ + PumpForMinlp(BonminSetup * setup); + + /** Copy constructor.*/ + PumpForMinlp(const PumpForMinlp &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new PumpForMinlp(*this); + } + + /** Destructor*/ + virtual ~PumpForMinlp(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Setup the defaults.*/ + virtual void setupDefaults(Ipopt::SmartPtr<Ipopt::OptionsList> options); + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/BonQuadCut.hpp b/thirdparty/linux/include/coin/BonQuadCut.hpp new file mode 100644 index 0000000..8cbf0c8 --- /dev/null +++ b/thirdparty/linux/include/coin/BonQuadCut.hpp @@ -0,0 +1,217 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonQuadCut_H +#define BonQuadCut_H + +#include "CoinPackedMatrix.hpp" +#include "OsiRowCut.hpp" +#include "OsiCuts.hpp" +#include "BonTypes.hpp" +#include <list> + + +namespace Bonmin { + + enum MatrixStorageType { + Upper /** Stores only the upper triangle of a symetric Q.*/, + Lower /** Stores the lower triangle of a symetric Q.*/, + Full /** Stores the whole matrix of a non-symetric Q.*/}; + +class QuadCut : public OsiRowCut { + public: + + /// Default constructor + QuadCut(); + + /// Copy constructor + QuadCut(const QuadCut & other); + + /// Assignment operator + QuadCut& operator=(const QuadCut & rhs); + + /// Virtual copy + virtual OsiRowCut * clone() const; + + /// Destructor + ~QuadCut(); + + /// Print + void print() const; + + ///Return the matrix stored + CoinPackedMatrix& Q(){ + return Q_; + } + + ///Return the matrix stored + const CoinPackedMatrix& Q() const{ + return Q_; + } + + /// Acces storage type + /// Acces storage type + MatrixStorageType& type(){ + return type_;} + + const MatrixStorageType& type() const{ + return type_;} + + /// Acces the constant + double & c(){return c_;} + + /// Acces the constant + const double & c() const {return c_;} + + /// Compute cut violation + double violated(const double * solution) const; + + private: + /// Stores the constant part of the cut + double c_; + ///Stores quadratic part of cut + CoinPackedMatrix Q_; + ///Storage type + MatrixStorageType type_; + + /** \name Arithmetic operators not implemented.*/ + //@{ + /// add <code>value</code> to every vector entry + void operator+=(double value); + + /// subtract <code>value</code> from every vector entry + void operator-=(double value); + + /// multiply every vector entry by <code>value</code> + void operator*=(double value); + + /// divide every vector entry by <code>value</code> + void operator/=(double value); + //@} + +}; + +/** Generalizes OsiCuts to handle quadratic cuts.*/ +class Cuts : public OsiCuts { + public: + typedef vector<QuadCut *> QuadCutPtrStorage; + /** Default constructor.*/ + Cuts(); + + /** Copy constructor.*/ + Cuts(const Cuts& other); + + /** Assignment operator.*/ + Cuts& operator=(const Cuts & rhs); + + /** Destructor */ + ~Cuts(); + + /** insert a quadratic cut into the collection. */ + inline void insert(const QuadCut& c); + + /** insert a quadratic cut into the collection (take control of the pointer and + put a NULL on return). + \warning c has to have been created with new (no malloc). + */ + inline void insert(QuadCut* &c); + + /** insert a set of Cuts.*/ + inline void insert(const Cuts &cs); + + /** Number of quadratic cuts in the collection.*/ + inline int sizeQuadCuts() const; + + /** Total number of cuts in the collection. */ + inline int sizeCuts() const; + + /** Print all cuts in the collection.*/ + void printCuts() const; + + + /** Access to a quadratic cut by pointer.*/ + inline QuadCut * quadCutPtr(int i); + + /** Access to a quadratic cut by const pointer.*/ + inline const QuadCut * quadCutPtr(int i) const; + + /** Access to a quadratic cut by reference.*/ + inline QuadCut& quadCut(int i); + + + /** Access to a quadratic cut by reference.*/ + inline const QuadCut& quadCut(int i) const; + + /** Erase quadratic cut from the collection.*/ + inline void eraseQuadCut(int i); + + private: + QuadCutPtrStorage quadCuts_; +}; + +void +Cuts::insert(const QuadCut &c){ + quadCuts_.push_back(new QuadCut(c)); +} + +void +Cuts::insert(QuadCut * &c){ + quadCuts_.push_back(c); + c = NULL; +} + +void +Cuts::insert(const Cuts & cs){ + OsiCuts::insert(cs); + for(unsigned int i = 0 ; i < cs.quadCuts_.size() ; i++){ + quadCuts_.push_back(new QuadCut(*cs.quadCuts_[i])); + } +} + +int +Cuts::sizeQuadCuts() const { + return static_cast<int>(quadCuts_.size()); +} + +int +Cuts::sizeCuts() const { + return static_cast<int>(quadCuts_.size()) + OsiCuts::sizeCuts(); +} + +QuadCut * +Cuts::quadCutPtr(int i) { + return quadCuts_[i]; +} + +const QuadCut * +Cuts::quadCutPtr(int i) const { + return quadCuts_[i]; +} + +QuadCut & +Cuts::quadCut(int i) { + return *quadCuts_[i]; +} + +const QuadCut & +Cuts::quadCut(int i) const { + return *quadCuts_[i]; +} + +void +Cuts::eraseQuadCut(int i){ + delete quadCuts_[i]; + quadCuts_.erase(quadCuts_.begin() + i); +} +typedef std::list<QuadCut*> list_QuadCut; + +}// Ends Bonmin namespace +#endif + + diff --git a/thirdparty/linux/include/coin/BonQuadRow.hpp b/thirdparty/linux/include/coin/BonQuadRow.hpp new file mode 100644 index 0000000..2508abd --- /dev/null +++ b/thirdparty/linux/include/coin/BonQuadRow.hpp @@ -0,0 +1,122 @@ +/// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonQuadRow_H +#define BonQuadRow_H + +#include "CoinPackedVector.hpp" +#include "BonTMatrix.hpp" +#include "BonQuadCut.hpp" + +namespace Bonmin{ + + /** Store column and row of the entry.*/ + typedef std::pair<int, int> matEntry; + /** Store the number of times entry is used and its index in the matrix.*/ + typedef std::pair<int, int> matIdx; +#if HAS_HASH_MAP + typedef std::has_map<matEntry, matIdx, std::hash< matEntry> > AdjustableMat; +#else + typedef std::map<matEntry, matIdx> AdjustableMat; +#endif + +/** Stores a quadratic row of the form l < c + ax + x^T Q x < u. + Does computation usefull for nlp-solver. + It can only be initialized from a QuadCut.*/ +class QuadRow { + public: + /** Default constructor.*/ + QuadRow(); + + /** Copy constructor.*/ + QuadRow(const QuadRow & other); + + /** Assignment operator.*/ + QuadRow& operator=(const QuadRow& rhs); + + /** Constructor from a quadratic cut.*/ + QuadRow(const QuadCut &cut); + + /** Assignment form a quadrattic &cut.*/ + QuadRow& operator=(const QuadCut & rhs); + + /** Constructor from a linear cut.*/ + QuadRow(const OsiRowCut &cut); + + /** Assignment form a linear &cut.*/ + QuadRow& operator=(const OsiRowCut & rhs); + + /** Evaluate quadratic form.*/ + double eval_f(const double *x, bool new_x); + + /** Get number of non-zeroes in the gradiant.*/ + int nnz_grad(); + /** Get structure of gradiant */ + void gradiant_struct(const int nnz, int * indices, bool offset); + /** Evaluate gradiant of quadratic form.*/ + void eval_grad(const int nnz, const double * x, bool new_x, double * values); + + /** number of non-zeroes in hessian. */ + int nnz_hessian(){ + return Q_.nnz_;} + + /** Says if the constraint is linear.*/ + bool isLinear(){ + return Q_.nnz_ == 0;} + + /** Return hessian value (i.e. Q_).*/ + void eval_hessian(double lambda, double * values); + + /** Add row to a bigger hessian.*/ + void add_to_hessian(AdjustableMat &H, bool offset); + + /** Remove row from a bigger hessian.*/ + void remove_from_hessian(AdjustableMat &H); +/** Print quadratic constraint.*/ +void print(); + + private: + /** Initialize once quadratic form is know.*/ + void initialize(); + + /** Does internal work to evaluate gradiant of this in x.*/ + void internal_eval_grad(const double *x); + + /** lower bound.*/ + double lb_; + /** upper bound.*/ + double ub_; + /** Constant term.*/ + double c_; + /** linear term in sparse storage.*/ + CoinPackedVector a_; + /** Quadratic term.*/ + TMat Q_; + + +#if HAS_HASH_MAP + typedef std::has_map<int, std::pair<double, double >, std::hash<int> > gStore; +#else + typedef std::map<int, std::pair<double, double> > gStore; +#endif + + gStore g_; + /** To have fast access to gradiant entries for a_.*/ + std::vector<gStore::iterator> a_grad_idx_; + /** To have fast access to gradient entries for rows Q_*/ + std::vector<gStore::iterator> Q_row_grad_idx_; + /** To have fast access to gradient entries for cols Q_*/ + std::vector<gStore::iterator> Q_col_grad_idx_; + /** To have fast access to entries in full hessian of Q_*/ + std::vector<AdjustableMat::iterator> Q_hessian_idx_; + /** Flag indicating if gradiant has been evaluated.*/ + bool grad_evaled_; +}; +}//End Bonmin namespace +#endif diff --git a/thirdparty/linux/include/coin/BonRegisteredOptions.hpp b/thirdparty/linux/include/coin/BonRegisteredOptions.hpp new file mode 100644 index 0000000..8679eda --- /dev/null +++ b/thirdparty/linux/include/coin/BonRegisteredOptions.hpp @@ -0,0 +1,225 @@ +// (C) Copyright International Business Machines Corporation 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 27/08/2007 + +#ifndef BonRegisteredOptions_H +#define BonRegisteredOptions_H + +#include "IpRegOptions.hpp" +#include "IpException.hpp" +#include "CoinError.hpp" +#include "IpTypes.hpp" +#include <iostream> + +/* Forward declaration, the function will be defined in BonAmplTMINLP.cpp, if ASL is available */ +namespace Ipopt { + class AmplOptionsList; +} + +namespace Bonmin { +/** Class to add a few more information to Ipopt::RegisteredOptions. + In particular, it allows to store code to indicate in which algorithm + option is available. It also allows to table summing up all the options + both in LaTex and html.*/ +class RegisteredOptions: public Ipopt::RegisteredOptions{ + public: + enum ExtraOptInfosBits{ + validInHybrid=0/** Say that option is valid in Hybrid method (1).*/, + validInQG/** Say that option is valid in Quesada Grossmann method (2).*/, + validInOA/**Say that option is valid in outer approximation dec (4).*/, + validInBBB/** Say that option is valid in the pure branch-and-bound (8).*/, + validInEcp/** Say that option is valid in the Ecp (16).*/, + validIniFP/** Say that option is valid in the iFP (32).*/, + validInCbc/** Say that option is valid when using Cbc_Par (64).*/ + }; + + +/* Table of values + * only B-Hyb 1 + * B-Hyb & B-QG 3 + * B-Hyb & B-OA 5 + * B-Hyb & B-QG & B-OA & B-ECP 23 + */ + + + + enum ExtraCategoriesInfo{ + BonminCategory = 0/** Option category is for Bonmin.*/, + IpoptCategory /** Option category for Ipopt.*/, + FilterCategory /** Option category for FilterSqp.*/, + BqpdCategory /** Option category for Bqpd.*/, + CouenneCategory /** Option category for Couenne.*/, + UndocumentedCategory /**For undocumented options.*/ + }; + /** Standard constructor.*/ + RegisteredOptions(): + Ipopt::RegisteredOptions(){ + } + + /** Standard destructor.*/ + ~RegisteredOptions(){ + } + + //DECLARE_STD_EXCEPTION(OPTION_NOT_REGISTERED); + /** Set registering category with extra information.*/ + void SetRegisteringCategory (const std::string ®istering_category, + const ExtraCategoriesInfo extra){ + Ipopt::RegisteredOptions::SetRegisteringCategory(registering_category); + categoriesInfos_[registering_category] = extra;} + + /** throw if option does not exists.*/ + inline void optionExists(const std::string & option){ + if(!IsValid(GetOption(option))){ + std::string msg = "Try to access option: "+option; + msg += "\n Option is not registered.\n"; + throw CoinError("Bonmin::RegisteredOption","optionExists",msg); + } + } + + /**Set extra information for option.*/ + inline void setOptionExtraInfo(const std::string & option, int code){ + optionExists(option); + bonOptInfos_[option] = code; + } + + /** Set that option is valid for hybrid.*/ + inline void optionValidForHybrid(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInHybrid;} + + /** Set that option is valid for QuesadaGrossmann.*/ + inline void optionValidForBQG(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInQG;} + + /** Set that option is valid for Outer approximation.*/ + inline void optionValidForBOA(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInOA;} + + /** Set that option is valid for pure branch-and-bound.*/ + inline void optionValidForBBB(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInBBB;} + + /** Set that option is valid for B-Ecp.*/ + inline void optionValidForBEcp(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInEcp;} + + /** Set that option is valid for B-iFP.*/ + inline void optionValidForBiFP(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validIniFP;} + + /** Set that option is valid for Cbc.*/ + inline void optionValidForCbc(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInCbc;} + + + /** Say if option is valid for hybrid.*/ + inline bool isValidForHybrid(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInHybrid); + else return true;} + + /** Say if option is valid for QuesadaGrossmann.*/ + inline bool isValidForBQG(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInQG); + else return true;} + + /** Say if option is valid for Outer approximation.*/ + inline bool isValidForBOA(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInOA); + return true;} + + /** Say if option is valid for pure branch-and-bound.*/ + inline bool isValidForBBB(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInBBB); + return true;} + + + /** Say if option is valid for B-Ecp.*/ + inline bool isValidForBEcp(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInEcp); + return true;} + + + /** Say if option is valid for B-iFP.*/ + inline bool isValidForBiFP(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validIniFP); + return true;} + + + /** Say if option is valid for Cbc.*/ + inline bool isValidForCbc(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInCbc); + return true;} + + + /** Output Latex table of options.*/ + void writeLatexOptionsTable(std::ostream &of, ExtraCategoriesInfo which); + + /** Output html table of options.*/ + void writeHtmlOptionsTable(std::ostream &of, ExtraCategoriesInfo which); + + + /** Output Latex/Html ooptions documentation.*/ + void writeLatexHtmlDoc(std::ostream &of, ExtraCategoriesInfo which); + /** Ouptut a bonmin.opt file with options default values and short descriptions.*/ + void writeBonminOpt(std::ostream &os, ExtraCategoriesInfo which); + + /** Get info about what a category is taking care of (e.g., Ipopt, Bonmin, FilterSQP,...) .*/ + ExtraCategoriesInfo categoriesInfo(const std::string &s) + { + std::map<std::string, ExtraCategoriesInfo>::iterator i = categoriesInfos_.find(s); + if(i == categoriesInfos_.end()) + return IpoptCategory; + return i->second; + } + + /* Forward declaration, the function will be defined in BonAmplTMINLP.cpp*/ + void fillAmplOptionList(ExtraCategoriesInfo which, Ipopt::AmplOptionsList * amplOptList); + + private: + /** Output Latex table of options.*/ + void chooseOptions(ExtraCategoriesInfo which, std::list<Ipopt::RegisteredOption *> &options); + /** Output html table of options.*/ + void writeHtmlOptionsTable(std::ostream & os, std::list<Ipopt::RegisteredOption *> &options); + /** Store extra Informations on Bonmin options.*/ + std::map<std::string, int> bonOptInfos_; + /** Store extra Informations on Registering categories + (is bonmin, filterSqp...).*/ + std::map<std::string, ExtraCategoriesInfo> categoriesInfos_; +}; + +}/*Ends namespace Bonmin.*/ +#endif + diff --git a/thirdparty/linux/include/coin/BonStrongBranchingSolver.hpp b/thirdparty/linux/include/coin/BonStrongBranchingSolver.hpp new file mode 100644 index 0000000..087d2e7 --- /dev/null +++ b/thirdparty/linux/include/coin/BonStrongBranchingSolver.hpp @@ -0,0 +1,69 @@ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// +// Author: Andreas Waechter 2007-08-20 IBM +// +#ifndef BonStrongBranchingSolver_H +#define BonStrongBranchingSolver_H + +#include "BonOsiTMINLPInterface.hpp" +#include "BonRegisteredOptions.hpp" +namespace Bonmin { + +/** This class is the base class for a solver that can be used in + * BonOsiSolverInterface to perform the strong branching solves. +*/ + +class StrongBranchingSolver : public Ipopt::ReferencedObject { + +public: + + /// Constructor from solver + StrongBranchingSolver (OsiTMINLPInterface * solver); + + /// Assignment operator + StrongBranchingSolver & operator= (const StrongBranchingSolver& rhs); + /// Copy constructor + StrongBranchingSolver(const StrongBranchingSolver& rhs); + + /// Destructor + virtual ~StrongBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + +protected: + + inline Ipopt::SmartPtr<Ipopt::Journalist>& Jnlst() + { + return jnlst_; + } + inline Ipopt::SmartPtr<Ipopt::OptionsList>& Options() + { + return options_; + } + inline Ipopt::SmartPtr<RegisteredOptions>& RegOptions() + { + return reg_options_; + } +private: + /** Default Constructor, forbiden for some reason.*/ + StrongBranchingSolver (); + + Ipopt::SmartPtr<Ipopt::Journalist> jnlst_; + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + Ipopt::SmartPtr<Bonmin::RegisteredOptions> reg_options_; + + int bb_log_level_; + +}; + +} +#endif diff --git a/thirdparty/linux/include/coin/BonSubMipSolver.hpp b/thirdparty/linux/include/coin/BonSubMipSolver.hpp new file mode 100644 index 0000000..d7749c2 --- /dev/null +++ b/thirdparty/linux/include/coin/BonSubMipSolver.hpp @@ -0,0 +1,143 @@ +// (C) Copyright International Business Machines (IBM) 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/07/2006 + + +// Code separated from BonOaDecBase to try to clarify OAs +#ifndef BonSubMipSolver_HPP +#define BonSubMipSolver_HPP +#include "IpSmartPtr.hpp" +#include <string> +/* forward declarations.*/ +class OsiSolverInterface; +class OsiClpSolverInterface; +class OsiCpxSolverInterface; +class CbcStrategy; +class CbcStrategyDefault; + +#include "OsiCuts.hpp" + +namespace Bonmin { + class RegisteredOptions; + class BabSetupBase; + /** A very simple class to provide a common interface for solving MIPs with Cplex and Cbc.*/ + class SubMipSolver + { + public: + enum MILP_solve_strategy{ + FindGoodSolution, + GetOptimum}; + /** Constructor */ + SubMipSolver(BabSetupBase &b, const std::string &prefix); + + /** Copy Constructor */ + SubMipSolver(const SubMipSolver ©); + + ~SubMipSolver(); + + /** Assign lp solver. */ + void setLpSolver(OsiSolverInterface * lp); + + /** Assign a strategy. */ + void setStrategy(CbcStrategyDefault * strategy); + + /** get the solution found in last local search (return NULL if no solution). */ + const double * getLastSolution() + { + return integerSolution_; + } + + double getLowerBound() + { + return lowBound_; + } + + void solve(double cutoff, + int loglevel, + double maxTime){ + if(milp_strat_ == FindGoodSolution){ + find_good_sol(cutoff, loglevel, maxTime); + } + else + optimize(cutoff, loglevel, maxTime); + } + + + /** update cutoff and perform a local search to a good solution. */ + void find_good_sol(double cutoff, + int loglevel, + double maxTime); + + /** update cutoff and optimize MIP. */ + void optimize(double cutoff, + int loglevel, + double maxTime); + + /** update cutoff, put OA constraints in cs as lazy constraints and optimize MIP. */ + void optimize_with_lazy_constraints(double cutoff, + int loglevel, + double maxTime, const OsiCuts & cs); + + /** Returns lower bound. */ + inline double lowBound() + { + return lowBound_; + } + + /** returns optimality status. */ + inline bool optimal() + { + return optimal_; + } + + /** Returns number of nodes in last solve.*/ + inline int nodeCount() + { + return nodeCount_; + } + + /** Returns number of simplex iterations in last solve.*/ + inline int iterationCount() + { + return iterationCount_; + } + + + OsiSolverInterface * solver(); + + /** Register options for that Oa based cut generation method. */ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + private: + /** If lp solver is clp (then have to use Cbc) (not owned).*/ + OsiClpSolverInterface *clp_; + /** If mip solver is cpx this is it (owned). */ + OsiCpxSolverInterface * cpx_; + /** lower bound obtained */ + double lowBound_; + /** Is optimality proven? */ + bool optimal_; + /** Has an integer solution? then it is here*/ + double * integerSolution_; + /** Strategy for solving sub mips with cbc. */ + CbcStrategyDefault * strategy_; + /** number of nodes in last mip solved.*/ + int nodeCount_; + /** number of simplex iteration in last mip solved.*/ + int iterationCount_; + /** MILP search strategy.*/ + MILP_solve_strategy milp_strat_; + /** setting for gap tolerance.*/ + double gap_tol_; + /** say if owns copy of clp_.*/ + bool ownClp_; + }; + +} + +#endif + diff --git a/thirdparty/linux/include/coin/BonTMINLP.hpp b/thirdparty/linux/include/coin/BonTMINLP.hpp new file mode 100644 index 0000000..b6d21e1 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMINLP.hpp @@ -0,0 +1,420 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2004, 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + +#ifndef __TMINLP_HPP__ +#define __TMINLP_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpAlgTypes.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiCuts.hpp" +#include "IpTNLP.hpp" +#include "CoinError.hpp" +#include "CoinHelperFunctions.hpp" + +namespace Bonmin +{ + DECLARE_STD_EXCEPTION(TMINLP_INVALID); + DECLARE_STD_EXCEPTION(TMINLP_INVALID_VARIABLE_BOUNDS); + + /** Base class for all MINLPs that use a standard triplet matrix form + * and dense vectors. + * The class TMINLP2TNLP allows the caller to produce a viable TNLP + * from the MINLP (by relaxing binary and/or integers, or by + * fixing them), which can then be solved by Ipopt. + * + * This interface presents the problem form: + * \f[ + * \begin{array}{rl} + * &min f(x)\\ + * + * \mbox{s.t.}&\\ + * & g^L <= g(x) <= g^U\\ + * + * & x^L <= x <= x^U\\ + * \end{array} + * \f] + * Where each x_i is either a continuous, binary, or integer variable. + * If x_i is binary, the bounds [xL,xU] are assumed to be [0,1]. + * In order to specify an equality constraint, set gL_i = gU_i = + * rhs. The value that indicates "infinity" for the bounds + * (i.e. the variable or constraint has no lower bound (-infinity) + * or upper bound (+infinity)) is set through the option + * nlp_lower_bound_inf and nlp_upper_bound_inf. To indicate that a + * variable has no upper or lower bound, set the bound to + * -ipopt_inf or +ipopt_inf respectively + */ + class TMINLP : public Ipopt::ReferencedObject + { + public: + friend class TMINLP2TNLP; + /** Return statuses of algorithm.*/ + enum SolverReturn{ + SUCCESS, + INFEASIBLE, + CONTINUOUS_UNBOUNDED, + LIMIT_EXCEEDED, + USER_INTERRUPT, + MINLP_ERROR}; + /** Class to store sos constraints for model */ + struct SosInfo + { + /** Number of SOS constraints.*/ + int num; + /** Type of sos. At present Only type '1' SOS are supported by Cbc*/ + char * types; + /** priorities of sos constraints.*/ + int * priorities; + + /** \name Sparse storage of the elements of the SOS constraints.*/ + /** @{ */ + /** Total number of non zeroes in SOS constraints.*/ + int numNz; + /** For 0 <= i < nums, start[i] gives the indice of indices and weights arrays at which the description of constraints i begins..*/ + int * starts; + /** indices of elements belonging to the SOS.*/ + int * indices; + /** weights of the elements of the SOS.*/ + double * weights; + /** @} */ + /** default constructor. */ + SosInfo(); + /** Copy constructor.*/ + SosInfo(const SosInfo & source); + + + /** destructor*/ + ~SosInfo() + { + gutsOfDestructor(); + } + + + /** Reset information */ + void gutsOfDestructor(); + + }; + + /** Stores branching priorities information. */ + struct BranchingInfo + { + /**number of variables*/ + int size; + /** User set priorities on variables. */ + int * priorities; + /** User set preferered branching direction. */ + int * branchingDirections; + /** User set up pseudo costs.*/ + double * upPsCosts; + /** User set down pseudo costs.*/ + double * downPsCosts; + BranchingInfo(): + size(0), + priorities(NULL), + branchingDirections(NULL), + upPsCosts(NULL), + downPsCosts(NULL) + {} + BranchingInfo(const BranchingInfo &other) + { + gutsOfDestructor(); + size = other.size; + priorities = CoinCopyOfArray(other.priorities, size); + branchingDirections = CoinCopyOfArray(other.branchingDirections, size); + upPsCosts = CoinCopyOfArray(other.upPsCosts, size); + downPsCosts = CoinCopyOfArray(other.downPsCosts, size); + } + void gutsOfDestructor() + { + if (priorities != NULL) delete [] priorities; + priorities = NULL; + if (branchingDirections != NULL) delete [] branchingDirections; + branchingDirections = NULL; + if (upPsCosts != NULL) delete [] upPsCosts; + upPsCosts = NULL; + if (downPsCosts != NULL) delete [] downPsCosts; + downPsCosts = NULL; + } + ~BranchingInfo() + { + gutsOfDestructor(); + } + }; + + /** Class to store perturbation radii for variables in the model */ + class PerturbInfo + { + public: + /** default constructor. */ + PerturbInfo() : + perturb_radius_(NULL) + {} + + /** destructor*/ + ~PerturbInfo() + { + delete [] perturb_radius_; + } + + /** Method for setting the perturbation radii. */ + void SetPerturbationArray(Ipopt::Index numvars, const double* perturb_radius); + + /** Method for getting the array for the perturbation radii in + * order to use the values. */ + const double* GetPerturbationArray() const { + return perturb_radius_; + } + + private: + /** Copy constructor.*/ + PerturbInfo(const PerturbInfo & source); + + /** Perturbation radii for all variables. A negative value + * means that the radius has not been given. If the pointer is + * NULL, then no variables have been assigned a perturbation + * radius. */ + double* perturb_radius_; + }; + + /** Type of the variables.*/ + enum VariableType + { + CONTINUOUS, + BINARY, + INTEGER + }; + + /**@name Constructors/Destructors */ + //@{ + TMINLP(); + + /** Default destructor */ + virtual ~TMINLP(); + //@} + + /**@name methods to gather information about the MINLP */ + //@{ + /** overload this method to return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style)=0; + + /** overload this method to return scaling parameters. This is + * only called if the options are set to retrieve user scaling. + * There, use_x_scaling (or use_g_scaling) should get set to true + * only if the variables (or constraints) are to be scaled. This + * method should return true only if the scaling parameters could + * be provided. + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling) + { + return false; + } + + + /** overload this method to provide the variables types. The var_types + * array will be allocated with length n. */ + virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types)=0; + + /** overload this method to provide the variables linearity. + * array should be allocated with length at least n.*/ + virtual bool get_variables_linearity(Ipopt::Index n, + Ipopt::TNLP::LinearityType* var_types) = 0; + + /** overload this method to provide the constraint linearity. + * array should be allocated with length at least m.*/ + virtual bool get_constraints_linearity(Ipopt::Index m, + Ipopt::TNLP::LinearityType* const_types) = 0; + + /** overload this method to return the information about the bound + * on the variables and constraints. The value that indicates + * that a bound does not exist is specified in the parameters + * nlp_lower_bound_inf and nlp_upper_bound_inf. By default, + * nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is + * 1e19. + * An exception will be thrown if x_l and x_u are not 0,1 for binary variables + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)=0; + + /** overload this method to return the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda)=0; + + /** overload this method to return the value of the objective function */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value)=0; + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f)=0; + + /** overload this method to return the vector of constraint values */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g)=0; + + /** overload this method to return the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values)=0; + + /** overload this method to return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values)=0; + /** Compute the value of a single constraint. The constraint + * number is i (starting counting from 0. */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi) + { + std::cerr << "Method eval_gi not overloaded from TMINLP\n"; + throw -1; + } + /** Compute the structure or values of the gradient for one + * constraint. The constraint * number is i (starting counting + * from 0. Other things are like with eval_jac_g. */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values) + { + std::cerr << "Method eval_grad_gi not overloaded from TMINLP\n"; + throw -1; + } + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(TMINLP::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value) =0; + //@} + + virtual const BranchingInfo * branchingInfo() const = 0; + + virtual const SosInfo * sosConstraints() const = 0; + + virtual const PerturbInfo* perturbInfo() const + { + return NULL; + } + + /** Say if has a specific function to compute upper bounds*/ + virtual bool hasUpperBoundingObjective(){ + return false;} + + /** overload this method to return the value of an alternative objective function for + upper bounding (to use it hasUpperBoundingObjective should return true).*/ + virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x, + Ipopt::Number& obj_value){ return false; } + + /** Used to mark constraints of the problem.*/ + enum Convexity { + Convex/** Constraint is convex.*/, + NonConvex/** Constraint is non-convex.*/, + SimpleConcave/** Constraint is concave of the simple form y >= F(x).*/}; + + /** Structure for marked non-convex constraints. With possibility of + storing index of a constraint relaxing the non-convex constraint*/ + struct MarkedNonConvex { + /** Default constructor gives "safe" values.*/ + MarkedNonConvex(): + cIdx(-1), cRelaxIdx(-1){} + /** Index of the nonconvex constraint.*/ + int cIdx; + /** Index of constraint relaxing the nonconvex constraint.*/ + int cRelaxIdx;}; + /** Structure which describes a constraints of the form + $f[ y \gt F(x) \f] + with \f$ F(x) \f$ a concave function.*/ + struct SimpleConcaveConstraint{ + /** Default constructor gives "safe" values.*/ + SimpleConcaveConstraint(): + xIdx(-1), yIdx(-1), cIdx(-1){} + /** Index of the variable x.*/ + int xIdx; + /** Index of the variable y.*/ + int yIdx; + /** Index of the constraint.*/ + int cIdx;}; + /** Get accest to constraint convexities.*/ + virtual bool get_constraint_convexities(int m, TMINLP::Convexity * constraints_convexities)const { + CoinFillN(constraints_convexities, m, TMINLP::Convex); + return true;} + /** Get dimension information on nonconvex constraints.*/ + virtual bool get_number_nonconvex(int & number_non_conv, int & number_concave) const{ + number_non_conv = 0; + number_concave = 0; + return true;} + /** Get array describing the constraints marked nonconvex in the model.*/ + virtual bool get_constraint_convexities(int number_non_conv, MarkedNonConvex * non_convs) const{ + assert(number_non_conv == 0); + return true;} + /** Fill array containing indices of simple concave constraints.*/ + virtual bool get_simple_concave_constraints(int number_concave, SimpleConcaveConstraint * simple_concave) const{ + assert(number_concave == 0); + return true;} + + /** Say if problem has a linear objective (for OA) */ + virtual bool hasLinearObjective(){return false;} + + /** Say if problem has general integer variables.*/ + bool hasGeneralInteger(); + + /** Access array describing constraint to which perspectives should be applied.*/ + virtual const int * get_const_xtra_id() const{ + return NULL; + } + protected: + /** Copy constructor */ + //@{ + /** Copy Constructor */ + TMINLP(const TMINLP&); + + /** Overloaded Equals Operator */ + void operator=(const TMINLP&); + //@} + + private: + }; + +} // namespace Ipopt + +#endif + diff --git a/thirdparty/linux/include/coin/BonTMINLP2OsiLP.hpp b/thirdparty/linux/include/coin/BonTMINLP2OsiLP.hpp new file mode 100644 index 0000000..09fb186 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMINLP2OsiLP.hpp @@ -0,0 +1,164 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/16/2007 +#ifndef BonminTMINLP2OsiLP_H +#define BonminTMINLP2OsiLP_H + +#include <cmath> +#include <cstdio> +#include "IpSmartPtr.hpp" +#include "IpTNLP.hpp" +#include "BonTypes.hpp" + +class OsiSolverInterface; +class OsiCuts; + +namespace Bonmin { + class TMINLP2TNLP; + class BabSetupBase; + + /** A transformer class to build outer approximations i.e. transfomrs nonlinear programs into linear programs.*/ + class TMINLP2OsiLP: public Ipopt::ReferencedObject { + + public: + + /** Default constructor.*/ + TMINLP2OsiLP(): + tiny_(-0.), + very_tiny_(-0.) + {} + + /** Copy constructor.*/ + TMINLP2OsiLP(const TMINLP2OsiLP & other): + tiny_(other.tiny_), + very_tiny_(other.very_tiny_), + model_(other.model_){ + } + + /** virtual copy constructor*/ + virtual TMINLP2OsiLP * clone() const = 0; + + void set_tols(double tiny, double very_tiny, double rhs_relax, double infty){ + tiny_ = tiny; + very_tiny_ = very_tiny; + rhs_relax_ = rhs_relax; + infty_ = infty; + } + + void set_model(Bonmin::TMINLP2TNLP * model){ + model_ = model; + initialize_jac_storage(); + } + + /** Assignment operator.*/ + TMINLP2OsiLP & operator=(const TMINLP2OsiLP& rhs){ + if(this != & rhs){ + tiny_ = rhs.tiny_; + very_tiny_ = rhs.very_tiny_; + model_ = rhs.model_; + } + return (*this); + } + + /** Destructor.*/ + ~TMINLP2OsiLP(){} + + /** Build the Outer approximation of model_ in x and put it in si.*/ + virtual void extract(OsiSolverInterface *si, + const double * x, bool getObj) = 0; + + +/** Get OAs of nonlinear constraints in x.*/ + virtual void get_refined_oa(OsiCuts & cs + ) const = 0; + +/** Get OAs of nonlinear constraints in x.*/ + virtual void get_oas(OsiCuts & cs, + const double * x, bool getObj, bool global) const = 0; + + + + protected: + /** Facilitator to clean up coefficient.*/ + inline bool cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) const; + /** If constraint coefficient is below this, we try to remove it.*/ + double tiny_; + /** If constraint coefficient is below this, we neglect it.*/ + double very_tiny_; + /** Amount by which to relax OA constraints RHSes*/ + double rhs_relax_; + /** infinity.*/ + double infty_; + /** Count the number of linear outer approximations taken.*/ + static int nTimesCalled; + + /** Cache Jacobian matrix*/ + /** Columns of jacobian.*/ + mutable vector<int> jCol_; + /** Rows of jacobian.*/ + mutable vector<int> iRow_; + /** Values of jacobian.*/ + mutable vector<double> value_; + + vector<Ipopt::TNLP::LinearityType> const_types_; + + void initialize_jac_storage(); + + Ipopt::SmartPtr<Bonmin::TMINLP2TNLP> model_; + }; + +//A procedure to try to remove small coefficients in OA cuts (or make it non small +inline +bool +TMINLP2OsiLP::cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) const +{ + if(fabs(value)>= tiny) return 1; + //fprintf(stderr, "Warning: small coefficient %g\n", tiny); + + if(fabs(value)<veryTiny) return 0;//Take the risk? + + //try and remove + double infty = 1e20; + bool colUpBounded = colUpper < 10000; + bool colLoBounded = colLower > -10000; + bool rowNotLoBounded = rowLower <= - infty; + bool rowNotUpBounded = rowUpper >= infty; + bool pos = value > 0; + + if(colLoBounded && !pos && rowNotUpBounded) { + lb += value * (colsol - colLower); + return 0; + } + else + if(colLoBounded && pos && rowNotLoBounded) { + ub += value * (colsol - colLower); + return 0; + } + else + if(colUpBounded && pos && rowNotUpBounded) { + lb += value * (colsol - colUpper); + return 0; + } + else + if(colUpBounded && !pos && rowNotLoBounded) { + ub += value * (colsol - colUpper); + return 0; + } + //can not remove coefficient + return 1; +} + + +} + +#endif + diff --git a/thirdparty/linux/include/coin/BonTMINLP2Quad.hpp b/thirdparty/linux/include/coin/BonTMINLP2Quad.hpp new file mode 100644 index 0000000..4d7f0c6 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMINLP2Quad.hpp @@ -0,0 +1,191 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef __TMINLPQuad_HPP__ +#define __TMINLPQuad_HPP__ + +#include "BonTMINLP2TNLP.hpp" +#include "BonQuadRow.hpp" + +namespace Bonmin +{ + + + /** This is a derived class fro TMINLP2TNLP to handle adding quadratic cuts. + */ + class TMINLP2TNLPQuadCuts : public Bonmin::TMINLP2TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + TMINLP2TNLPQuadCuts(const Ipopt::SmartPtr<Bonmin::TMINLP> tminlp +#ifdef WARM_STARTER + , + const OptionsList& options +#endif + ); + + + /** Copy Constructor + * \warning source and copy point to the same tminlp_. + */ + TMINLP2TNLPQuadCuts(const TMINLP2TNLPQuadCuts&); + + /** Virtual copy.*/ + virtual Bonmin::TMINLP2TNLP * clone() const{ + printf("Cloning TMINLP2TNLPQuadCuts.\n"); + return new TMINLP2TNLPQuadCuts(*this);} + + /** Destructor */ + virtual ~TMINLP2TNLPQuadCuts(); + //@} + /**@name methods to gather information about the NLP */ + //@{ + /** This call is just passed onto parent class and add number of quadratic + cuts*/ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, + Ipopt::TNLP::IndexStyleEnum& index_style); + + /** This call is just passed onto parent class and add bounds of quadratic + cuts*/ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType* const_types); + + /** This call is just passed onto parent class and add + lambda for quadratic cuts*/ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method that returns scaling parameters (passed to parent all quadratic + not scaled). + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x (appends constraint values for quadratics).*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + /** compute the value of a single constraint */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** compute the structure or values of the gradient for one + constraint */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + + /** \name Cuts management. */ + //@{ + + + /** Add some linear or quadratic cuts to the problem formulation + if some of the OsiRowCuts are quadratic they will be well understood as long as safe is true.*/ + void addCuts(const Cuts& cuts, bool safe); + + + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + void addCuts(const OsiCuts &cuts); + + /** Add some linear cuts to the problem formulation.*/ + virtual void addCuts(unsigned int numberCuts, const OsiRowCut ** cuts); + + + /** Remove some cuts from the formulation */ + void removeCuts(unsigned int number ,const int * toRemove); + + //@} + // + /** Change objective to a linear one whith given objective function.*/ + void set_linear_objective(int n_var, const double * obj, double c_0); + + /** Reset objective to original one */ + void reset_objective(){ + obj_.clear(); + } + + protected: + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + void addRowCuts(const OsiCuts &cuts, bool safe); + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TMINLP2TNLPQuadCuts(); + + /** Overloaded Equals Operator */ + TMINLP2TNLPQuadCuts& operator=(const TMINLP2TNLP&); + //@} + + private: + /** Some storage for quadratic cuts.*/ + vector<QuadRow *> quadRows_; + + /** Storage for the original hessian of the problem.*/ + AdjustableMat H_; + + /** print H_ for debug.*/ + void printH(); + /** Current umber of entries in the jacobian.*/ + int curr_nnz_jac_; + + /** Store user passed linear objective.*/ + vector<double> obj_; + /** constant term in objective function.*/ + double c_; + }; + +} // namespace Ipopt + +#endif + diff --git a/thirdparty/linux/include/coin/BonTMINLP2TNLP.hpp b/thirdparty/linux/include/coin/BonTMINLP2TNLP.hpp new file mode 100644 index 0000000..7523fc1 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMINLP2TNLP.hpp @@ -0,0 +1,509 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2004, 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + +#ifndef __TMINLP2TNLP_HPP__ +#define __TMINLP2TNLP_HPP__ + +#include "IpTNLP.hpp" +#include "BonTMINLP.hpp" +#include "IpSmartPtr.hpp" +#include "IpIpoptApplication.hpp" +#include "IpOptionsList.hpp" +#include "BonTypes.hpp" + +namespace Bonmin +{ + class IpoptInteriorWarmStarter; + + /** This is an adapter class that converts a TMINLP to + * a TNLP to be solved by Ipopt. It allows an external + * caller to modify the bounds of variables, allowing + * the treatment of binary and integer variables as + * relaxed, or fixed + */ + class TMINLP2TNLP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + TMINLP2TNLP(const Ipopt::SmartPtr<TMINLP> tminlp +#ifdef WARM_STARTER + , + const OptionsList& options +#endif + ); + + /** Copy Constructor + * \warning source and copy point to the same tminlp_. + */ + TMINLP2TNLP(const TMINLP2TNLP&); + + /** virtual copy .*/ + virtual TMINLP2TNLP * clone() const{ + return new TMINLP2TNLP(*this);} + + /** Default destructor */ + virtual ~TMINLP2TNLP(); + //@} + + /**@name Methods to modify the MINLP and form the NLP */ + //@{ + + /** Get the number of variables */ + inline Ipopt::Index num_variables() const + { + assert(x_l_.size() == x_u_.size()); + return static_cast<int>(x_l_.size()); + } + + /** Get the number of constraints */ + inline Ipopt::Index num_constraints() const + { + assert(g_l_.size() == g_u_.size()); + return static_cast<int>(g_l_.size()); + } + /** Get the nomber of nz in hessian */ + Ipopt::Index nnz_h_lag() + { + return nnz_h_lag_; + } + /** Get the variable types */ + const TMINLP::VariableType* var_types() + { + return &var_types_[0]; + } + + /** Get the current values for the lower bounds */ + const Ipopt::Number* x_l() + { + return &x_l_[0]; + } + /** Get the current values for the upper bounds */ + const Ipopt::Number* x_u() + { + return &x_u_[0]; + } + + /** Get the original values for the lower bounds */ + const Ipopt::Number* orig_x_l() const + { + return &orig_x_l_[0]; + } + /** Get the original values for the upper bounds */ + const Ipopt::Number* orig_x_u() const + { + return orig_x_u_(); + } + + /** Get the current values for constraints lower bounds */ + const Ipopt::Number* g_l() + { + return g_l_(); + } + /** Get the current values for constraints upper bounds */ + const Ipopt::Number* g_u() + { + return g_u_(); + } + + /** get the starting primal point */ + const Ipopt::Number * x_init() const + { + return x_init_(); + } + + /** get the user provided starting primal point */ + const Ipopt::Number * x_init_user() const + { + return x_init_user_(); + } + + /** get the starting dual point */ + const Ipopt::Number * duals_init() const + { + return duals_init_; + } + + /** get the solution values */ + const Ipopt::Number* x_sol() const + { + return x_sol_(); + } + + /** get the g solution (activities) */ + const Ipopt::Number* g_sol() const + { + return g_sol_(); + } + + /** get the dual values */ + const Ipopt::Number* duals_sol() const + { + return duals_sol_(); + } + + /** Get Optimization status */ + Ipopt::SolverReturn optimization_status() const + { + return return_status_; + } + + /** Get the objective value */ + Ipopt::Number obj_value() const + { + return obj_value_; + } + + /** Manually set objective value. */ + void set_obj_value(Ipopt::Number value) + { + obj_value_ = value; + } + + /** force solution to be fractionnal.*/ + void force_fractionnal_sol(); + + /** Change the bounds on the variables */ + void SetVariablesBounds(Ipopt::Index n, + const Ipopt::Number * x_l, + const Ipopt::Number * x_u); + + /** Change the lower bound on the variables */ + void SetVariablesLowerBounds(Ipopt::Index n, + const Ipopt::Number * x_l); + + /** Change the upper bound on the variable */ + void SetVariablesUpperBounds(Ipopt::Index n, + const Ipopt::Number * x_u); + + /** Change the bounds on the variable */ + void SetVariableBounds(Ipopt::Index var_no, Ipopt::Number x_l, Ipopt::Number x_u); + + /** Change the lower bound on the variable */ + void SetVariableLowerBound(Ipopt::Index var_no, Ipopt::Number x_l); + + /** Change the upper bound on the variable */ + void SetVariableUpperBound(Ipopt::Index var_no, Ipopt::Number x_u); + + /** reset the starting point to original one. */ + void resetStartingPoint(); + + /** set the starting point to x_init */ + void setxInit(Ipopt::Index n,const Ipopt::Number* x_init); + + /** set the dual starting point to duals_init */ + void setDualsInit(Ipopt::Index n, const Ipopt::Number* duals_init); + + /** xInit has been set? + * \return 0 if not, 1 if only primal 2 if primal dual.*/ + int has_x_init(){ + if(x_init_.empty()) return 0; + if(duals_init_) return 2; + return 1; + } + /** Set the contiuous solution */ + void Set_x_sol(Ipopt::Index n, const Ipopt::Number* x_sol); + + /** Set the contiuous dual solution */ + void Set_dual_sol(Ipopt::Index n, const Ipopt::Number* dual_sol); + + /** Change the type of the variable */ + void SetVariableType(Ipopt::Index n, TMINLP::VariableType type); + //@} + /** Procedure to ouptut relevant informations to reproduce a sub-problem. + Compare the current problem to the problem to solve + and writes files with bounds which have changed and current starting point. + */ + void outputDiffs(const std::string& probName, const std::string* varNames); + + /**@name methods to gather information about the NLP */ + //@{ + /** This call is just passed onto the TMINLP object */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, + TNLP::IndexStyleEnum& index_style); + + /** The caller is allowed to modify the bounds, so this + * method returns the internal bounds information + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Returns the constraint linearity. + * array should be alocated with length at least m..*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types) + { + return tminlp_->get_constraints_linearity(m, const_types); + } + + /** Returns the variables linearity. + * array should be alocated with length at least n..*/ + virtual bool get_variables_linearity(Ipopt::Index n, LinearityType* var_types) + { + return tminlp_->get_variables_linearity(n, var_types); + } + + /** returns true if objective is linear.*/ + virtual bool hasLinearObjective(){return tminlp_->hasLinearObjective();} + /** Method called by Ipopt to get the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method that returns scaling parameters. + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Methat that returns an Ipopt IteratesVector that has the + * starting point for all internal varibles. */ + virtual bool get_warm_start_iterate(Ipopt::IteratesVector& warm_start_iterate); + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** compute the value of a single constraint */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** compute the structure or values of the gradient for one + constraint */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + /** Intermediate Callback method for the user. Providing dummy + * default implementation. For details see IntermediateCallBack + * in IpNLP.hpp. */ + virtual bool intermediate_callback(Ipopt::AlgorithmMode mode, + Ipopt::Index iter, Ipopt::Number obj_value, + Ipopt::Number inf_pr, Ipopt::Number inf_du, + Ipopt::Number mu, Ipopt::Number d_norm, + Ipopt::Number regularization_size, + Ipopt::Number alpha_du, Ipopt::Number alpha_pr, + Ipopt::Index ls_trials, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method called to check wether a problem has still some variable not fixed. If there are no more + unfixed vars, checks wether the solution given by the bounds is feasible.*/ + + /** @name Methods for setting and getting the warm starter */ + //@{ + void SetWarmStarter(Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter); + + Ipopt::SmartPtr<IpoptInteriorWarmStarter> GetWarmStarter(); + + //@} + + /** Say if has a specific function to compute upper bounds*/ + virtual bool hasUpperBoundingObjective(){ + return tminlp_->hasUpperBoundingObjective();} + + /** Evaluate the upper bounding function at given point and store the result.*/ + double evaluateUpperBoundingFunction(const double * x); + + /** \name Cuts management. */ + /** Methods are not implemented at this point. But I need the interface.*/ + //@{ + + + /** Add some linear cuts to the problem formulation (not implemented yet in base class).*/ + virtual void addCuts(unsigned int numberCuts, const OsiRowCut ** cuts){ + if(numberCuts > 0) + throw CoinError("BonTMINLP2TNLP", "addCuts", "Not implemented");} + + + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + virtual void addCuts(const OsiCuts &cuts){ + if(cuts.sizeRowCuts() > 0 || cuts.sizeColCuts() > 0) + throw CoinError("BonTMINLP2TNLP", "addCuts", "Not implemented");} + + /** Remove some cuts to the formulation */ + virtual void removeCuts(unsigned int number ,const int * toRemove){ + if(number > 0) + throw CoinError("BonTMINLP2TNLP", "removeCuts", "Not implemented");} + + //@} + + + /** Access array describing constraint to which perspectives should be applied.*/ + virtual const int * get_const_xtra_id() const{ + return tminlp_->get_const_xtra_id(); + } + + /** Round and check the current solution, return norm inf of constraint violation.*/ + double check_solution(OsiObject ** objects = 0, int nObjects = -1); + protected: + /** \name These should be modified in derived class to always maintain there correctness. + They are directly queried by OsiTMINLPInterface without virtual function for + speed.*/ + /** @{ */ + /// Types of the variable (TMINLP::CONTINUOUS, TMINLP::INTEGER, TMINLP::BINARY). + vector<TMINLP::VariableType> var_types_; + /// Current lower bounds on variables + vector<Ipopt::Number> x_l_; + /// Current upper bounds on variables + vector<Ipopt::Number> x_u_; + /// Original lower bounds on variables + vector<Ipopt::Number> orig_x_l_; + /// Original upper bounds on variables + vector<Ipopt::Number> orig_x_u_; + /// Lower bounds on constraints values + vector<Ipopt::Number> g_l_; + /// Upper bounds on constraints values + vector<Ipopt::Number> g_u_; + /// Initial primal point + vector<Ipopt::Number> x_init_; + /** Initial values for all dual multipliers (constraints then lower bounds then upper bounds) */ + Ipopt::Number * duals_init_; + /// User-provideed initial prmal point + vector<Ipopt::Number> x_init_user_; + /// Optimal solution + vector<Ipopt::Number> x_sol_; + /// Activities of constraint g( x_sol_) + vector<Ipopt::Number> g_sol_; + /** Dual multipliers of constraints and bounds*/ + vector<Ipopt::Number> duals_sol_; + /** @} */ + + /** Access number of entries in tminlp_ hessian*/ + Ipopt::Index nnz_h_lag() const{ + return nnz_h_lag_;} + /** Access number of entries in tminlp_ hessian*/ + Ipopt::Index nnz_jac_g() const{ + return nnz_jac_g_;} + + /** Acces index_style.*/ + TNLP::IndexStyleEnum index_style() const{ + return index_style_;} + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TMINLP2TNLP(); + + /** Overloaded Equals Operator */ + TMINLP2TNLP& operator=(const TMINLP2TNLP&); + //@} + + /** pointer to the tminlp that is being adapted */ + Ipopt::SmartPtr<TMINLP> tminlp_; + + /** @name Internal copies of data allowing caller to modify the MINLP */ + //@{ + /// Number of non-zeroes in the constraints jacobian. + Ipopt::Index nnz_jac_g_; + /// Number of non-zeroes in the lagrangian hessian + Ipopt::Index nnz_h_lag_; + /**index style (fortran or C)*/ + TNLP::IndexStyleEnum index_style_; + + /** Return status of the optimization process*/ + Ipopt::SolverReturn return_status_; + /** Value of the optimal solution found by Ipopt */ + Ipopt::Number obj_value_; + //@} + + /** @name Warmstart object and related data */ + //@{ + /** Pointer to object that holds warmstart information */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> curr_warm_starter_; + /** Value for a lower bound that denotes -infinity */ + Ipopt::Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Ipopt::Number nlp_upper_bound_inf_; + /** Option from Ipopt - we currently use it to see if we want to + * use some clever warm start or just the last iterate from the + * previous run */ + bool warm_start_entire_iterate_; + /** Do we need a new warm starter object */ + bool need_new_warm_starter_; + //@} + + + /** Private method that throws an exception if the variable bounds + * are not consistent with the variable type */ + void throw_exception_on_bad_variable_bound(Ipopt::Index i); + + private: + // Delete all arrays + void gutsOfDelete(); + + /** Copies all the arrays. + \warning this and other should be two instances of the same problem + \warning AW: I am trying to mimic a copy construction for Cbc + use with great care not safe. + */ + void gutsOfCopy(const TMINLP2TNLP &source); + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/BonTMINLPLinObj.hpp b/thirdparty/linux/include/coin/BonTMINLPLinObj.hpp new file mode 100644 index 0000000..819bc57 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMINLPLinObj.hpp @@ -0,0 +1,216 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 08/16/2007 + + +#ifndef TMINLPLinObj_H +#define TMINLPLinObj_H + +#include "BonTMINLP.hpp" + +namespace Bonmin { +/** From a TMINLP, this class adapts to another TMINLP where the original objective is transformed into a constraint + by adding an extra variable which is minimized. + + More precisely + \f[ + \begin{array}{l} + \min f(x)\\ + s.t\\ + g_l \leq g(x) \leq g_u\\ + x_l \leq x \leq u + \end{array} + \f] + is transformed ino + \begin{array}{l} + \min \eta\\ + s.t\\ + -\infty \leq f(x) - \eta \leq 0\\ + g_l \leq g(x) \leq g_u\\ + x_l \leq x \leq u + \end{array} + \f] + The objective is put as first constraint of the problem and the extra variable is the last one. + .*/ +class TMINLPLinObj: public Bonmin::TMINLP { + public: + /** Default constructor*/ + TMINLPLinObj(); + + /** destructor.*/ + virtual ~TMINLPLinObj(); + + /** set reference TMINLP */ + void setTminlp(Ipopt::SmartPtr<TMINLP> tminlp); + + /**@name methods to gather information about the MINLP */ + //@{ + /** Return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. Call tminlp_ one but number of constraints and non-zeroes in the jacobian is stored internally.*/ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + /** Return scaling parameters. If tminlp_ method returns true, translate + * constraint scaling (if asked). + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Get the variable type. Just call tminlp_'s method;. */ + virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types){ + assert(IsValid(tminlp_)); + assert(n == n_); + var_types[n-1] = TMINLP::CONTINUOUS; + return tminlp_->get_variables_types(n - 1, var_types); + } + + /** Return the constraints linearity. Call tminlp_'s method and translate. + */ + virtual bool get_constraints_linearity(Ipopt::Index m, + Ipopt::TNLP::LinearityType* const_types); + + /** Return the information about the bound + * on the variables and constraints. Call tminlp_'s method and translate + * constraints bounds.*/ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Return the starting point. + Have to translate z_L and z_U. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Return the value of the objective function. + * Just call tminlp_ method. */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value){ + assert(n == n_); + obj_value = x[n-1]; + return true;} + + /** Return the vector of the gradient of + * the objective w.r.t. x. Just call tminlp_ method. */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f){ + assert(IsValid(tminlp_)); + assert(n == n_); + n--; + for(int i = 0 ; i < n ; i++){ + grad_f[i] = 0;} + grad_f[n] = 1; + return true;} + + /** Return the vector of constraint values. + * Use tminlp_ functions and use mapping to get the needed values. */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Return the jacobian of the constraints. + * In first call nothing to change. In later just fix the values for the simple concaves + * and remove entries corresponding to nonConvex constraints. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** \brief Return the hessian of the lagrangian. + * Here we just put lambda in the correct format and call + * tminlp_'s function.*/ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + /** Compute the value of a single constraint. The constraint + * number is i (starting counting from 0. */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** Compute the structure or values of the gradient for one + * constraint. The constraint * number is i (starting counting + * from 0. Other things are like with eval_jac_g. */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + //@} + + virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType* c){ + assert(IsValid(tminlp_)); + assert(n == n_); + bool r_val = tminlp_->get_variables_linearity(n-1, c); + c[n - 1] = Ipopt::TNLP::LINEAR; + return r_val; + } + + + /** @name Solution Methods */ + //@{ + /** Use tminlp_ function.*/ + virtual void finalize_solution(TMINLP::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value){ + return tminlp_->finalize_solution(status, n - 1, x, + obj_value); + } + //@} + + /** Use tminlp_ function.*/ + virtual const BranchingInfo * branchingInfo() const{ + return tminlp_->branchingInfo(); + } + + /** Use tminlp_ function. + \bug Has to translate sos information.*/ + virtual const SosInfo * sosConstraints() const{ + return tminlp_->sosConstraints(); + } + /** Use tminlp_ function.*/ + virtual const PerturbInfo* perturbInfo() const + { + return tminlp_->perturbInfo(); + } + + /** Use tminlp_ function.*/ + virtual bool hasUpperBoundingObjective(){ + assert(IsValid(tminlp_)); + return tminlp_->hasUpperBoundingObjective();} + + /** Use tminlp_ function.*/ + virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x, + Ipopt::Number& obj_value){ + assert(IsValid(tminlp_)); + return tminlp_->eval_upper_bound_f(n - 1, x, obj_value); } + + /** Say if problem has a linear objective (for OA) */ + virtual bool hasLinearObjective(){return true;} + /** return pointer to tminlp_.*/ + Ipopt::SmartPtr<TMINLP> tminlp(){return tminlp_;} + private: + /** Reset all data.*/ + void gutsOfDestructor(); + + /** Reference TMINLP which is to be relaxed.*/ + Ipopt::SmartPtr<TMINLP> tminlp_; + /** Ipopt::Number of constraints in the transformed MINLP.*/ + int m_; + /** Ipopt::Number of variables in the transformed MINLP.*/ + int n_; + /** number of non-zeroes in the jacobian of the transformed MINLP.*/ + int nnz_jac_; + /** offset for jacobian.*/ + int offset_; + +}; + + +}/* Ends Bonmin namepsace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/BonTMatrix.hpp b/thirdparty/linux/include/coin/BonTMatrix.hpp new file mode 100644 index 0000000..2aa6316 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTMatrix.hpp @@ -0,0 +1,167 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonTMatrix_H +#define BonTMatrix_H + +#include "CoinPackedMatrix.hpp" +#include "BonArraysHelpers.hpp" +#include <vector> +#include <list> +#include <algorithm> +#include "BonQuadCut.hpp" + +namespace Bonmin { + +struct TMat{ + int * iRow_; + int * jCol_; + double * value_; + int nnz_; + int capacity_; + + + /** Storage for non empty rows. + first is row number and second is first element in row.*/ + typedef vector< std::pair< int, int> > RowS; + + /** Default constructor.*/ + TMat(): iRow_(NULL), jCol_(NULL), value_(NULL), nnz_(0), + capacity_(0) + {} + + + void freeSpace(){ + delete [] iRow_; + delete [] jCol_; + delete [] value_; + } + + /** Copy constructor.*/ + TMat(const TMat &other); + + /** Construct from a CoinPackedMatrix*/ + TMat(const CoinPackedMatrix &M, MatrixStorageType T); + + /** Assignment operator.*/ + TMat& operator=(const TMat &rhs); + + /** Assignment from a CoinPackedMatrix.*/ + TMat & operator=(const CoinPackedMatrix &M); + + void resize(int nnz){ + Bonmin::resizeAndCopyArray(iRow_, nnz_, nnz); + Bonmin::resizeAndCopyArray(jCol_, nnz_, nnz); + Bonmin::resizeAndCopyArray(value_, nnz_, nnz); + nnz_ = nnz; + } + + ~TMat(); + + /** Get number of non empty rows.*/ + int numNonEmptyRows(); + + /** Get the list of non empty row.*/ + const RowS & nonEmptyRows() const { + return nonEmptyRows_;} + + /** Get number of non empty cols.*/ + int numNonEmptyCols(); + + /** Get the list of non empty row.*/ + const RowS & nonEmptyCols() const { + return nonEmptyCols_;} + + private: + /** Structure for ordering matrix.*/ + struct TMatOrdering{ + TMat * M_; + TMatOrdering(TMat *M): + M_(M){} + }; + + /** Structure for ordering matrix by columns.*/ + struct ColumnOrder : public TMatOrdering { + ColumnOrder(TMat *M): + TMatOrdering(M){} + + bool operator()(const int& i, const int& j){ + if (M_->jCol_[i] < M_->jCol_[j]) + return true; + if (M_->jCol_[i] == M_->jCol_[j] && M_->iRow_[i] < M_->iRow_[j]) + return true; + return false; + } + }; + + + /** Structure for ordering matrix by columns.*/ + struct RowOrder : public TMatOrdering { + RowOrder(TMat *M): + TMatOrdering(M){} + bool operator()(const int& i, const int& j){ + if (M_->iRow_[i]< M_->iRow_[j]) + return true; + if (M_->iRow_[i] == M_->iRow_[j] && M_->jCol_[i] < M_->jCol_[j]) + return true; + return false; + } + }; + public: + /** Orders current matrix by columns. */ + const vector<int>& orderByColumns(){ + resizeOrdering(columnOrdering_, nnz_); + std::sort(columnOrdering_.begin(), columnOrdering_.end(),ColumnOrder(this)); + return columnOrdering_; + } + /** Orders current matrix by rows.*/ + const vector<int>& orderByRows(){ + resizeOrdering(rowOrdering_, nnz_); + std::sort(rowOrdering_.begin(), rowOrdering_.end(), RowOrder(this)); + return rowOrdering_; + } + + /** Remove the duplicated entries.*/ + void removeDuplicates(); + + /** Assuming that this is representing a quadratic form. Produce equivalent + quadratic form with only upper triange stored.*/ + void makeQuadUpperDiag(); + + void resizeOrdering(vector<int> &ordering, unsigned int newSize){ + size_t oldSize = ordering.size(); + ordering.resize(newSize); + for(size_t i = oldSize ; i < newSize ; i++) + ordering[i] = static_cast<int>(i); + } + + /** Create the TMat from M.*/ + void create(const CoinPackedMatrix &M); + + vector<int> columnOrdering_; + + vector<int> rowOrdering_; + + void make_upper_triangular(const MatrixStorageType &T); + + void make_lower_to_be_upper(); + + void make_full_upper_triangular(); + + // Stores non empty rows for computing jacobian structure + RowS nonEmptyRows_; + + // Stores non empty cols for computing jacobian structure + RowS nonEmptyCols_; + }; + +}//Ends Bonmin namespace + +#endif + diff --git a/thirdparty/linux/include/coin/BonTNLP2FPNLP.hpp b/thirdparty/linux/include/coin/BonTNLP2FPNLP.hpp new file mode 100644 index 0000000..82137c9 --- /dev/null +++ b/thirdparty/linux/include/coin/BonTNLP2FPNLP.hpp @@ -0,0 +1,264 @@ +// Copyright (C) 2004, International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// +// Authors: Pierre Bonami 06/10/2005 + +#ifndef _TNLP2FPNLP_HPP_ +#define _TNLP2FPNLP_HPP_ + +#include "IpTNLP.hpp" +#include "BonTMINLP.hpp" +#include "IpSmartPtr.hpp" +#include "BonTypes.hpp" + +namespace Bonmin +{ + /** This is an adapter class to convert an NLP to a Feasibility Pump NLP + * by changing the objective function to the (2-norm) distance to a point. + * The extra function is set_dist_to_point_obj(size_t n, const double *, const int *) + */ + class TNLP2FPNLP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Build using tnlp as source problem.*/ + TNLP2FPNLP(const Ipopt::SmartPtr<Ipopt::TNLP> tnlp, double objectiveScalingFactor = 100); + + /** Build using tnlp as source problem and using other for all other parameters..*/ + TNLP2FPNLP(const Ipopt::SmartPtr<TNLP> tnlp, const Ipopt::SmartPtr<TNLP2FPNLP> other); + + /** Default destructor */ + virtual ~TNLP2FPNLP(); + //@} + void use(Ipopt::SmartPtr<TNLP> tnlp){ + tnlp_ = GetRawPtr(tnlp);} + /**@name Methods to select the objective function and extra constraints*/ + //@{ + /// Flag to indicate that we want to use the feasibility pump objective + void set_use_feasibility_pump_objective(bool use_feasibility_pump_objective) + { use_feasibility_pump_objective_ = use_feasibility_pump_objective; } + + /** Flag to indicate that we want to use a cutoff constraint + * This constraint has the form f(x) <= (1-epsilon) f(x') */ + void set_use_cutoff_constraint(bool use_cutoff_constraint) + { use_cutoff_constraint_ = use_cutoff_constraint; } + + /// Flag to indicate that we want to use a local branching constraint + void set_use_local_branching_constraint(bool use_local_branching_constraint) + { use_local_branching_constraint_ = use_local_branching_constraint; } + //@} + + /**@name Methods to provide the rhs of the extra constraints*/ + //@{ + /// Set the cutoff value to use in the cutoff constraint + void set_cutoff(Ipopt::Number cutoff); + + /// Set the rhs of the local branching constraint + void set_rhs_local_branching_constraint(double rhs_local_branching_constraint) + { assert(rhs_local_branching_constraint >= 0); + rhs_local_branching_constraint_ = rhs_local_branching_constraint; } + //@} + + /**@name Methods to change the objective function*/ + //@{ + /** \brief Set the point to which distance is minimized. + * The distance is minimize in a subspace define by a subset of coordinates + * \param n number of coordinates on which distance is minimized + * \param inds indices of the coordinates on which distance is minimized + * \param vals values of the point for coordinates in ind + */ + void set_dist_to_point_obj(size_t n, const Ipopt::Number * vals, const Ipopt::Index * inds); + + /** Set the value for sigma */ + void setSigma(double sigma){ + assert(sigma >= 0.); + sigma_ = sigma;} + /** Set the value for lambda*/ + void setLambda(double lambda){ + assert(lambda >= 0. && lambda <= 1.); + lambda_ = lambda;} + /** Set the value for simgma */ + void setNorm(int norm){ + assert(norm >0 && norm < 3); + norm_ = norm;} + //@} + + /**@name methods to gather information about the NLP */ + //@{ + /** get info from nlp_ and add hessian information */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + + /** This call is just passed onto tnlp_ + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Passed onto tnlp_ + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda) + { + int m2 = m; + if(use_cutoff_constraint_) { + m2--; + if(lambda!=NULL)lambda[m2] = 0; + } + if(use_local_branching_constraint_) { + m2--; + if(lambda!= NULL)lambda[m2] = 0; + } + int ret_code = tnlp_->get_starting_point(n, init_x, x, + init_z, z_L, z_U, m2, init_lambda, lambda); + return ret_code; + } + + /** overloaded to return the value of the objective function */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** overload to return the values of the left-hand side of the + constraints */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** overload to return the jacobian of g */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** Evaluate the modified Hessian of the Lagrangian*/ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + virtual bool get_variables_linearity(Ipopt::Index n, LinearityType* var_types) + { + return tnlp_->get_variables_linearity(n, var_types);; + } + + /** overload this method to return the constraint linearity. + * array should be alocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types) + { + int m2 = m; + if(use_cutoff_constraint_) { + m2--; + const_types[m2] = Ipopt::TNLP::NON_LINEAR; + } + if(use_local_branching_constraint_) { + m2--; + const_types[m2] = Ipopt::TNLP::LINEAR; + } + return tnlp_->get_constraints_linearity(m2, const_types); + } + /** @name Scaling of the objective function */ + //@{ + void setObjectiveScaling(double value) + { + objectiveScalingFactor_ = value; + } + double getObjectiveScaling() const + { + return objectiveScalingFactor_; + } + + private: + /** @name Internal methods to help compute the distance, its gradient and hessian */ + //@{ + /** Compute the norm-2 distance to the current point to which distance is minimized. */ + double dist_to_point(const Ipopt::Number *x); + //@} + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TNLP2FPNLP(); + + /** Copy Constructor */ + TNLP2FPNLP(const TNLP2FPNLP&); + + /** Overloaded Equals Operator */ + void operator=(const TNLP2FPNLP&); + //@} + + /** pointer to the tminlp that is being adapted */ + Ipopt::SmartPtr<TNLP> tnlp_; + + /** @name Data for storing the point the distance to which is minimized */ + //@{ + /// Indices of the variables for which distance is minimized (i.e. indices of integer variables in a feasibility pump setting) + vector<Ipopt::Index> inds_; + /// Values of the point to which we separate (if x is the point vals_[i] should be x[inds_[i]] ) + vector<Ipopt::Number> vals_; + /** value for the convex combination to take between original objective and distance function. + * ( take lambda_ * distance + (1-lambda) sigma f(x).*/ + double lambda_; + /** Scaling for the original objective.*/ + double sigma_; + /** Norm to use (L_1 or L_2).*/ + int norm_; + //@} + + /// Scaling factor for the objective + double objectiveScalingFactor_; + + /**@name Flags to select the objective function and extra constraints*/ + //@{ + /// Flag to indicate that we want to use the feasibility pump objective + bool use_feasibility_pump_objective_; + + /** Flag to indicate that we want to use a cutoff constraint + * This constraint has the form f(x) <= (1-epsilon) f(x') */ + bool use_cutoff_constraint_; + + /// Flag to indicate that we want to use a local branching constraint + bool use_local_branching_constraint_; + //@} + + /**@name Data for storing the rhs of the extra constraints*/ + //@{ + /// Value of best solution known + double cutoff_; + + /// RHS of local branching constraint + double rhs_local_branching_constraint_; + //@} + + /// Ipopt::Index style (C++ or Fortran) + Ipopt::TNLP::IndexStyleEnum index_style_; + + }; + +} // namespace Ipopt + +#endif /*_TNLP2FPNLP_HPP_*/ diff --git a/thirdparty/linux/include/coin/BonTNLPSolver.hpp b/thirdparty/linux/include/coin/BonTNLPSolver.hpp new file mode 100644 index 0000000..195fbad --- /dev/null +++ b/thirdparty/linux/include/coin/BonTNLPSolver.hpp @@ -0,0 +1,241 @@ +// (C) Copyright International Business Machines (IBM) 2006, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, IBM +// +// Date : 26/09/2006 + + +#ifndef TNLPSolver_H +#define TNLPSolver_H +#include "IpTNLP.hpp" +#include "BonTMINLP2TNLP.hpp" + +//Some declarations +#include "IpOptionsList.hpp" +#include "CoinWarmStart.hpp" +#include "BonRegisteredOptions.hpp" +#include "CoinTime.hpp" +namespace Bonmin { +/** This is a generic class for calling an NLP solver to solve a TNLP. + A TNLPSolver is able to solve and resolve a problem, it has some options (stored + with Ipopt OptionList structure and registeredOptions) it produces some statistics (in SolveStatisctics and sometimes some errorCodes. +*/ +class TNLPSolver: public Ipopt::ReferencedObject{ + public: + + enum ReturnStatus /** Standard return statuses for a solver*/{ + iterationLimit = -3/** Solver reached iteration limit. */, + timeLimit = 5/** Solver reached iteration limit. */, + doesNotConverge = -8/** Algorithm does not converge.*/, + computationError = -2/** Some error was made in the computations. */, + notEnoughFreedom = -1/** not enough degrees of freedom.*/, + illDefinedProblem = -4/** The solver finds that the problem is not well defined. */, + illegalOption =-5/** An option is not valid. */, + externalException =-6/** Some unrecovered exception occured in an external tool used by the solver. */, + exception =-7/** Some unrocevered exception */, + solvedOptimal = 1/** Problem solved to an optimal solution.*/, + solvedOptimalTol =2/** Problem solved to "acceptable level of tolerance. */, + provenInfeasible =3/** Infeasibility Proven. */, + unbounded = 4/** Problem is unbounded.*/, + numReturnCodes/**Fake member to know size*/ + }; + + + +//############################################################################# + + /** We will throw this error when a problem is not solved. + Eventually store the error code from solver*/ + class UnsolvedError + { + public: + /** Constructor */ + UnsolvedError(int errorNum = -10000, + Ipopt::SmartPtr<TMINLP2TNLP> model = NULL, + std::string name="") + : + errorNum_(errorNum), + model_(model), + name_(name) + {if(name_=="") +{ +#ifndef NDEBUG + std::cerr<<"FIXME"<<std::endl; +#endif +}} + /** Print error message.*/ + void printError(std::ostream & os); + /** Get the string corresponding to error.*/ + virtual const std::string& errorName() const = 0; + /** Return the name of the solver. */ + virtual const std::string& solverName() const = 0; + /** Return error number. */ + int errorNum() const{ + return errorNum_;} + /** destructor. */ + virtual ~UnsolvedError(){} + /** write files with differences between input model and + this one */ + void writeDiffFiles(const std::string prefix=std::string()) const; + private: + /** Error code (solver dependent). */ + int errorNum_; + + /** model_ on which error occured*/ + Ipopt::SmartPtr< TMINLP2TNLP > model_; + + /** name of the model on which error occured. */ + std::string name_; + } + ; + + virtual UnsolvedError * newUnsolvedError(int num, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name) = 0; + + + + /// default Constructor + TNLPSolver(); + + ///Constructor with options initialization +TNLPSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + + ///virtual copy constructor + virtual Ipopt::SmartPtr<TNLPSolver> clone() = 0; + + /// Virtual destructor + virtual ~TNLPSolver(); + + /** Initialize the TNLPSolver (read options from params_file) + */ + virtual bool Initialize(std::string params_file) = 0; + + /** Initialize the TNLPSolver (read options from istream is) + */ + virtual bool Initialize(std::istream& is) = 0; + + /** @name Solve methods */ + //@{ + /// Solves a problem expresses as a TNLP + virtual ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0; + + /// Resolves a problem expresses as a TNLP + virtual ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0; + + /// Set the warm start in the solver + virtual bool setWarmStart(const CoinWarmStart * warm, + Ipopt::SmartPtr<TMINLP2TNLP> tnlp) = 0; + +/// Get warm start used in last optimization + virtual CoinWarmStart * getUsedWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0; + + /// Get the warm start form the solver + virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0; + + virtual CoinWarmStart * getEmptyWarmStart() const = 0; + + /** Check that warm start object is valid.*/ + virtual bool warmStartIsValid(const CoinWarmStart * ws) const = 0; + + /// Enable the warm start options in the solver + virtual void enableWarmStart() = 0; + + /// Disable the warm start options in the solver + virtual void disableWarmStart() = 0; + //@} + + ///Get a pointer to a journalist + Ipopt::SmartPtr<Ipopt::Journalist> journalist(){ + return journalist_;} + + ///Get a pointer to RegisteredOptions (generally used to add new ones) + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions(){ + return roptions_;} + + /// Get the options (for getting their values). + Ipopt::SmartPtr<const Ipopt::OptionsList> options() const { + return ConstPtr(options_);} + + /// Get the options (for getting and setting their values). + Ipopt::SmartPtr<Ipopt::OptionsList> options() { + return options_;} + + /// Get the prefix + const char * prefix(){ + return prefix_.c_str(); + } + /// Register this solver options into passed roptions +static void RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){} + + /// Get the CpuTime of the last optimization. + virtual double CPUTime() = 0; + + /// Get the iteration count of the last optimization. + virtual int IterationCount() = 0; + + + /// turn off all output from the solver + virtual void setOutputToDefault() = 0 ; + /// turn on all output from the solver + virtual void forceSolverOutput(int log_level) = 0; + /// Get the solver name + virtual std::string & solverName() = 0; + + /** Say if an optimization status for a problem which failed is recoverable + (problem may be solvable).*/ + bool isRecoverable(ReturnStatus &r); + + /** Setup for a global time limit for solver.*/ + void setup_global_time_limit(double time_limit){ + time_limit_ = time_limit + 5; + start_time_ = CoinCpuTime(); + } + + /** Say if return status is an error.*/ + bool isError(ReturnStatus &r){ + return r < 0;} + /** Error code (solver specific).*/ +virtual int errorCode() const = 0; +protected: + /** Determine if problem is of dimension zero and if it is check if solution + is feasible.*/ + bool zeroDimension(const Ipopt::SmartPtr<Ipopt::TNLP> &tnlp, + ReturnStatus &optimization_status); + + /** Initializes options and journalist.*/ + void initializeOptionsAndJournalist(); + + /** Storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist_; + + /** List of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + + /** Registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions_; + + /** Prefix to use for reading bonmin's options.*/ + std::string prefix_; + /** Global start time.*/ + double start_time_; + + /** Global time limit.*/ + double time_limit_; + + /** To record default log level.*/ + int default_log_level_; + /// Copy Constructor + TNLPSolver(const TNLPSolver & other); + +}; +} +#endif + + diff --git a/thirdparty/linux/include/coin/BonTypes.hpp b/thirdparty/linux/include/coin/BonTypes.hpp new file mode 100644 index 0000000..2924dfa --- /dev/null +++ b/thirdparty/linux/include/coin/BonTypes.hpp @@ -0,0 +1,102 @@ +#ifndef __BonTypes_H_ +#define __BonTypes_H_ +#include<vector> +#include "CoinSmartPtr.hpp" + +namespace Bonmin { +/** A small wrap around std::vector to give easy access to array for interfacing with fortran code.*/ +template<typename T> +class vector : public std::vector<T>{ +public: + /** Default constructor.*/ + vector(): std::vector<T>(){} + /** Constructor with initialization.*/ + vector(size_t n, const T& v): std::vector<T>(n,v){} + /** Copy constructor.*/ + vector(const vector<T>& other): std::vector<T>(other){} + /** Copy constructor.*/ + vector(const std::vector<T>& other): std::vector<T>(other){} + /** constructor with size.*/ + vector(size_t n): std::vector<T>(n){} + /** Assignment.*/ + vector<T>& operator=(const vector<T>& other){ + std::vector<T>::operator=(other); + return (*this);} + /** Assignment.*/ + vector<T>& operator=(const std::vector<T>& other){ + return std::vector<T>::operator=(other); + return (*this);} + +/** Access pointer to first element of storage.*/ +inline T* operator()(){ +#if defined(_MSC_VER) + if (std::vector<T>::size() == 0) + return NULL; +#endif +return &std::vector<T>::front();} +/** Access pointer to first element of storage.*/ +inline const T* operator()() const { +#if defined(_MSC_VER) + if (std::vector<T>::size() == 0) + return NULL; +#endif +return &std::vector<T>::front(); +} +}; + +//structure to store an object of class X in a Coin::ReferencedObject +template<class X> +struct SimpleReferenced : public Coin::ReferencedObject { + /** The object.*/ + X object; + + const X& operator()() const{ + return object;} + + X& operator()() { + return object;} + +}; +//structure to store a pointer to an object of class X in a +// Coin::ReferencedObject +template<class X> +struct SimpleReferencedPtr : public Coin::ReferencedObject { + /** The object.*/ + X * object; + + SimpleReferencedPtr(): + object(NULL){} + + ~SimpleReferencedPtr(){ + delete object;} + + const X& operator()() const{ + return *object;} + + X& operator()() { + return *object;} + + const X* ptr() const{ + return object;} + + X* ptr(){ + return object;} +}; + +template <class X> +SimpleReferenced<X> * make_referenced(X other){ + SimpleReferenced<X> * ret_val = new SimpleReferenced<X>; + ret_val->object = other; + return ret_val; +} +template <class X> +SimpleReferencedPtr<X> * make_referenced(X* other){ + SimpleReferencedPtr <X> * ret_val = new SimpleReferencedPtr<X>; + ret_val->object = other; + return ret_val; +} + + +} +#endif + diff --git a/thirdparty/linux/include/coin/BonminConfig.h b/thirdparty/linux/include/coin/BonminConfig.h new file mode 100644 index 0000000..1878f14 --- /dev/null +++ b/thirdparty/linux/include/coin/BonminConfig.h @@ -0,0 +1,19 @@ +/* src/Interfaces/config_bonmin.h. Generated by configure. */ +/* src/Interfaces/config_bonmin.h.in. */ + +#ifndef __CONFIG_BONMIN_H__ +#define __CONFIG_BONMIN_H__ + +/* Version number of project */ +#define BONMIN_VERSION "1.8.4" + +/* Major Version number of project */ +#define BONMIN_VERSION_MAJOR 1 + +/* Minor Version number of project */ +#define BONMIN_VERSION_MINOR 8 + +/* Release Version number of project */ +#define BONMIN_VERSION_RELEASE 4 + +#endif diff --git a/thirdparty/linux/include/coin/CbcBranchActual.hpp b/thirdparty/linux/include/coin/CbcBranchActual.hpp new file mode 100644 index 0000000..709883c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchActual.hpp @@ -0,0 +1,24 @@ +/* $Id: CbcBranchActual.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchActual_H +#define CbcBranchActual_H + +#include "CbcBranchBase.hpp" +#include "CoinPackedMatrix.hpp" +#include "CbcClique.hpp" +#include "CbcSOS.hpp" +#include "CbcSimpleInteger.hpp" +#include "CbcNWay.hpp" +#include "CbcSimpleIntegerPseudoCost.hpp" +#include "CbcBranchDefaultDecision.hpp" +#include "CbcFollowOn.hpp" +#include "CbcFixVariable.hpp" +#include "CbcDummyBranchingObject.hpp" +#include "CbcGeneral.hpp" +#include "CbcGeneralDepth.hpp" +#include "CbcSubProblem.hpp" +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchAllDifferent.hpp b/thirdparty/linux/include/coin/CbcBranchAllDifferent.hpp new file mode 100644 index 0000000..a380945 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchAllDifferent.hpp @@ -0,0 +1,62 @@ +// $Id: CbcBranchAllDifferent.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/13/2009-- carved out of CbcBranchCut + +#ifndef CbcBranchAllDifferent_H +#define CbcBranchAllDifferent_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" +#include "CbcBranchCut.hpp" + +/** Define a branch class that branches so that it is only satsified if all + members have different values + So cut is x <= y-1 or x >= y+1 +*/ + + +class CbcBranchAllDifferent : public CbcBranchCut { + +public: + + // Default Constructor + CbcBranchAllDifferent (); + + /** Useful constructor - passed set of integer variables which must all be different + */ + CbcBranchAllDifferent (CbcModel * model, int number, const int * which); + + // Copy constructor + CbcBranchAllDifferent ( const CbcBranchAllDifferent &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchAllDifferent & operator=( const CbcBranchAllDifferent& rhs); + + // Destructor + ~CbcBranchAllDifferent (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + +protected: + /// data + + /// Number of entries + int numberInSet_; + /// Which variables + int * which_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchBase.hpp b/thirdparty/linux/include/coin/CbcBranchBase.hpp new file mode 100644 index 0000000..56c4261 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchBase.hpp @@ -0,0 +1,78 @@ +/* $Id: CbcBranchBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchBase_H +#define CbcBranchBase_H + +#include <string> +#include <vector> +#include "OsiBranchingObject.hpp" + +enum CbcRangeCompare { + CbcRangeSame, + CbcRangeDisjoint, + CbcRangeSubset, + CbcRangeSuperset, + CbcRangeOverlap +}; + +#include "CbcObject.hpp" +#include "CbcBranchingObject.hpp" +#include "CbcBranchDecision.hpp" +#include "CbcConsequence.hpp" +#include "CbcObjectUpdateData.hpp" + +//############################################################################## + +/** Compare two ranges. The two bounds arrays are both of size two and + describe closed intervals. Return the appropriate CbcRangeCompare value + (first argument being the sub/superset if that's the case). In case of + overlap (and if \c replaceIfOverlap is true) replace the content of thisBd + with the intersection of the ranges. +*/ +static inline CbcRangeCompare +CbcCompareRanges(double* thisBd, const double* otherBd, + const bool replaceIfOverlap) +{ + const double lbDiff = thisBd[0] - otherBd[0]; + if (lbDiff < 0) { // lb of this < lb of other + if (thisBd[1] >= otherBd[1]) { // ub of this >= ub of other + return CbcRangeSuperset; + } else if (thisBd[1] < otherBd[0]) { + return CbcRangeDisjoint; + } else { + // overlap + if (replaceIfOverlap) { + thisBd[0] = otherBd[0]; + } + return CbcRangeOverlap; + } + } else if (lbDiff > 0) { // lb of this > lb of other + if (thisBd[1] <= otherBd[1]) { // ub of this <= ub of other + return CbcRangeSubset; + } else if (thisBd[0] > otherBd[1]) { + return CbcRangeDisjoint; + } else { + // overlap + if (replaceIfOverlap) { + thisBd[1] = otherBd[1]; + } + return CbcRangeOverlap; + } + } else { // lb of this == lb of other + if (thisBd[1] == otherBd[1]) { + return CbcRangeSame; + } + return thisBd[1] < otherBd[1] ? CbcRangeSubset : CbcRangeSuperset; + } + + return CbcRangeSame; // fake return + +} + +//############################################################################# + +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchCut.hpp b/thirdparty/linux/include/coin/CbcBranchCut.hpp new file mode 100644 index 0000000..0fdc940 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchCut.hpp @@ -0,0 +1,183 @@ +/* $Id: CbcBranchCut.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchCut_H +#define CbcBranchCut_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a cut branching class. + At present empty - all stuff in descendants +*/ + +class CbcBranchCut : public CbcObject { + +public: + + // Default Constructor + CbcBranchCut (); + + /** In to maintain normal methods + */ + CbcBranchCut (CbcModel * model); + // Copy constructor + CbcBranchCut ( const CbcBranchCut &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchCut & operator=( const CbcBranchCut& rhs); + + // Destructor + ~CbcBranchCut (); + + /// Infeasibility + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. + + At present this will do nothing + */ + virtual void feasibleRegion(); + + /** \brief Return true if branch created by object should fix variables + */ + virtual bool boundBranch() const ; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in the good direction. + + The preferred branching object will force the variable to be +/-1 from + its current value, depending on the reduced cost and objective sense. If + movement in the direction which improves the objective is impossible due + to bounds on the variable, the branching object will move in the other + direction. If no movement is possible, the method returns NULL. + + Only the bounds on this variable are considered when determining if the new + point is feasible. + + At present this does nothing + */ + virtual CbcBranchingObject * preferredNewFeasible() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + As for preferredNewFeasible(), but the preferred branching object will + force movement in a direction that degrades the objective. + + At present this does nothing + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const ; + + using CbcObject::resetBounds ; + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(); + + +protected: + /// data + +}; +/** Cut branching object + + This object can specify a two-way branch in terms of two cuts +*/ + +class CbcCutBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcCutBranchingObject (); + + /** Create a cut branching object + + Cut down will applied on way=-1, up on way==1 + Assumed down will be first so way_ set to -1 + */ + CbcCutBranchingObject (CbcModel * model, OsiRowCut & down, OsiRowCut &up, bool canFix); + + /// Copy constructor + CbcCutBranchingObject ( const CbcCutBranchingObject &); + + /// Assignment operator + CbcCutBranchingObject & operator= (const CbcCutBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcCutBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for variables or adds a cut depending on the + current arm of the branch and advances the object state to the next arm. + Returns change in guessed objective on next branch + */ + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** \brief Return true if branch should fix variables + */ + virtual bool boundBranch() const; + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return CutBranchingObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Cut for the down arm (way_ = -1) + OsiRowCut down_; + /// Cut for the up arm (way_ = 1) + OsiRowCut up_; + /// True if one way can fix variables + bool canFix_; +}; +#endif diff --git a/thirdparty/linux/include/coin/CbcBranchDecision.hpp b/thirdparty/linux/include/coin/CbcBranchDecision.hpp new file mode 100644 index 0000000..538fe8c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchDecision.hpp @@ -0,0 +1,129 @@ +// $Id: CbcBranchDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcBranchDecision_H +#define CbcBranchDecision_H + +#include "CbcBranchBase.hpp" + +/** Abstract branching decision base class + + In the abstract, an CbcBranchDecision object is expected to be able to + compare two possible branching choices. + + The #betterBranch() method is the crucial routine. It is expected to be able + to compare two \link CbcBranchingObject CbcBranchingObjects \endlink. + + See CbcObject for an overview of the three classes (CbcObject, + CbcBranchingObject, and CbcBranchDecision) which make up cbc's branching + model. +*/ +class CbcModel; +class OsiChooseVariable; + +class CbcBranchDecision { +public: + /// Default Constructor + CbcBranchDecision (); + + // Copy constructor + CbcBranchDecision ( const CbcBranchDecision &); + + /// Destructor + virtual ~CbcBranchDecision(); + +/// Clone + virtual CbcBranchDecision * clone() const = 0; + + /// Initialize <i>e.g.</i> before starting to choose a branch at a node + virtual void initialize(CbcModel * model) = 0; + + /** \brief Compare two branching objects. Return nonzero if branching + using \p thisOne is better than branching using \p bestSoFar. + + If \p bestSoFar is NULL, the routine should return a nonzero value. + This routine is used only after strong branching. + Either this or bestBranch is used depending which user wants. + + */ + + virtual int + betterBranch (CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numberInfeasibilitiesUp, + double changeDown, int numberInfeasibilitiesDown) = 0 ; + + /** \brief Compare N branching objects. Return index of best + and sets way of branching in chosen object. + + Either this or betterBranch is used depending which user wants. + */ + + virtual int + bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied, + double * changeUp, int * numberInfeasibilitiesUp, + double * changeDown, int * numberInfeasibilitiesDown, + double objectiveValue) ; + + /** Says whether this method can handle both methods - + 1 better, 2 best, 3 both */ + virtual int whichMethod() { + return 2; + } + + /** Saves a clone of current branching object. Can be used to update + information on object causing branch - after branch */ + virtual void saveBranchingObject(OsiBranchingObject * ) {} + /** Pass in information on branch just done. + assumes object can get information from solver */ + virtual void updateInformation(OsiSolverInterface * , + const CbcNode * ) {} + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double ) {} + virtual double getBestCriterion() const { + return 0.0; + } + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /// Model + inline CbcModel * cbcModel() const { + return model_; + } + /* If chooseMethod_ id non-null then the rest is fairly pointless + as choosemethod_ will be doing all work + This comment makes more sense if you realise that there's a conversion in + process from the Cbc branching classes to Osi branching classes. The test + for use of the Osi branching classes is CbcModel::branchingMethod_ + non-null (i.e., it points to one of these CbcBranchDecision objects) and + that branch decision object has an OsiChooseVariable method set. In which + case, we'll use it, rather than the choose[*]Variable methods defined in + CbcNode. + */ + + OsiChooseVariable * chooseMethod() const { + return chooseMethod_; + } + /// Set (clone) chooseMethod + void setChooseMethod(const OsiChooseVariable & method); + +protected: + + // Clone of branching object + CbcBranchingObject * object_; + /// Pointer to model + CbcModel * model_; + /* If chooseMethod_ id non-null then the rest is fairly pointless + as choosemethod_ will be doing all work + */ + OsiChooseVariable * chooseMethod_; +private: + /// Assignment is illegal + CbcBranchDecision & operator=(const CbcBranchDecision& rhs); + +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchDefaultDecision.hpp b/thirdparty/linux/include/coin/CbcBranchDefaultDecision.hpp new file mode 100644 index 0000000..d45035e --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchDefaultDecision.hpp @@ -0,0 +1,100 @@ +// $Id: CbcBranchDefaultDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcBranchDefaultDecision_H +#define CbcBranchDefaultDecision_H + +#include "CbcBranchBase.hpp" +/** Branching decision default class + + This class implements a simple default algorithm + (betterBranch()) for choosing a branching variable. +*/ + +class CbcBranchDefaultDecision : public CbcBranchDecision { +public: + // Default Constructor + CbcBranchDefaultDecision (); + + // Copy constructor + CbcBranchDefaultDecision ( const CbcBranchDefaultDecision &); + + virtual ~CbcBranchDefaultDecision(); + + /// Clone + virtual CbcBranchDecision * clone() const; + + /// Initialize, <i>e.g.</i> before the start of branch selection at a node + virtual void initialize(CbcModel * model); + + /** \brief Compare two branching objects. Return nonzero if \p thisOne is + better than \p bestSoFar. + + The routine compares branches using the values supplied in \p numInfUp and + \p numInfDn until a solution is found by search, after which it uses the + values supplied in \p changeUp and \p changeDn. The best branching object + seen so far and the associated parameter values are remembered in the + \c CbcBranchDefaultDecision object. The nonzero return value is +1 if the + up branch is preferred, -1 if the down branch is preferred. + + As the names imply, the assumption is that the values supplied for + \p numInfUp and \p numInfDn will be the number of infeasibilities reported + by the branching object, and \p changeUp and \p changeDn will be the + estimated change in objective. Other measures can be used if desired. + + Because an \c CbcBranchDefaultDecision object remembers the current best + branching candidate (#bestObject_) as well as the values used in the + comparison, the parameter \p bestSoFar is redundant, hence unused. + */ + virtual int betterBranch(CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numInfUp, + double changeDn, int numInfDn); + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double value); + virtual double getBestCriterion() const; + + /** \brief Compare N branching objects. Return index of best + and sets way of branching in chosen object. + + This routine is used only after strong branching. + */ + + virtual int + bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied, + double * changeUp, int * numberInfeasibilitiesUp, + double * changeDown, int * numberInfeasibilitiesDown, + double objectiveValue) ; +private: + + /// Illegal Assignment operator + CbcBranchDefaultDecision & operator=(const CbcBranchDefaultDecision& rhs); + + /// data + + /// "best" so far + double bestCriterion_; + + /// Change up for best + double bestChangeUp_; + + /// Number of infeasibilities for up + int bestNumberUp_; + + /// Change down for best + double bestChangeDown_; + + /// Pointer to best branching object + CbcBranchingObject * bestObject_; + + /// Number of infeasibilities for down + int bestNumberDown_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchDynamic.hpp b/thirdparty/linux/include/coin/CbcBranchDynamic.hpp new file mode 100644 index 0000000..ffc5c34 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchDynamic.hpp @@ -0,0 +1,206 @@ +/* $Id: CbcBranchDynamic.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchDynamic_H +#define CbcBranchDynamic_H + +#include "CoinPackedMatrix.hpp" +#include "CbcSimpleIntegerDynamicPseudoCost.hpp" +#include "CbcBranchActual.hpp" + +/** Branching decision dynamic class + + This class implements a simple algorithm + (betterBranch()) for choosing a branching variable when dynamic pseudo costs. +*/ + +class CbcBranchDynamicDecision : public CbcBranchDecision { +public: + // Default Constructor + CbcBranchDynamicDecision (); + + // Copy constructor + CbcBranchDynamicDecision ( const CbcBranchDynamicDecision &); + + virtual ~CbcBranchDynamicDecision(); + + /// Clone + virtual CbcBranchDecision * clone() const; + + /// Initialize, <i>e.g.</i> before the start of branch selection at a node + virtual void initialize(CbcModel * model); + + /** \brief Compare two branching objects. Return nonzero if \p thisOne is + better than \p bestSoFar. + + The routine compares branches using the values supplied in \p numInfUp and + \p numInfDn until a solution is found by search, after which it uses the + values supplied in \p changeUp and \p changeDn. The best branching object + seen so far and the associated parameter values are remembered in the + \c CbcBranchDynamicDecision object. The nonzero return value is +1 if the + up branch is preferred, -1 if the down branch is preferred. + + As the names imply, the assumption is that the values supplied for + \p numInfUp and \p numInfDn will be the number of infeasibilities reported + by the branching object, and \p changeUp and \p changeDn will be the + estimated change in objective. Other measures can be used if desired. + + Because an \c CbcBranchDynamicDecision object remembers the current best + branching candidate (#bestObject_) as well as the values used in the + comparison, the parameter \p bestSoFar is redundant, hence unused. + */ + virtual int betterBranch(CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numInfUp, + double changeDn, int numInfDn); + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double value); + virtual double getBestCriterion() const; + /** Says whether this method can handle both methods - + 1 better, 2 best, 3 both */ + virtual int whichMethod() { + return 3; + } + + /** Saves a clone of current branching object. Can be used to update + information on object causing branch - after branch */ + virtual void saveBranchingObject(OsiBranchingObject * object) ; + /** Pass in information on branch just done. + assumes object can get information from solver */ + virtual void updateInformation(OsiSolverInterface * solver, + const CbcNode * node); + + +private: + + /// Illegal Assignment operator + CbcBranchDynamicDecision & operator=(const CbcBranchDynamicDecision& rhs); + + /// data + + /// "best" so far + double bestCriterion_; + + /// Change up for best + double bestChangeUp_; + + /// Number of infeasibilities for up + int bestNumberUp_; + + /// Change down for best + double bestChangeDown_; + + /// Number of infeasibilities for down + int bestNumberDown_; + + /// Pointer to best branching object + CbcBranchingObject * bestObject_; +}; +/** Simple branching object for an integer variable with pseudo costs + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcDynamicPseudoCostBranchingObject : public CbcIntegerBranchingObject { + +public: + + /// Default constructor + CbcDynamicPseudoCostBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, + int way , double value, + CbcSimpleIntegerDynamicPseudoCost * object) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcDynamicPseudoCostBranchingObject ( const CbcDynamicPseudoCostBranchingObject &); + + /// Assignment operator + CbcDynamicPseudoCostBranchingObject & operator= (const CbcDynamicPseudoCostBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcDynamicPseudoCostBranchingObject (); + + /// Does part of constructor + void fillPart (int variable, + int way , double value, + CbcSimpleIntegerDynamicPseudoCost * object) ; + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + This version also changes guessed objective value + */ + virtual double branch(); + + /** Some branchingObjects may claim to be able to skip + strong branching. If so they have to fill in CbcStrongInfo. + The object mention in incoming CbcStrongInfo must match. + Returns nonzero if skip is wanted */ + virtual int fillStrongInfo( CbcStrongInfo & info); + + /// Change in guessed + inline double changeInGuessed() const { + return changeInGuessed_; + } + /// Set change in guessed + inline void setChangeInGuessed(double value) { + changeInGuessed_ = value; + } + /// Return object + inline CbcSimpleIntegerDynamicPseudoCost * object() const { + return object_; + } + /// Set object + inline void setObject(CbcSimpleIntegerDynamicPseudoCost * object) { + object_ = object; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return DynamicPseudoCostBranchObj; + } + + // LL: compareOriginalObject and compareBranchingObject are inherited from + // CbcIntegerBranchingObject thus need not be declared/defined here. After + // all, this kind of branching object is simply using pseudocosts to make + // decisions, but once the decisions are made they are the same kind as in + // the underlying class. + +protected: + /// Change in guessed objective value for next branch + double changeInGuessed_; + /// Pointer back to object + CbcSimpleIntegerDynamicPseudoCost * object_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchLotsize.hpp b/thirdparty/linux/include/coin/CbcBranchLotsize.hpp new file mode 100644 index 0000000..4ba6510 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchLotsize.hpp @@ -0,0 +1,242 @@ +/* $Id: CbcBranchLotsize.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchLotsize_H +#define CbcBranchLotsize_H + +#include "CbcBranchBase.hpp" +/** Lotsize class */ + + +class CbcLotsize : public CbcObject { + +public: + + // Default Constructor + CbcLotsize (); + + /* Useful constructor - passed model index. + Also passed valid values - if range then pairs + */ + CbcLotsize (CbcModel * model, int iColumn, + int numberPoints, const double * points, bool range = false); + + // Copy constructor + CbcLotsize ( const CbcLotsize &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcLotsize & operator=( const CbcLotsize& rhs); + + // Destructor + ~CbcLotsize (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. + */ + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in the good direction. + + The preferred branching object will force the variable to be +/-1 from + its current value, depending on the reduced cost and objective sense. If + movement in the direction which improves the objective is impossible due + to bounds on the variable, the branching object will move in the other + direction. If no movement is possible, the method returns NULL. + + Only the bounds on this variable are considered when determining if the new + point is feasible. + */ + virtual CbcBranchingObject * preferredNewFeasible() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + As for preferredNewFeasible(), but the preferred branching object will + force movement in a direction that degrades the objective. + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const ; + + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(const OsiSolverInterface * solver); + + /** Finds range of interest so value is feasible in range range_ or infeasible + between hi[range_] and lo[range_+1]. Returns true if feasible. + */ + bool findRange(double value) const; + + /** Returns floor and ceiling + */ + virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value, + double tolerance) const; + + /// Model column number + inline int modelSequence() const { + return columnNumber_; + } + /// Set model column number + inline void setModelSequence(int value) { + columnNumber_ = value; + } + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /// Original variable bounds + inline double originalLowerBound() const { + return bound_[0]; + } + inline double originalUpperBound() const { + return bound_[rangeType_*numberRanges_-1]; + } + /// Type - 1 points, 2 ranges + inline int rangeType() const { + return rangeType_; + } + /// Number of points + inline int numberRanges() const { + return numberRanges_; + } + /// Ranges + inline double * bound() const { + return bound_; + } + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + +private: + /// Just for debug (CBC_PRINT defined in CbcBranchLotsize.cpp) + void printLotsize(double value, bool condition, int type) const; + +private: + /// data + + /// Column number in model + int columnNumber_; + /// Type - 1 points, 2 ranges + int rangeType_; + /// Number of points + int numberRanges_; + // largest gap + double largestGap_; + /// Ranges + double * bound_; + /// Current range + mutable int range_; +}; + +/** Lotsize branching object + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcLotsizeBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcLotsizeBranchingObject (); + + /** Create a lotsize floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= valid range below(x*), the other valid range above(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcLotsizeBranchingObject (CbcModel *model, int variable, + int way , double value, const CbcLotsize * lotsize) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix in valid range + */ + + CbcLotsizeBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcLotsizeBranchingObject ( const CbcLotsizeBranchingObject &); + + /// Assignment operator + CbcLotsizeBranchingObject & operator= (const CbcLotsizeBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcLotsizeBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + */ + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return LotsizeBranchObj; + } + + // LL: compareOriginalObject can be inherited from the CbcBranchingObject + // since variable_ uniquely defines the lot sizing object. + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchToFixLots.hpp b/thirdparty/linux/include/coin/CbcBranchToFixLots.hpp new file mode 100644 index 0000000..3b0a9ea --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchToFixLots.hpp @@ -0,0 +1,94 @@ +// $Id: CbcBranchToFixLots.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/13/2009-- carved out of CbcBranchCut + +#ifndef CbcBranchToFixLots_H +#define CbcBranchToFixLots_H + +#include "CbcBranchCut.hpp" +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a branch class that branches so that one way variables are fixed + while the other way cuts off that solution. + a) On reduced cost + b) When enough ==1 or <=1 rows have been satisfied (not fixed - satisfied) +*/ + + +class CbcBranchToFixLots : public CbcBranchCut { + +public: + + // Default Constructor + CbcBranchToFixLots (); + + /** Useful constructor - passed reduced cost tolerance and fraction we would like fixed. + Also depth level to do at. + Also passed number of 1 rows which when clean triggers fix + Always does if all 1 rows cleaned up and number>0 or if fraction columns reached + Also whether to create branch if can't reach fraction. + */ + CbcBranchToFixLots (CbcModel * model, double djTolerance, + double fractionFixed, int depth, + int numberClean = 0, + const char * mark = NULL, + bool alwaysCreate = false); + + // Copy constructor + CbcBranchToFixLots ( const CbcBranchToFixLots &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchToFixLots & operator=( const CbcBranchToFixLots& rhs); + + // Destructor + ~CbcBranchToFixLots (); + + /** Does a lot of the work, + Returns 0 if no good, 1 if dj, 2 if clean, 3 if both + FIXME: should use enum or equivalent to make these numbers clearer. + */ + int shallWe() const; + + /// Infeasibility for an integer variable - large is 0.5, but also can be infinity when known infeasible. + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return true; + } + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + + +protected: + /// data + + /// Reduced cost tolerance i.e. dj has to be >= this before fixed + double djTolerance_; + /// We only need to make sure this fraction fixed + double fractionFixed_; + /// Never fix ones marked here + char * mark_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Do if depth multiple of this + int depth_; + /// number of ==1 rows which need to be clean + int numberClean_; + /// If true then always create branch + bool alwaysCreate_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcBranchingObject.hpp b/thirdparty/linux/include/coin/CbcBranchingObject.hpp new file mode 100644 index 0000000..803108d --- /dev/null +++ b/thirdparty/linux/include/coin/CbcBranchingObject.hpp @@ -0,0 +1,236 @@ +// $Id: CbcBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcBranchingObject_H +#define CbcBranchingObject_H + +#include <string> +#include <vector> +#include "CbcBranchBase.hpp" +#include "OsiBranchingObject.hpp" + + +// The types of objects that will be derived from this class. +enum CbcBranchObjType + { + SimpleIntegerBranchObj = 100, + SimpleIntegerDynamicPseudoCostBranchObj = 101, + CliqueBranchObj = 102, + LongCliqueBranchObj = 103, + SoSBranchObj = 104, + NWayBranchObj = 105, + FollowOnBranchObj = 106, + DummyBranchObj = 107, + GeneralDepthBranchObj = 108, + OneGeneralBranchingObj = 110, + CutBranchingObj = 200, + LotsizeBranchObj = 300, + DynamicPseudoCostBranchObj = 400 + }; + +/** \brief Abstract branching object base class + Now just difference with OsiBranchingObject + + In the abstract, an CbcBranchingObject contains instructions for how to + branch. We want an abstract class so that we can describe how to branch on + simple objects (<i>e.g.</i>, integers) and more exotic objects + (<i>e.g.</i>, cliques or hyperplanes). + + The #branch() method is the crucial routine: it is expected to be able to + step through a set of branch arms, executing the actions required to create + each subproblem in turn. The base class is primarily virtual to allow for + a wide range of problem modifications. + + See CbcObject for an overview of the three classes (CbcObject, + CbcBranchingObject, and CbcBranchDecision) which make up cbc's branching + model. +*/ + +class CbcBranchingObject : public OsiBranchingObject { + +public: + + /// Default Constructor + CbcBranchingObject (); + + /// Constructor + CbcBranchingObject (CbcModel * model, int variable, int way , double value); + + /// Copy constructor + CbcBranchingObject ( const CbcBranchingObject &); + + /// Assignment operator + CbcBranchingObject & operator=( const CbcBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const = 0; + + /// Destructor + virtual ~CbcBranchingObject (); + + /** Some branchingObjects may claim to be able to skip + strong branching. If so they have to fill in CbcStrongInfo. + The object mention in incoming CbcStrongInfo must match. + Returns nonzero if skip is wanted */ + virtual int fillStrongInfo( CbcStrongInfo & ) { + return 0; + } + /// Reset number of branches left to original + inline void resetNumberBranchesLeft() { + branchIndex_ = 0; + } + /// Set number of branches to do + inline void setNumberBranches(int value) { + branchIndex_ = 0; + numberBranches_ = value; + } + + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. Mainly for diagnostics, whether it is true branch or + strong branching is also passed. + Returns change in guessed objective on next branch + */ + virtual double branch() = 0; + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. Mainly for diagnostics, whether it is true branch or + strong branching is also passed. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * ) { + return branch(); + } + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * , + double * , double * , + int ) const {} + + /** Change (tighten) bounds in object to reflect bounds in solver. + Return true if now fixed */ + virtual bool tighten(OsiSolverInterface * ) {return false;} + + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch() { + assert(branchIndex_ > 0); + branchIndex_--; + way_ = -way_; + } + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print() const {} + + /** \brief Index identifying the associated CbcObject within its class. + + The name is misleading, and typically the index will <i>not</i> refer + directly to a variable. + Rather, it identifies an CbcObject within the class of similar + CbcObjects + + <i>E.g.</i>, for an CbcSimpleInteger, variable() is the index of the + integer variable in the set of integer variables (<i>not</i> the index of + the variable in the set of all variables). + */ + inline int variable() const { + return variable_; + } + + /** Get the state of the branching object + + Returns a code indicating the active arm of the branching object. + The precise meaning is defined in the derived class. + + \sa #way_ + */ + inline int way() const { + return way_; + } + + /** Set the state of the branching object. + + See #way() + */ + inline void way(int way) { + way_ = way; + } + + /// update model + inline void setModel(CbcModel * model) { + model_ = model; + } + /// Return model + inline CbcModel * model() const { + return model_; + } + + /// Return pointer back to object which created + inline CbcObject * object() const { + return originalCbcObject_; + } + /// Set pointer back to object which created + inline void setOriginalObject(CbcObject * object) { + originalCbcObject_ = object; + } + + // Methods used in heuristics + + /** Return the type (an integer identifier) of \c this. + See definition of CbcBranchObjType above for possibilities + */ + + virtual CbcBranchObjType type() const = 0; + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const { + const CbcBranchingObject* br = dynamic_cast<const CbcBranchingObject*>(brObj); + return variable() - br->variable(); + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be of the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false) = 0; + +protected: + + /// The model that owns this branching object + CbcModel * model_; + /// Pointer back to object which created + CbcObject * originalCbcObject_; + + /// Branching variable (0 is first integer) + int variable_; + // was - Way to branch - -1 down (first), 1 up, -2 down (second), 2 up (second) + /** The state of the branching object. + + Specifies the active arm of the branching object. Coded as -1 to take + the `down' arm, +1 for the `up' arm. `Down' and `up' are defined based on + the natural meaning (floor and ceiling, respectively) for a simple integer. + The precise meaning is defined in the derived class. + */ + int way_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcClique.hpp b/thirdparty/linux/include/coin/CbcClique.hpp new file mode 100644 index 0000000..e21e027 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcClique.hpp @@ -0,0 +1,303 @@ +// $Id: CbcClique.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcClique_H +#define CbcClique_H + +/** \brief Branching object for cliques + + A clique is defined to be a set of binary variables where fixing any one + variable to its `strong' value fixes all other variables. An example is the + most common SOS1 construction: a set of binary variables x_j s.t. SUM{j} + x_j = 1. Setting any one variable to 1 forces all other variables to 0. + (See comments for CbcSOS below.) + + Other configurations are possible, however: Consider x1-x2+x3 <= 0. + Setting x1 (x3) to 1 forces x2 to 1 and x3 (x1) to 0. Setting x2 to 0 + forces x1 and x3 to 0. + + The proper point of view to take when interpreting CbcClique is + `generalisation of SOS1 on binary variables.' To get into the proper frame + of mind, here's an example. + + Consider the following sequence, where x_j = (1-y_j): + \verbatim + x1 + x2 + x3 <= 1 all strong at 1 + x1 - y2 + x3 <= 0 y2 strong at 0; x1, x3 strong at 1 + -y1 - y2 + x3 <= -1 y1, y2 strong at 0, x3 strong at 1 + -y1 - y2 - y3 <= -2 all strong at 0 + \endverbatim + The first line is a standard SOS1 on binary variables. + + Variables with +1 coefficients are `SOS-style' and variables with -1 + coefficients are `non-SOS-style'. So #numberNonSOSMembers_ simply tells you + how many variables have -1 coefficients. The implicit rhs for a clique is + 1-numberNonSOSMembers_. +*/ +class CbcClique : public CbcObject { + +public: + + /// Default Constructor + CbcClique (); + + /** Useful constructor (which are integer indices) slack can denote a slack + in set. If type == NULL then as if 1 + */ + CbcClique (CbcModel * model, int cliqueType, int numberMembers, + const int * which, const char * type, + int identifier, int slack = -1); + + /// Copy constructor + CbcClique ( const CbcClique &); + + /// Clone + virtual CbcObject * clone() const; + + /// Assignment operator + CbcClique & operator=( const CbcClique& rhs); + + /// Destructor + virtual ~CbcClique (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + /** \brief Number of variables with -1 coefficient + + Number of non-SOS members, i.e., fixing to zero is strong. + See comments at head of class, and comments for #type_. + */ + inline int numberNonSOSMembers() const { + return numberNonSOSMembers_; + } + + /// Members (indices in range 0 ... numberIntegers_-1) + inline const int * members() const { + return members_; + } + + /*! \brief Type of each member, i.e., which way is strong. + + This also specifies whether a variable has a +1 or -1 coefficient. + - 0 => -1 coefficient, 0 is strong value + - 1 => +1 coefficient, 1 is strong value + If unspecified, all coefficients are assumed to be positive. + + Indexed as 0 .. numberMembers_-1 + */ + inline char type(int index) const { + if (type_) return type_[index]; + else return 1; + } + + /// Clique type: 0 is <=, 1 is == + inline int cliqueType() const { + return cliqueType_; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Number of members + int numberMembers_; + + /// Number of Non SOS members i.e. fixing to zero is strong + int numberNonSOSMembers_; + + /// Members (indices in range 0 ... numberIntegers_-1) + int * members_; + + /** \brief Strong value for each member. + + This also specifies whether a variable has a +1 or -1 coefficient. + - 0 => -1 coefficient, 0 is strong value + - 1 => +1 coefficient, 1 is strong value + If unspecified, all coefficients are assumed to be positive. + + Indexed as 0 .. numberMembers_-1 + */ + char * type_; + + /** \brief Clique type + + 0 defines a <= relation, 1 an equality. The assumed value of the rhs is + numberNonSOSMembers_+1. (See comments for the class.) + */ + int cliqueType_; + + /** \brief Slack variable for the clique + + Identifies the slack variable for the clique (typically added to convert + a <= relation to an equality). Value is sequence number within clique + menbers. + */ + int slack_; +}; + +/** Branching object for unordered cliques + + Intended for cliques which are long enough to make it worthwhile + but <= 64 members. There will also be ones for long cliques. + + Variable_ is the clique id number (redundant, as the object also holds a + pointer to the clique. + */ +class CbcCliqueBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcCliqueBranchingObject (); + + // Useful constructor + CbcCliqueBranchingObject (CbcModel * model, const CbcClique * clique, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcCliqueBranchingObject ( const CbcCliqueBranchingObject &); + + // Assignment operator + CbcCliqueBranchingObject & operator=( const CbcCliqueBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcCliqueBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return CliqueBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be of the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + const CbcClique * clique_; + /// downMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int downMask_[2]; + /// upMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int upMask_[2]; +}; + +/** Unordered Clique Branching Object class. + These are for cliques which are > 64 members + Variable is number of clique. + */ +class CbcLongCliqueBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcLongCliqueBranchingObject (); + + // Useful constructor + CbcLongCliqueBranchingObject (CbcModel * model, const CbcClique * clique, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject &); + + // Assignment operator + CbcLongCliqueBranchingObject & operator=( const CbcLongCliqueBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcLongCliqueBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return LongCliqueBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + const CbcClique * clique_; + /// downMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int * downMask_; + /// upMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int * upMask_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCompare.hpp b/thirdparty/linux/include/coin/CbcCompare.hpp new file mode 100644 index 0000000..fadc866 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompare.hpp @@ -0,0 +1,39 @@ +/* $Id: CbcCompare.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompare_H +#define CbcCompare_H + +class CbcCompareBase; + +class CbcCompare { +public: + CbcCompareBase * test_; + // Default Constructor + CbcCompare () { + test_ = NULL; + } + + virtual ~CbcCompare() {} + + bool operator() (CbcNode * x, CbcNode * y) { + return test_->test(x, y); + } + bool compareNodes (CbcNode * x, CbcNode * y) { + return test_->test(x, y); + } + /// This is alternate test function + inline bool alternateTest (CbcNode * x, CbcNode * y) { + return test_->alternateTest(x, y); + } + + /// return comparison object + inline CbcCompareBase * comparisonObject() const { + return test_; + } +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCompareActual.hpp b/thirdparty/linux/include/coin/CbcCompareActual.hpp new file mode 100644 index 0000000..60417c8 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareActual.hpp @@ -0,0 +1,14 @@ +/* $Id: CbcCompareActual.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompareActual_H +#define CbcCompareActual_H +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +#include "CbcCompareDepth.hpp" +#include "CbcCompareDefault.hpp" +#endif + diff --git a/thirdparty/linux/include/coin/CbcCompareBase.hpp b/thirdparty/linux/include/coin/CbcCompareBase.hpp new file mode 100644 index 0000000..1242f6d --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareBase.hpp @@ -0,0 +1,142 @@ +/* $Id: CbcCompareBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompareBase_H +#define CbcCompareBase_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + + This is rather inflexible so if the comparison functions wants + it can signal to use alternative criterion on a complete pass + throgh tree. + +*/ +#include "CbcNode.hpp" +#include "CbcConfig.h" + +class CbcModel; +class CbcTree; +class CbcCompareBase { +public: + // Default Constructor + CbcCompareBase () { + test_ = NULL; + threaded_ = false; + } + + /*! \brief Reconsider behaviour after discovering a new solution. + + This allows any method to change its behaviour. It is called + after each solution. + + The method should return true if changes are made which will + alter the evaluation criteria applied to a node. (So that in + cases where the search tree is sorted, it can be properly + rebuilt.) + */ + virtual bool newSolution(CbcModel * ) { return (false) ; } + + /*! \brief Reconsider behaviour after discovering a new solution. + + This allows any method to change its behaviour. It is called + after each solution. + + The method should return true if changes are made which will + alter the evaluation criteria applied to a node. (So that in + cases where the search tree is sorted, it can be properly + rebuilt.) + */ + virtual bool newSolution(CbcModel * , + double , + int ) { return (false) ; } + + // This allows any method to change behavior as it is called + // after every 1000 nodes. + // Return true if want tree re-sorted + virtual bool every1000Nodes(CbcModel * , int ) { + return false; + } + + /** Returns true if wants code to do scan with alternate criterion + NOTE - this is temporarily disabled + */ + virtual bool fullScan() const { + return false; + } + + virtual ~CbcCompareBase() {} + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + // Copy constructor + CbcCompareBase ( const CbcCompareBase & rhs) { + test_ = rhs.test_; + threaded_ = rhs.threaded_; + } + + // Assignment operator + CbcCompareBase & operator=( const CbcCompareBase& rhs) { + if (this != &rhs) { + test_ = rhs.test_; + threaded_ = rhs.threaded_; + } + return *this; + } + + /// Clone + virtual CbcCompareBase * clone() const { + abort(); + return NULL; + } + + /// This is test function + virtual bool test (CbcNode * , CbcNode * ) { + return true; + } + + /// This is alternate test function + virtual bool alternateTest (CbcNode * x, CbcNode * y) { + return test(x, y); + } + + bool operator() (CbcNode * x, CbcNode * y) { + return test(x, y); + } + /// Further test if everything else equal + inline bool equalityTest (CbcNode * x, CbcNode * y) const { + assert (x); + assert (y); + if (!threaded_) { + CbcNodeInfo * infoX = x->nodeInfo(); + assert (infoX); + int nodeNumberX = infoX->nodeNumber(); + CbcNodeInfo * infoY = y->nodeInfo(); + assert (infoY); + int nodeNumberY = infoY->nodeNumber(); + assert (nodeNumberX != nodeNumberY); + return (nodeNumberX > nodeNumberY); + } else { + assert (x->nodeNumber() != y->nodeNumber()); + return (x->nodeNumber() > y->nodeNumber()); + } + } + /// Say threaded + inline void sayThreaded() { + threaded_ = true; + } +protected: + CbcCompareBase * test_; + // If not threaded we can use better way to break ties + bool threaded_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCompareDefault.hpp b/thirdparty/linux/include/coin/CbcCompareDefault.hpp new file mode 100644 index 0000000..2d1ce8e --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareDefault.hpp @@ -0,0 +1,120 @@ +// $Id: CbcCompareDefault.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareDefault_H +#define CbcCompareDefault_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" + +class CbcModel; + +/* This is an example of a more complex rule with data + It is default after first solution + If weight is 0.0 then it is computed to hit first solution + less 5% +*/ +class CbcCompareDefault : public CbcCompareBase { +public: + /// Default Constructor + CbcCompareDefault () ; + /// Constructor with weight + CbcCompareDefault (double weight); + + /// Copy constructor + CbcCompareDefault ( const CbcCompareDefault &rhs); + + /// Assignment operator + CbcCompareDefault & operator=( const CbcCompareDefault& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + ~CbcCompareDefault() ; + /* This returns true if weighted value of node y is less than + weighted value of node x */ + virtual bool test (CbcNode * x, CbcNode * y) ; + + using CbcCompareBase::newSolution ; + /// This allows method to change behavior as it is called + /// after each solution + virtual bool newSolution(CbcModel * model, + double objectiveAtContinuous, + int numberInfeasibilitiesAtContinuous) ; + /// This allows method to change behavior + /// Return true if want tree re-sorted + virtual bool every1000Nodes(CbcModel * model, int numberNodes); + + /* if weight == -1.0 then fewest infeasibilities (before solution) + if -2.0 then do breadth first just for first 1000 nodes + if -3.0 then depth first before solution + */ + inline double getWeight() const { + return weight_; + } + inline void setWeight(double weight) { + weight_ = weight; + } + /// Cutoff + inline double getCutoff() const { + return cutoff_; + } + inline void setCutoff(double cutoff) { + cutoff_ = cutoff; + } + /// Best possible solution + inline double getBestPossible() const { + return bestPossible_; + } + inline void setBestPossible(double bestPossible) { + bestPossible_ = bestPossible; + } + /// Depth above which want to explore first + inline void setBreadthDepth(int value) { + breadthDepth_ = value; + } + /// Start dive + void startDive(CbcModel * model); + /// Clean up diving (i.e. switch off or prepare) + void cleanDive(); +protected: + /// Weight for each infeasibility + double weight_; + /// Weight for each infeasibility - computed from solution + double saveWeight_; + /// Cutoff + double cutoff_; + /// Best possible solution + double bestPossible_; + /// Number of solutions + int numberSolutions_; + /// Tree size (at last check) + int treeSize_; + /// Depth above which want to explore first + int breadthDepth_; + /// Chosen node from estimated (-1 is off) + int startNodeNumber_; + /// Node number when dive started + int afterNodeNumber_; + /// Indicates doing setup for diving + bool setupForDiving_ ; +}; + +#endif //CbcCompareDefault_H + diff --git a/thirdparty/linux/include/coin/CbcCompareDepth.hpp b/thirdparty/linux/include/coin/CbcCompareDepth.hpp new file mode 100644 index 0000000..5fe5073 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareDepth.hpp @@ -0,0 +1,47 @@ +// $Id: CbcCompareDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/24/09 carved out of CbcCompareActual + +#ifndef CbcCompareDepth_H +#define CbcCompareDepth_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +class CbcModel; +// This is default before first solution +class CbcCompareDepth : public CbcCompareBase { +public: + // Default Constructor + CbcCompareDepth () ; + + ~CbcCompareDepth(); + // Copy constructor + CbcCompareDepth ( const CbcCompareDepth &rhs); + + // Assignment operator + CbcCompareDepth & operator=( const CbcCompareDepth& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + // This returns true if the depth of node y is greater than depth of node x + virtual bool test (CbcNode * x, CbcNode * y); +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCompareEstimate.hpp b/thirdparty/linux/include/coin/CbcCompareEstimate.hpp new file mode 100644 index 0000000..8f6c056 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareEstimate.hpp @@ -0,0 +1,48 @@ +// $Id: CbcCompareEstimate.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareEstimate_H +#define CbcCompareEstimate_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +class CbcModel; + +/* This is when rounding is being done +*/ +class CbcCompareEstimate : public CbcCompareBase { +public: + // Default Constructor + CbcCompareEstimate () ; + ~CbcCompareEstimate() ; + // Copy constructor + CbcCompareEstimate ( const CbcCompareEstimate &rhs); + + // Assignment operator + CbcCompareEstimate & operator=( const CbcCompareEstimate& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + virtual bool test (CbcNode * x, CbcNode * y) ; +}; + + +#endif //CbcCompareEstimate_H + diff --git a/thirdparty/linux/include/coin/CbcCompareObjective.hpp b/thirdparty/linux/include/coin/CbcCompareObjective.hpp new file mode 100644 index 0000000..a3f6613 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCompareObjective.hpp @@ -0,0 +1,49 @@ +// $Id: CbcCompareObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareObjective_H +#define CbcCompareObjective_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" + +class CbcModel; + +class CbcCompareObjective : public CbcCompareBase { +public: + // Default Constructor + CbcCompareObjective (); + + virtual ~CbcCompareObjective(); + // Copy constructor + CbcCompareObjective ( const CbcCompareObjective &rhs); + + // Assignment operator + CbcCompareObjective & operator=( const CbcCompareObjective& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + /* This returns true if objective value of node y is less than + objective value of node x */ + virtual bool test (CbcNode * x, CbcNode * y); +}; + +#endif //CbcCompareObjective_H + diff --git a/thirdparty/linux/include/coin/CbcConfig.h b/thirdparty/linux/include/coin/CbcConfig.h new file mode 100644 index 0000000..4794473 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcConfig.h @@ -0,0 +1,14 @@ +/* src/config_cbc.h. Generated by configure. */ +/* src/config_cbc.h.in. */ + +/* Version number of project */ +#define CBC_VERSION "2.9.6" + +/* Major Version number of project */ +#define CBC_VERSION_MAJOR 2 + +/* Minor Version number of project */ +#define CBC_VERSION_MINOR 9 + +/* Release Version number of project */ +#define CBC_VERSION_RELEASE 6 diff --git a/thirdparty/linux/include/coin/CbcConsequence.hpp b/thirdparty/linux/include/coin/CbcConsequence.hpp new file mode 100644 index 0000000..f64a8bc --- /dev/null +++ b/thirdparty/linux/include/coin/CbcConsequence.hpp @@ -0,0 +1,49 @@ +// $Id: CbcConsequence.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcConsequence_H +#define CbcConsequence_H + +class OsiSolverInterface; + +/** Abstract base class for consequent bounds. + When a variable is branched on it normally interacts with other variables by + means of equations. There are cases where we want to step outside LP and do something + more directly e.g. fix bounds. This class is for that. + + At present it need not be virtual as only instance is CbcFixVariable, but ... + + */ + +class CbcConsequence { + +public: + + // Default Constructor + CbcConsequence (); + + // Copy constructor + CbcConsequence ( const CbcConsequence & rhs); + + // Assignment operator + CbcConsequence & operator=( const CbcConsequence & rhs); + + /// Clone + virtual CbcConsequence * clone() const = 0; + + /// Destructor + virtual ~CbcConsequence (); + + /** Apply to an LP solver. Action depends on state + */ + virtual void applyToSolver(OsiSolverInterface * solver, int state) const = 0; + +protected: +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCountRowCut.hpp b/thirdparty/linux/include/coin/CbcCountRowCut.hpp new file mode 100644 index 0000000..73eac08 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCountRowCut.hpp @@ -0,0 +1,168 @@ +/* $Id: CbcCountRowCut.hpp 2094 2014-11-18 11:15:36Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCountRowCut_H +#define CbcCountRowCut_H + + +class OsiCuts; +class OsiRowCut; +class CbcNodeInfo; + +//############################################################################# +/** \brief OsiRowCut augmented with bookkeeping + + CbcCountRowCut is an OsiRowCut object augmented with bookkeeping + information: a reference count and information that specifies the + the generator that created the cut and the node to which it's associated. + + The general principles for handling the reference count are as follows: + <ul> + <li> Once it's determined how the node will branch, increment the + reference count under the assumption that all children will use + all cuts currently tight at the node and will survive to be placed + in the search tree. + <li> As this assumption is proven incorrect (a cut becomes loose, or a + child is fathomed), decrement the reference count accordingly. + </ul> + When all possible uses of a cut have been demonstrated to be unnecessary, + the reference count (#numberPointingToThis_) will fall to zero. The + CbcCountRowCut object (and its included OsiRowCut object) are then deleted. +*/ + +class CbcCountRowCut : public OsiRowCut { + +public: + + /** @name Constructors & destructors */ + //@{ + + /// Default Constructor + CbcCountRowCut (); + + /// `Copy' constructor using an OsiRowCut + CbcCountRowCut ( const OsiRowCut &); + + /// `Copy' constructor using an OsiRowCut and an CbcNodeInfo + CbcCountRowCut(const OsiRowCut &, CbcNodeInfo *, int whichOne, + int whichGenerator = -1, int numberPointingToThis = 0); + + /** Destructor + + \note The destructor will reach out (via #owner_) and NULL the + reference to the cut in the owner's + \link CbcNodeInfo::cuts_ cuts_ \endlink list. + */ + virtual ~CbcCountRowCut (); + //@} + + /// Increment the number of references + void increment(int change = 1); + + /// Decrement the number of references and return the number left. + int decrement(int change = 1); + + /** \brief Set the information associating this cut with a node + + An CbcNodeInfo object and an index in the cut set of the node. + For locally valid cuts, the node will be the search tree node where the + cut was generated. For globally valid cuts, it's the node where the cut + was activated. + */ + void setInfo(CbcNodeInfo *, int whichOne); + + /// Number of other CbcNodeInfo objects pointing to this row cut + inline int numberPointingToThis() { + return numberPointingToThis_; + } + + /// Which generator for cuts - as user order + inline int whichCutGenerator() const { + return whichCutGenerator_; + } + + /// Returns true if can drop cut if slack basic + bool canDropCut(const OsiSolverInterface * solver, int row) const; + +#ifdef CHECK_CUT_COUNTS + // Just for printing sanity checks + int tempNumber_; +#endif + +private: + + /// Standard copy is illegal (reference counts would be incorrect) + CbcCountRowCut(const CbcCountRowCut &); + + /// Standard assignment is illegal (reference counts would be incorrect) + CbcCountRowCut & operator=(const CbcCountRowCut& rhs); + + /// Backward pointer to owning CbcNodeInfo + CbcNodeInfo * owner_; + + /// Index of cut in owner's cut set + /// (\link CbcNodeInfo::cuts_ cuts_ \endlink). + int ownerCut_; + + /// Number of other CbcNodeInfo objects pointing to this cut + int numberPointingToThis_; + + /** Which generator created this cut + (add 10000 if globally valid) + if -1 then from global cut pool + -2 cut branch + -3 unknown + */ + int whichCutGenerator_; + +}; +/** + Really for Conflict cuts to - + a) stop duplicates + b) allow half baked cuts + The whichRow_ field in OsiRowCut2 is used for a type + 0 - normal + 1 - processed cut (conflict) + 2 - unprocessed cut i.e. dual ray computation +*/ +// for hashing +typedef struct { + int index, next; +} CoinHashLink; +class CbcRowCuts { +public: + + CbcRowCuts(int initialMaxSize=0, int hashMultiplier=4 ); + ~CbcRowCuts(); + CbcRowCuts(const CbcRowCuts& rhs); + CbcRowCuts& operator=(const CbcRowCuts& rhs); + inline OsiRowCut2 * cut(int sequence) const + { return rowCut_[sequence];} + inline int numberCuts() const + { return numberCuts_;} + inline int sizeRowCuts() const + { return numberCuts_;} + inline OsiRowCut * rowCutPtr(int sequence) + { return rowCut_[sequence];} + void eraseRowCut(int sequence); + // Return 0 if added, 1 if not, -1 if not added because of space + int addCutIfNotDuplicate(const OsiRowCut & cut,int whichType=0); + // Return 0 if added, 1 if not, -1 if not added because of space + int addCutIfNotDuplicateWhenGreedy(const OsiRowCut & cut,int whichType=0); + // Add in cuts as normal cuts (and delete) + void addCuts(OsiCuts & cs); + // Truncate + void truncate(int numberAfter); +private: + OsiRowCut2 ** rowCut_; + /// Hash table + CoinHashLink *hash_; + int size_; + int hashMultiplier_; + int numberCuts_; + int lastHash_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcCutGenerator.hpp b/thirdparty/linux/include/coin/CbcCutGenerator.hpp new file mode 100644 index 0000000..f07142e --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCutGenerator.hpp @@ -0,0 +1,482 @@ +/* $Id: CbcCutGenerator.hpp 2081 2014-09-25 11:31:17Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCutGenerator_H +#define CbcCutGenerator_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" +#include "CbcCutModifier.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; + +//############################################################################# + +/** Interface between Cbc and Cut Generation Library. + + \c CbcCutGenerator is intended to provide an intelligent interface between + Cbc and the cutting plane algorithms in the CGL. A \c CbcCutGenerator is + bound to a \c CglCutGenerator and to an \c CbcModel. It contains parameters + which control when and how the \c generateCuts method of the + \c CglCutGenerator will be called. + + The builtin decision criteria available to use when deciding whether to + generate cuts are limited: every <i>X</i> nodes, when a solution is found, + and when a subproblem is found to be infeasible. The idea is that the class + will grow more intelligent with time. + + \todo Add a pointer to function member which will allow a client to install + their own decision algorithm to decide whether or not to call the CGL + \p generateCuts method. Create a default decision method that looks + at the builtin criteria. + + \todo It strikes me as not good that generateCuts contains code specific to + individual CGL algorithms. Another set of pointer to function members, + so that the client can specify the cut generation method as well as + pre- and post-generation methods? Taken a bit further, should this + class contain a bunch of pointer to function members, one for each + of the places where the cut generator might be referenced? + Initialization, root node, search tree node, discovery of solution, + and termination all come to mind. Initialization and termination would + also be useful for instrumenting cbc. +*/ + +class CbcCutGenerator { + +public: + + /** \name Generate Cuts */ + //@{ + /** Generate cuts for the client model. + + Evaluate the state of the client model and decide whether to generate cuts. + The generated cuts are inserted into and returned in the collection of cuts + \p cs. + + If \p fullScan is !=0, the generator is obliged to call the CGL + \c generateCuts routine. Otherwise, it is free to make a local decision. + Negative fullScan says things like at integer solution + The current implementation uses \c whenCutGenerator_ to decide. + + The routine returns true if reoptimisation is needed (because the state of + the solver interface has been modified). + + If node then can find out depth + */ + bool generateCuts( OsiCuts &cs, int fullScan, OsiSolverInterface * solver, + CbcNode * node); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CbcCutGenerator (); + + /// Normal constructor + CbcCutGenerator(CbcModel * model, CglCutGenerator * generator, + int howOften = 1, const char * name = NULL, + bool normal = true, bool atSolution = false, + bool infeasible = false, int howOftenInsub = -100, + int whatDepth = -1, int whatDepthInSub = -1, int switchOffIfLessThan = 0); + + /// Copy constructor + CbcCutGenerator (const CbcCutGenerator &); + + /// Assignment operator + CbcCutGenerator & operator=(const CbcCutGenerator& rhs); + + /// Destructor + ~CbcCutGenerator (); + //@} + + /**@name Gets and sets */ + //@{ + /** Set the client model. + + In addition to setting the client model, refreshModel also calls + the \c refreshSolver method of the CglCutGenerator object. + */ + void refreshModel(CbcModel * model); + + /// return name of generator + inline const char * cutGeneratorName() const { + return generatorName_; + } + + /// Create C++ lines to show how to tune + void generateTuning( FILE * fp); + /** Set the cut generation interval + + Set the number of nodes evaluated between calls to the Cgl object's + \p generateCuts routine. + + If \p value is positive, cuts will always be generated at the specified + interval. + If \p value is negative, cuts will initially be generated at the specified + interval, but Cbc may adjust the value depending on the success of cuts + produced by this generator. + + A value of -100 disables the generator, while a value of -99 means + just at root. + */ + void setHowOften(int value) ; + + /// Get the cut generation interval. + inline int howOften() const { + return whenCutGenerator_; + } + /// Get the cut generation interval.in sub tree + inline int howOftenInSub() const { + return whenCutGeneratorInSub_; + } + /// Get level of cut inaccuracy (0 means exact e.g. cliques) + inline int inaccuracy() const { + return inaccuracy_; + } + /// Set level of cut inaccuracy (0 means exact e.g. cliques) + inline void setInaccuracy(int level) { + inaccuracy_ = level; + } + + /** Set the cut generation depth + + Set the depth criterion for calls to the Cgl object's + \p generateCuts routine. Only active if > 0. + + If whenCutGenerator is positive and this is positive then this overrides. + If whenCutGenerator is -1 then this is used as criterion if any cuts + were generated at root node. + If whenCutGenerator is anything else this is ignored. + */ + void setWhatDepth(int value) ; + /// Set the cut generation depth in sub tree + void setWhatDepthInSub(int value) ; + /// Get the cut generation depth criterion. + inline int whatDepth() const { + return depthCutGenerator_; + } + /// Get the cut generation depth criterion.in sub tree + inline int whatDepthInSub() const { + return depthCutGeneratorInSub_; + } + /// Set maximum number of times to enter + inline void setMaximumTries(int value) + { maximumTries_ = value;} + /// Get maximum number of times to enter + inline int maximumTries() const + { return maximumTries_;} + + /// Get switches + inline int switches() const { + return switches_; + } + /// Set switches (for copying from virgin state) + inline void setSwitches(int value) { + switches_ = value; + } + /// Get whether the cut generator should be called in the normal place + inline bool normal() const { + return (switches_&1) != 0; + } + /// Set whether the cut generator should be called in the normal place + inline void setNormal(bool value) { + switches_ &= ~1; + switches_ |= value ? 1 : 0; + } + /// Get whether the cut generator should be called when a solution is found + inline bool atSolution() const { + return (switches_&2) != 0; + } + /// Set whether the cut generator should be called when a solution is found + inline void setAtSolution(bool value) { + switches_ &= ~2; + switches_ |= value ? 2 : 0; + } + /** Get whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline bool whenInfeasible() const { + return (switches_&4) != 0; + } + /** Set whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline void setWhenInfeasible(bool value) { + switches_ &= ~4; + switches_ |= value ? 4 : 0; + } + /// Get whether the cut generator is being timed + inline bool timing() const { + return (switches_&64) != 0; + } + /// Set whether the cut generator is being timed + inline void setTiming(bool value) { + switches_ &= ~64; + switches_ |= value ? 64 : 0; + timeInCutGenerator_ = 0.0; + } + /// Return time taken in cut generator + inline double timeInCutGenerator() const { + return timeInCutGenerator_; + } + inline void incrementTimeInCutGenerator(double value) { + timeInCutGenerator_ += value; + } + /// Get the \c CglCutGenerator corresponding to this \c CbcCutGenerator. + inline CglCutGenerator * generator() const { + return generator_; + } + /// Number times cut generator entered + inline int numberTimesEntered() const { + return numberTimes_; + } + inline void setNumberTimesEntered(int value) { + numberTimes_ = value; + } + inline void incrementNumberTimesEntered(int value = 1) { + numberTimes_ += value; + } + /// Total number of cuts added + inline int numberCutsInTotal() const { + return numberCuts_; + } + inline void setNumberCutsInTotal(int value) { + numberCuts_ = value; + } + inline void incrementNumberCutsInTotal(int value = 1) { + numberCuts_ += value; + } + /// Total number of elements added + inline int numberElementsInTotal() const { + return numberElements_; + } + inline void setNumberElementsInTotal(int value) { + numberElements_ = value; + } + inline void incrementNumberElementsInTotal(int value = 1) { + numberElements_ += value; + } + /// Total number of column cuts + inline int numberColumnCuts() const { + return numberColumnCuts_; + } + inline void setNumberColumnCuts(int value) { + numberColumnCuts_ = value; + } + inline void incrementNumberColumnCuts(int value = 1) { + numberColumnCuts_ += value; + } + /// Total number of cuts active after (at end of n cut passes at each node) + inline int numberCutsActive() const { + return numberCutsActive_; + } + inline void setNumberCutsActive(int value) { + numberCutsActive_ = value; + } + inline void incrementNumberCutsActive(int value = 1) { + numberCutsActive_ += value; + } + inline void setSwitchOffIfLessThan(int value) { + switchOffIfLessThan_ = value; + } + inline int switchOffIfLessThan() const { + return switchOffIfLessThan_; + } + /// Say if optimal basis needed + inline bool needsOptimalBasis() const { + return (switches_&128) != 0; + } + /// Set if optimal basis needed + inline void setNeedsOptimalBasis(bool yesNo) { + switches_ &= ~128; + switches_ |= yesNo ? 128 : 0; + } + /// Whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline bool mustCallAgain() const { + return (switches_&8) != 0; + } + /// Set whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline void setMustCallAgain(bool yesNo) { + switches_ &= ~8; + switches_ |= yesNo ? 8 : 0; + } + /// Whether generator switched off for moment + inline bool switchedOff() const { + return (switches_&16) != 0; + } + /// Set whether generator switched off for moment + inline void setSwitchedOff(bool yesNo) { + switches_ &= ~16; + switches_ |= yesNo ? 16 : 0; + } + /// Whether last round of cuts did little + inline bool ineffectualCuts() const { + return (switches_&512) != 0; + } + /// Set whether last round of cuts did little + inline void setIneffectualCuts(bool yesNo) { + switches_ &= ~512; + switches_ |= yesNo ? 512 : 0; + } + /// Whether to use if any cuts generated + inline bool whetherToUse() const { + return (switches_&1024) != 0; + } + /// Set whether to use if any cuts generated + inline void setWhetherToUse(bool yesNo) { + switches_ &= ~1024; + switches_ |= yesNo ? 1024 : 0; + } + /// Whether in must call again mode (or after others) + inline bool whetherInMustCallAgainMode() const { + return (switches_&2048) != 0; + } + /// Set whether in must call again mode (or after others) + inline void setWhetherInMustCallAgainMode(bool yesNo) { + switches_ &= ~2048; + switches_ |= yesNo ? 2048 : 0; + } + /// Whether to call at end + inline bool whetherCallAtEnd() const { + return (switches_&4096) != 0; + } + /// Set whether to call at end + inline void setWhetherCallAtEnd(bool yesNo) { + switches_ &= ~4096; + switches_ |= yesNo ? 4096 : 0; + } + /// Whether needs refresh on copy + inline bool needsRefresh() const { + return (switches_&8192) != 0; + } + /// Set whether needs refresh on copy + inline void setNeedsRefresh(bool yesNo) { + switches_ &= ~8192; + switches_ |= yesNo ? 8192 : 0; + } + /// Number of cuts generated at root + inline int numberCutsAtRoot() const { + return numberCutsAtRoot_; + } + inline void setNumberCutsAtRoot(int value) { + numberCutsAtRoot_ = value; + } + /// Number of cuts active at root + inline int numberActiveCutsAtRoot() const { + return numberActiveCutsAtRoot_; + } + inline void setNumberActiveCutsAtRoot(int value) { + numberActiveCutsAtRoot_ = value; + } + /// Number of short cuts at root + inline int numberShortCutsAtRoot() const { + return numberShortCutsAtRoot_; + } + inline void setNumberShortCutsAtRoot(int value) { + numberShortCutsAtRoot_ = value; + } + /// Set model + inline void setModel(CbcModel * model) { + model_ = model; + } + /// Whether global cuts at root + inline bool globalCutsAtRoot() const { + return (switches_&32) != 0; + } + /// Set whether global cuts at root + inline void setGlobalCutsAtRoot(bool yesNo) { + switches_ &= ~32; + switches_ |= yesNo ? 32 : 0; + } + /// Whether global cuts + inline bool globalCuts() const { + return (switches_&256) != 0; + } + /// Set whether global cuts + inline void setGlobalCuts(bool yesNo) { + switches_ &= ~256; + switches_ |= yesNo ? 256 : 0; + } + /// Add in statistics from other + void addStatistics(const CbcCutGenerator * other); + /// Scale back statistics by factor + void scaleBackStatistics(int factor); + //@} + +private: + /**@name Private gets and sets */ + //@{ + //@} + /// Saved cuts + OsiCuts savedCuts_; + /// Time in cut generator + double timeInCutGenerator_; + /// The client model + CbcModel *model_; + + // The CglCutGenerator object + CglCutGenerator * generator_; + + /// Name of generator + char * generatorName_; + + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine. + */ + int whenCutGenerator_; + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine in sub tree. + */ + int whenCutGeneratorInSub_; + /** If first pass at root produces fewer than this cuts then switch off + */ + int switchOffIfLessThan_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + */ + int depthCutGenerator_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + In sub tree. + */ + int depthCutGeneratorInSub_; + + /// Level of cut inaccuracy (0 means exact e.g. cliques) + int inaccuracy_; + /// Number times cut generator entered + int numberTimes_; + /// Total number of cuts added + int numberCuts_; + /// Total number of elements added + int numberElements_; + /// Total number of column cuts added + int numberColumnCuts_; + /// Total number of cuts active after (at end of n cut passes at each node) + int numberCutsActive_; + /// Number of cuts generated at root + int numberCutsAtRoot_; + /// Number of cuts active at root + int numberActiveCutsAtRoot_; + /// Number of short cuts at root + int numberShortCutsAtRoot_; + /// Switches - see gets and sets + int switches_; + /// Maximum number of times to enter + int maximumTries_; +}; + +// How often to do if mostly switched off (A) +# define SCANCUTS 1000 +// How often to do if mostly switched off (probing B) +# define SCANCUTS_PROBING 1000 + +#endif + diff --git a/thirdparty/linux/include/coin/CbcCutModifier.hpp b/thirdparty/linux/include/coin/CbcCutModifier.hpp new file mode 100644 index 0000000..726d615 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCutModifier.hpp @@ -0,0 +1,57 @@ +// $Id: CbcCutModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCutGenerator + +#ifndef CbcCutModifier_H +#define CbcCutModifier_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; +/** Abstract cut modifier base class + + In exotic circumstances - cuts may need to be modified + a) strengthened - changed + b) weakened - changed + c) deleted - set to NULL + d) unchanged +*/ + +class CbcCutModifier { +public: + /// Default Constructor + CbcCutModifier (); + + // Copy constructor + CbcCutModifier ( const CbcCutModifier &); + + /// Destructor + virtual ~CbcCutModifier(); + + /// Assignment + CbcCutModifier & operator=(const CbcCutModifier& rhs); +/// Clone + virtual CbcCutModifier * clone() const = 0; + + /** Returns + 0 unchanged + 1 strengthened + 2 weakened + 3 deleted + */ + virtual int modify(const OsiSolverInterface * solver, OsiRowCut & cut) = 0; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} +protected: + +}; + +#endif //CbcCutModifier_H + diff --git a/thirdparty/linux/include/coin/CbcCutSubsetModifier.hpp b/thirdparty/linux/include/coin/CbcCutSubsetModifier.hpp new file mode 100644 index 0000000..593fa62 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcCutSubsetModifier.hpp @@ -0,0 +1,66 @@ +// $Id: CbcCutSubsetModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCutGenerator + +#ifndef CbcCutSubsetModifier_H +#define CbcCutSubsetModifier_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" +#include "CbcCutModifier.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; +/** Simple cut modifier base class + + In exotic circumstances - cuts may need to be modified + a) strengthened - changed + b) weakened - changed + c) deleted - set to NULL + d) unchanged + + initially get rid of cuts with variables >= k + could weaken +*/ + +class CbcCutSubsetModifier : public CbcCutModifier { +public: + /// Default Constructor + CbcCutSubsetModifier (); + + /// Useful Constructor + CbcCutSubsetModifier (int firstOdd); + + // Copy constructor + CbcCutSubsetModifier ( const CbcCutSubsetModifier &); + + /// Destructor + virtual ~CbcCutSubsetModifier(); + + /// Assignment + CbcCutSubsetModifier & operator=(const CbcCutSubsetModifier& rhs); +/// Clone + virtual CbcCutModifier * clone() const ; + + /** Returns + 0 unchanged + 1 strengthened + 2 weakened + 3 deleted + */ + virtual int modify(const OsiSolverInterface * solver, OsiRowCut & cut) ; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} +protected: + /// data + /// First odd variable + int firstOdd_; +}; + +#endif //CbcCutSubsetModifier_H + diff --git a/thirdparty/linux/include/coin/CbcDummyBranchingObject.hpp b/thirdparty/linux/include/coin/CbcDummyBranchingObject.hpp new file mode 100644 index 0000000..b7e15c5 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcDummyBranchingObject.hpp @@ -0,0 +1,83 @@ +// $Id: CbcDummyBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcDummyBranchingObject_H +#define CbcDummyBranchingObject_H + +#include "CbcBranchBase.hpp" +/** Dummy branching object + + This object specifies a one-way dummy branch. + This is so one can carry on branching even when it looks feasible +*/ + +class CbcDummyBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcDummyBranchingObject (CbcModel * model = NULL); + + /// Copy constructor + CbcDummyBranchingObject ( const CbcDummyBranchingObject &); + + /// Assignment operator + CbcDummyBranchingObject & operator= (const CbcDummyBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcDummyBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Dummy branch + */ + virtual double branch(); + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return DummyBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcEventHandler.hpp b/thirdparty/linux/include/coin/CbcEventHandler.hpp new file mode 100644 index 0000000..cedc4b8 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcEventHandler.hpp @@ -0,0 +1,245 @@ +/* + Copyright (C) 2006, International Business Machines Corporation and others. + All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). + + $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ +*/ + +#ifndef CbcEventHandler_H +#define CbcEventHandler_H + +/*! \file CbcEventHandler.hpp + \brief Event handling for cbc + + This file contains the declaration of CbcEventHandler, used for event + handling in cbc. + + The central method is CbcEventHandler::event(). The default semantics of + this call are `ask for the action to take in reponse to this event'. The + call is made at the point in the code where the event occurs (<i>e.g.</i>, + when a solution is found, or when a node is added to or removed from the + search tree). The return value specifies the action to perform in response + to the event (<i>e.g.</i>, continue, or stop). + + This is a lazy class. Initially, it knows nothing about specific events, + and returns dfltAction_ for any event. This makes for a trivial constructor + and fast startup. The only place where the list of known events or actions + is hardwired is in the enum definitions for CbcEvent and CbcAction, + respectively. + + At the first call to setAction, a map is created to hold (Event,Action) + pairs, and this map will be consulted ever after. Events not in the map + will still return the default value. + + For serious extensions, derive a subclass and replace event() with a + function that suits you better. The function has access to the CbcModel + via a pointer held in the CbcEventHandler object, and can do as much + thinking as it likes before returning an answer. You can also print as + much information as you want. The model is held as a const, however, so + you can't alter reality. + + The design of the class deliberately matches ClpEventHandler, so that other + solvers can participate in cbc without breaking the patterns set by + clp-specific code. + +*/ + +#include <cstddef> +#include <map> + +/* May well already be declared, but can't hurt. */ + +class CbcModel ; + +/* + cvs/svn: $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ +*/ + +/*! \class CbcEventHandler + \brief Base class for Cbc event handling. + + Up front: We're not talking about unanticipated events here. We're talking + about anticipated events, in the sense that the code is going to make a call + to event() and is prepared to obey the return value that it receives. + + The general pattern for usage is as follows: + <ol> + <li> Create a CbcEventHandler object. This will be initialised with a set + of default actions for every recognised event. + + <li> Attach the event handler to the CbcModel object. + + <li> When execution reaches the point where an event occurs, call the + event handler as CbcEventHandler::event(the event). The return value + will specify what the code should do in response to the event. + </ol> + + The return value associated with an event can be changed at any time. +*/ + +class CbcEventHandler { + +public: + + /*! \brief Events known to cbc */ + + enum CbcEvent { /*! Processing of the current node is complete. */ + node = 200, + /*! A tree status interval has arrived. */ + treeStatus, + /*! A solution has been found. */ + solution, + /*! A heuristic solution has been found. */ + heuristicSolution, + /*! A solution will be found unless user takes action (first check). */ + beforeSolution1, + /*! A solution will be found unless user takes action (thorough check). */ + beforeSolution2, + /*! After failed heuristic. */ + afterHeuristic, + /*! On entry to small branch and bound. */ + smallBranchAndBound, + /*! After a pass of heuristic. */ + heuristicPass, + /*! When converting constraints to cuts. */ + convertToCuts, + /*! End of search. */ + endSearch + } ; + + /*! \brief Action codes returned by the event handler. + + Specific values are chosen to match ClpEventHandler return codes. + */ + + enum CbcAction { /*! Continue --- no action required. */ + noAction = -1, + /*! Stop --- abort the current run at the next opportunity. */ + stop = 0, + /*! Restart --- restart branch-and-cut search; do not undo root node + processing. + */ + restart, + /*! RestartRoot --- undo root node and start branch-and-cut afresh. */ + restartRoot, + /*! Add special cuts. */ + addCuts, + /*! Pretend solution never happened. */ + killSolution, + /*! Take action on modified data. */ + takeAction + + } ; + + /*! \brief Data type for event/action pairs */ + + typedef std::map<CbcEvent, CbcAction> eaMapPair ; + + + /*! \name Event Processing */ + //@{ + + /*! \brief Return the action to be taken for an event. + + Return the action that should be taken in response to the event passed as + the parameter. The default implementation simply reads a return code + from a map. + */ + virtual CbcAction event(CbcEvent whichEvent) ; + + /*! \brief Return the action to be taken for an event - and modify data. + + Return the action that should be taken in response to the event passed as + the parameter. The default implementation simply reads a return code + from a map. + */ + virtual CbcAction event(CbcEvent whichEvent, void * data) ; + + //@} + + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor. */ + + CbcEventHandler(CbcModel *model = 0 /* was NULL but 4.6 complains */) ; + + /*! \brief Copy constructor. */ + + CbcEventHandler(const CbcEventHandler &orig) ; + + /*! \brief Assignment. */ + + CbcEventHandler& operator=(const CbcEventHandler &rhs) ; + + /*! \brief Clone (virtual) constructor. */ + + virtual CbcEventHandler* clone() const ; + + /*! \brief Destructor. */ + + virtual ~CbcEventHandler() ; + + //@} + + /*! \name Set/Get methods */ + //@{ + + /*! \brief Set model. */ + + inline void setModel(CbcModel *model) { + model_ = model ; + } + + /*! \brief Get model. */ + + inline const CbcModel* getModel() const { + return model_ ; + } + + /*! \brief Set the default action */ + + inline void setDfltAction(CbcAction action) { + dfltAction_ = action ; + } + + /*! \brief Set the action code associated with an event */ + + inline void setAction(CbcEvent event, CbcAction action) { + if (eaMap_ == 0) { + eaMap_ = new eaMapPair ; + } + (*eaMap_)[event] = action ; + } + + //@} + + +protected: + + /*! \name Data members + + Protected (as opposed to private) to allow access by derived classes. + */ + //@{ + + /*! \brief Pointer to associated CbcModel */ + + CbcModel *model_ ; + + /*! \brief Default action */ + + CbcAction dfltAction_ ; + + /*! \brief Pointer to a map that holds non-default event/action pairs */ + + eaMapPair *eaMap_ ; + + //@} +} ; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcFathom.hpp b/thirdparty/linux/include/coin/CbcFathom.hpp new file mode 100644 index 0000000..8f934c9 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFathom.hpp @@ -0,0 +1,137 @@ +/* $Id: CbcFathom.hpp 1889 2013-04-07 13:46:46Z stefan $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFathom_H +#define CbcFathom_H +#include "CbcConfig.h" + +/* + This file contains two classes, CbcFathom and CbcOsiSolver. It's unclear why + they're in the same file. CbcOsiSolver is a base class for CbcLinked. + + --lh, 071031 -- +*/ + + +class CbcModel; + +//############################################################################# +/** Fathom base class. + + The idea is that after some branching the problem will be effectively smaller than + the original problem and maybe there will be a more specialized technique which can completely + fathom this branch quickly. + + One method is to presolve the problem to give a much smaller new problem and then do branch + and cut on that. Another might be dynamic programming. + + */ + +class CbcFathom { +public: + // Default Constructor + CbcFathom (); + + // Constructor with model - assumed before cuts + CbcFathom (CbcModel & model); + + virtual ~CbcFathom(); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Clone + virtual CbcFathom * clone() const = 0; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model) = 0; + + /** returns 0 if no fathoming attempted, 1 fully fathomed, + 2 incomplete search, 3 incomplete search but treat as complete. + If solution then newSolution will not be NULL and + will be freed by CbcModel. It is expected that the solution is better + than best so far but CbcModel will double check. + + If returns 3 then of course there is no guarantee of global optimum + */ + virtual int fathom(double *& newSolution) = 0; + + // Is this method possible + inline bool possible() const { + return possible_; + } + +protected: + + /// Model + CbcModel * model_; + /// Possible - if this method of fathoming can be used + bool possible_; +private: + + /// Illegal Assignment operator + CbcFathom & operator=(const CbcFathom& rhs); + +}; + +#include "OsiClpSolverInterface.hpp" + +//############################################################################# + +/** + +This is for codes where solver needs to know about CbcModel + Seems to provide only one value-added feature, a CbcModel object. + +*/ + +class CbcOsiSolver : public OsiClpSolverInterface { + +public: + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + CbcOsiSolver (); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + CbcOsiSolver (const CbcOsiSolver &); + + /// Assignment operator + CbcOsiSolver & operator=(const CbcOsiSolver& rhs); + + /// Destructor + virtual ~CbcOsiSolver (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Set Cbc Model + inline void setCbcModel(CbcModel * model) { + cbcModel_ = model; + } + /// Return Cbc Model + inline CbcModel * cbcModel() const { + return cbcModel_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name Private member data */ + //@{ + /// Pointer back to CbcModel + CbcModel * cbcModel_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/CbcFathomDynamicProgramming.hpp b/thirdparty/linux/include/coin/CbcFathomDynamicProgramming.hpp new file mode 100644 index 0000000..7f38987 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFathomDynamicProgramming.hpp @@ -0,0 +1,169 @@ +/* $Id: CbcFathomDynamicProgramming.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFathomDynamicProgramming_H +#define CbcFathomDynamicProgramming_H + +#include "CbcFathom.hpp" + +//############################################################################# +/** FathomDynamicProgramming class. + + The idea is that after some branching the problem will be effectively smaller than + the original problem and maybe there will be a more specialized technique which can completely + fathom this branch quickly. + + This is a dynamic programming implementation which is very fast for some + specialized problems. It expects small integral rhs, an all integer problem + and positive integral coefficients. At present it can not do general set covering + problems just set partitioning. It can find multiple optima for various rhs + combinations. + + The main limiting factor is size of state space. Each 1 rhs doubles the size of the problem. + 2 or 3 rhs quadruples, 4,5,6,7 by 8 etc. + */ + +class CbcFathomDynamicProgramming : public CbcFathom { +public: + // Default Constructor + CbcFathomDynamicProgramming (); + + // Constructor with model - assumed before cuts + CbcFathomDynamicProgramming (CbcModel & model); + // Copy constructor + CbcFathomDynamicProgramming(const CbcFathomDynamicProgramming & rhs); + + virtual ~CbcFathomDynamicProgramming(); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Clone + virtual CbcFathom * clone() const; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /** returns 0 if no fathoming attempted, 1 fully fathomed , + 2 incomplete search, 3 incomplete search but treat as complete. + If solution then newSolution will not be NULL and + will be freed by CbcModel. It is expected that the solution is better + than best so far but CbcModel will double check. + + If returns 3 then of course there is no guarantee of global optimum + */ + virtual int fathom(double *& newSolution); + + /// Maximum size allowed + inline int maximumSize() const { + return maximumSizeAllowed_; + } + inline void setMaximumSize(int value) { + maximumSizeAllowed_ = value; + } + /// Returns type of algorithm and sets up arrays + int checkPossible(int allowableSize = 0); + // set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /** Tries a column + returns true if was used in making any changes. + */ + bool tryColumn(int numberElements, const int * rows, + const double * coefficients, double cost, + int upper = COIN_INT_MAX); + /// Returns cost array + inline const double * cost() const { + return cost_; + } + /// Returns back array + inline const int * back() const { + return back_; + } + /// Gets bit pattern for target result + inline int target() const { + return target_; + } + /// Sets bit pattern for target result + inline void setTarget(int value) { + target_ = value; + } +private: + /// Does deleteions + void gutsOfDelete(); + + /** Adds one attempt of one column of type 0, + returns true if was used in making any changes + */ + bool addOneColumn0(int numberElements, const int * rows, + double cost); + /** Adds one attempt of one column of type 1, + returns true if was used in making any changes. + At present the user has to call it once for each possible value + */ + bool addOneColumn1(int numberElements, const int * rows, + const int * coefficients, double cost); + /** Adds one attempt of one column of type 1, + returns true if was used in making any changes. + At present the user has to call it once for each possible value. + This version is when there are enough 1 rhs to do faster + */ + bool addOneColumn1A(int numberElements, const int * rows, + const int * coefficients, double cost); + /// Gets bit pattern from original column + int bitPattern(int numberElements, const int * rows, + const int * coefficients); + /// Gets bit pattern from original column + int bitPattern(int numberElements, const int * rows, + const double * coefficients); + /// Fills in original column (dense) from bit pattern - returning number nonzero + int decodeBitPattern(int bitPattern, int * values, int numberRows); + +protected: + + /// Size of states (power of 2 unless just one constraint) + int size_; + /** Type - 0 coefficients and rhs all 1, + 1 - coefficients > 1 or rhs > 1 + */ + int type_; + /// Space for states + double * cost_; + /// Which state produced this cheapest one + int * back_; + /// Some rows may be satisified so we need a lookup + int * lookup_; + /// Space for sorted indices + int * indices_; + /// Number of active rows + int numberActive_; + /// Maximum size allowed + int maximumSizeAllowed_; + /// Start bit for each active row + int * startBit_; + /// Number bits for each active row + int * numberBits_; + /// Effective rhs + int * rhs_; + /// Space for sorted coefficients + int * coefficients_; + /// Target pattern + int target_; + /// Number of Non 1 rhs + int numberNonOne_; + /// Current bit pattern + int bitPattern_; + /// Current algorithm + int algorithm_; +private: + + /// Illegal Assignment operator + CbcFathomDynamicProgramming & operator=(const CbcFathomDynamicProgramming& rhs); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcFeasibilityBase.hpp b/thirdparty/linux/include/coin/CbcFeasibilityBase.hpp new file mode 100644 index 0000000..fe8181f --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFeasibilityBase.hpp @@ -0,0 +1,56 @@ +/* $Id: CbcFeasibilityBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFeasibilityBase_H +#define CbcFeasibilityBase_H + + +//############################################################################# +/* There are cases where the user wants to control how CBC sees the problems feasibility. + The user may want to examine the problem and say : + a) The default looks OK + b) Pretend this problem is Integer feasible + c) Pretend this problem is infeasible even though it looks feasible + + This simple class allows user to do that. + +*/ + +class CbcModel; +class CbcFeasibilityBase { +public: + // Default Constructor + CbcFeasibilityBase () {} + + /** + On input mode: + 0 - called after a solve but before any cuts + -1 - called after strong branching + Returns : + 0 - no opinion + -1 pretend infeasible + 1 pretend integer solution + */ + virtual int feasible(CbcModel * , int ) { + return 0; + } + + virtual ~CbcFeasibilityBase() {} + + // Copy constructor + CbcFeasibilityBase ( const CbcFeasibilityBase & ) {} + + // Assignment operator + CbcFeasibilityBase & operator=( const CbcFeasibilityBase& ) { + return *this; + } + + /// Clone + virtual CbcFeasibilityBase * clone() const { + return new CbcFeasibilityBase(*this); + } +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcFixVariable.hpp b/thirdparty/linux/include/coin/CbcFixVariable.hpp new file mode 100644 index 0000000..aa33509 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFixVariable.hpp @@ -0,0 +1,67 @@ +// $Id: CbcFixVariable.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcFixVariable_H +#define CbcFixVariable_H + +#include "CbcBranchBase.hpp" +/** Class for consequent bounds. + When a variable is branched on it normally interacts with other variables by + means of equations. There are cases where we want to step outside LP and do something + more directly e.g. fix bounds. This class is for that. + + A state of -9999 means at LB, +9999 means at UB, + others mean if fixed to that value. + + */ + +class CbcFixVariable : public CbcConsequence { + +public: + + // Default Constructor + CbcFixVariable (); + + // One useful Constructor + CbcFixVariable (int numberStates, const int * states, const int * numberNewLower, const int ** newLowerValue, + const int ** lowerColumn, + const int * numberNewUpper, const int ** newUpperValue, + const int ** upperColumn); + + // Copy constructor + CbcFixVariable ( const CbcFixVariable & rhs); + + // Assignment operator + CbcFixVariable & operator=( const CbcFixVariable & rhs); + + /// Clone + virtual CbcConsequence * clone() const; + + /// Destructor + virtual ~CbcFixVariable (); + + /** Apply to an LP solver. Action depends on state + */ + virtual void applyToSolver(OsiSolverInterface * solver, int state) const; + +protected: + /// Number of states + int numberStates_; + /// Values of integers for various states + int * states_; + /// Start of information for each state (setting new lower) + int * startLower_; + /// Start of information for each state (setting new upper) + int * startUpper_; + /// For each variable new bounds + double * newBound_; + /// Variable + int * variable_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcFollowOn.hpp b/thirdparty/linux/include/coin/CbcFollowOn.hpp new file mode 100644 index 0000000..ada5988 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFollowOn.hpp @@ -0,0 +1,207 @@ +// $Id: CbcFollowOn.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcFollowOn_H +#define CbcFollowOn_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a follow on class. + The idea of this is that in air-crew scheduling problems crew may fly in on flight A + and out on flight B or on some other flight. A useful branch is one which on one side + fixes all which go out on flight B to 0, while the other branch fixes all those that do NOT + go out on flight B to 0. + + This branching rule should be in addition to normal rules and have a high priority. +*/ + +class CbcFollowOn : public CbcObject { + +public: + + // Default Constructor + CbcFollowOn (); + + /** Useful constructor + */ + CbcFollowOn (CbcModel * model); + + // Copy constructor + CbcFollowOn ( const CbcFollowOn &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcFollowOn & operator=( const CbcFollowOn& rhs); + + // Destructor + ~CbcFollowOn (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// As some computation is needed in more than one place - returns row + virtual int gutsOfFollowOn(int & otherRow, int & preferredWay) const; + +protected: + /// data + /// Matrix + CoinPackedMatrix matrix_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Possible rhs (if 0 then not possible) + int * rhs_; +}; + +/** General Branching Object class. + Each way fixes some variables to lower bound + */ +class CbcFixingBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcFixingBranchingObject (); + + // Useful constructor + CbcFixingBranchingObject (CbcModel * model, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcFixingBranchingObject ( const CbcFixingBranchingObject &); + + // Assignment operator + CbcFixingBranchingObject & operator=( const CbcFixingBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcFixingBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return FollowOnBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + /// Number on down list + int numberDown_; + /// Number on up list + int numberUp_; + /// downList - variables to fix to lb on down branch + int * downList_; + /// upList - variables to fix to lb on up branch + int * upList_; +}; + +/** Define an idiotic idea class. + The idea of this is that we take some integer variables away from integer and + sum them with some randomness to get signed sum close to 0.5. We then can + branch to exclude that gap. + + This branching rule should be in addition to normal rules and have a high priority. +*/ + +class CbcIdiotBranch : public CbcObject { + +public: + + // Default Constructor + CbcIdiotBranch (); + + /** Useful constructor + */ + CbcIdiotBranch (CbcModel * model); + + // Copy constructor + CbcIdiotBranch ( const CbcIdiotBranch &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcIdiotBranch & operator=( const CbcIdiotBranch& rhs); + + // Destructor + ~CbcIdiotBranch (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Initialize for branching + virtual void initializeForBranching(CbcModel * ); +protected: + /// Build "cut" + OsiRowCut buildCut(const OsiBranchingInformation * info,int type,int & preferredWay) const; + /// data + /// Thread specific random number generator + mutable CoinThreadRandom randomNumberGenerator_; + /// Saved version of thread specific random number generator + mutable CoinThreadRandom savedRandomNumberGenerator_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcFullNodeInfo.hpp b/thirdparty/linux/include/coin/CbcFullNodeInfo.hpp new file mode 100644 index 0000000..c4704bd --- /dev/null +++ b/thirdparty/linux/include/coin/CbcFullNodeInfo.hpp @@ -0,0 +1,161 @@ +// $Id: CbcFullNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcFullNodeInfo_H +#define CbcFullNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +//############################################################################# +/** Information required to recreate the subproblem at this node + + When a subproblem is initially created, it is represented by a CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information needed while the subproblem remains live. + The CbcNode is deleted when the last branch arm has been evaluated. + + The CbcNodeInfo contains information required to maintain the branch-and-cut + search tree structure (links and reference counts) and to recreate the + subproblem for this node (basis, variable bounds, cutting planes). A + CbcNodeInfo object remains in existence until all nodes have been pruned from + the subtree rooted at this node. + + The principle used to maintain the reference count is that the reference + count is always the sum of all potential and actual children of the node. + Specifically, + <ul> + <li> Once it's determined how the node will branch, the reference count + is set to the number of potential children (<i>i.e.</i>, the number + of arms of the branch). + <li> As each child is created by CbcNode::branch() (converting a potential + child to the active subproblem), the reference count is decremented. + <li> If the child survives and will become a node in the search tree + (converting the active subproblem into an actual child), increment the + reference count. + </ul> + Notice that the active subproblem lives in a sort of limbo, neither a + potential or an actual node in the branch-and-cut tree. + + CbcNodeInfo objects come in two flavours. A CbcFullNodeInfo object contains + a full record of the information required to recreate a subproblem. + A CbcPartialNodeInfo object expresses this information in terms of + differences from the parent. +*/ + + +/** \brief Holds complete information for recreating a subproblem. + + A CbcFullNodeInfo object contains all necessary information (bounds, basis, + and cuts) required to recreate a subproblem. + + \todo While there's no explicit statement, the code often makes the implicit + assumption that an CbcFullNodeInfo structure will appear only at the + root node of the search tree. Things will break if this assumption + is violated. +*/ + +class CbcFullNodeInfo : public CbcNodeInfo { + +public: + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound information at node, + creates a new basis according to information at node, but with the size + passed in through basis, and adds any cuts to the addCuts array. + + \note The basis passed in via basis is solely a vehicle for passing in + the desired basis size. It will be deleted and a new basis returned. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const ; + + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ; + + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const ; + // Default Constructor + CbcFullNodeInfo (); + + /** Constructor from continuous or satisfied + */ + CbcFullNodeInfo (CbcModel * model, + int numberRowsAtContinuous); + + // Copy constructor + CbcFullNodeInfo ( const CbcFullNodeInfo &); + + // Destructor + ~CbcFullNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + /// Lower bounds + inline const double * lower() const { + return lower_; + } + /// Set a bound + inline void setColLower(int sequence, double value) + { lower_[sequence]=value;} + /// Mutable lower bounds + inline double * mutableLower() const { + return lower_; + } + /// Upper bounds + inline const double * upper() const { + return upper_; + } + /// Set a bound + inline void setColUpper(int sequence, double value) + { upper_[sequence]=value;} + /// Mutable upper bounds + inline double * mutableUpper() const { + return upper_; + } +protected: + // Data + /** Full basis + + This MUST BE A POINTER to avoid cutting extra information in derived + warm start classes. + */ + CoinWarmStartBasis *basis_; + int numberIntegers_; + // Bounds stored in full + double * lower_; + double * upper_; +private: + /// Illegal Assignment operator + CbcFullNodeInfo & operator=(const CbcFullNodeInfo& rhs); +}; +#endif //CbcFullNodeInfo_H + diff --git a/thirdparty/linux/include/coin/CbcGeneral.hpp b/thirdparty/linux/include/coin/CbcGeneral.hpp new file mode 100644 index 0000000..19436b3 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcGeneral.hpp @@ -0,0 +1,60 @@ +// $Id: CbcGeneral.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcGeneral_H +#define CbcGeneral_H + +#include "CbcBranchBase.hpp" +/** Define a catch all class. + This will create a list of subproblems +*/ + + +class CbcGeneral : public CbcObject { + +public: + + // Default Constructor + CbcGeneral (); + + /** Useful constructor + Just needs to point to model. + */ + CbcGeneral (CbcModel * model); + + // Copy constructor + CbcGeneral ( const CbcGeneral &); + + /// Clone + virtual CbcObject * clone() const = 0; + + // Assignment operator + CbcGeneral & operator=( const CbcGeneral& rhs); + + // Destructor + ~CbcGeneral (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion() = 0; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns) = 0; + +protected: + /// data +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcGeneralDepth.hpp b/thirdparty/linux/include/coin/CbcGeneralDepth.hpp new file mode 100644 index 0000000..0d9f817 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcGeneralDepth.hpp @@ -0,0 +1,279 @@ +// $Id: CbcGeneralDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcGeneralDepth_H +#define CbcGeneralDepth_H + +#include "CbcGeneral.hpp" +#include "CbcBranchBase.hpp" +#include "CbcSubProblem.hpp" + +#ifdef COIN_HAS_CLP + +/** Define a catch all class. + This will create a list of subproblems using partial evaluation +*/ +#include "ClpSimplex.hpp" +#include "ClpNode.hpp" + + +class CbcGeneralDepth : public CbcGeneral { + +public: + + // Default Constructor + CbcGeneralDepth (); + + /** Useful constructor + Just needs to point to model. + Initial version does evaluation to depth N + This is stored in CbcModel but may be + better here + */ + CbcGeneralDepth (CbcModel * model, int maximumDepth); + + // Copy constructor + CbcGeneralDepth ( const CbcGeneralDepth &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcGeneralDepth & operator=( const CbcGeneralDepth& rhs); + + // Destructor + ~CbcGeneralDepth (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Return maximum number of nodes + inline int maximumNodes() const { + return maximumNodes_; + } + /// Get maximum depth + inline int maximumDepth() const { + return maximumDepth_; + } + /// Set maximum depth + inline void setMaximumDepth(int value) { + maximumDepth_ = value; + } + /// Return number of nodes + inline int numberNodes() const { + return numberNodes_; + } + /// Get which solution + inline int whichSolution() const { + return whichSolution_; + } + /// Get ClpNode info + inline ClpNode * nodeInfo(int which) { + return nodeInfo_->nodeInfo_[which]; + } + + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Maximum depth + int maximumDepth_; + /// Maximum nodes + int maximumNodes_; + /// Which node has solution (or -1) + mutable int whichSolution_; + /// Number of valid nodes (including whichSolution_) + mutable int numberNodes_; + /// For solving nodes + mutable ClpNodeStuff * nodeInfo_; +}; +/** Branching object for general objects + + */ +class CbcNode; +class CbcGeneralBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcGeneralBranchingObject (); + + // Useful constructor + CbcGeneralBranchingObject (CbcModel * model); + + // Copy constructor + CbcGeneralBranchingObject ( const CbcGeneralBranchingObject &); + + // Assignment operator + CbcGeneralBranchingObject & operator=( const CbcGeneralBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcGeneralBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Double checks in case node can change its mind! + Can change objective etc */ + virtual void checkIsCutoff(double cutoff); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /// Fill in current objective etc + void state(double & objectiveValue, double & sumInfeasibilities, + int & numberUnsatisfied, int which) const; + /// Set CbcNode + inline void setNode(CbcNode * node) { + node_ = node; + } + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return GeneralDepthBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + /// Number of subproblems + inline int numberSubProblems() const { + return numberSubProblems_; + } + /// Decrement number left and return number + inline int decrementNumberLeft() { + numberSubLeft_--; + return numberSubLeft_; + } + /// Which node we want to use + inline int whichNode() const { + return whichNode_; + } + /// Set which node we want to use + inline void setWhichNode(int value) { + whichNode_ = value; + } + // Sub problem + const CbcSubProblem * subProblem(int which) const { + return subProblems_ + which; + } + +public: + /// data + // Sub problems + CbcSubProblem * subProblems_; + /// Node + CbcNode * node_; + /// Number of subproblems + int numberSubProblems_; + /// Number of subproblems left + int numberSubLeft_; + /// Which node we want to use (-1 for default) + int whichNode_; + /// Number of rows + int numberRows_; +}; +/** Branching object for general objects - just one + + */ +class CbcOneGeneralBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcOneGeneralBranchingObject (); + + // Useful constructor + CbcOneGeneralBranchingObject (CbcModel * model, + CbcGeneralBranchingObject * object, + int whichOne); + + // Copy constructor + CbcOneGeneralBranchingObject ( const CbcOneGeneralBranchingObject &); + + // Assignment operator + CbcOneGeneralBranchingObject & operator=( const CbcOneGeneralBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcOneGeneralBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Double checks in case node can change its mind! + Can change objective etc */ + virtual void checkIsCutoff(double cutoff); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return OneGeneralBranchingObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +public: + /// data + /// Object + CbcGeneralBranchingObject * object_; + /// Which one + int whichOne_; +}; +#endif //COIN_HAS_CLP +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristic.hpp b/thirdparty/linux/include/coin/CbcHeuristic.hpp new file mode 100644 index 0000000..32466c6 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristic.hpp @@ -0,0 +1,682 @@ +/* $Id: CbcHeuristic.hpp 2094 2014-11-18 11:15:36Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristic_H +#define CbcHeuristic_H + +#include <string> +#include <vector> +#include "CoinPackedMatrix.hpp" +#include "OsiCuts.hpp" +#include "CoinHelperFunctions.hpp" +#include "OsiBranchingObject.hpp" + +class OsiSolverInterface; + +class CbcModel; + +//############################################################################# + +class CbcHeuristicNodeList; +class CbcBranchingObject; + +/** A class describing the branching decisions that were made to get + to the node where a heuristic was invoked from */ + +class CbcHeuristicNode { +private: + void gutsOfConstructor(CbcModel& model); + CbcHeuristicNode(); + CbcHeuristicNode& operator=(const CbcHeuristicNode&); +private: + /// The number of branching decisions made + int numObjects_; + /** The indices of the branching objects. Note: an index may be + listed multiple times. E.g., a general integer variable that has + been branched on multiple times. */ + CbcBranchingObject** brObj_; +public: + CbcHeuristicNode(CbcModel& model); + + CbcHeuristicNode(const CbcHeuristicNode& rhs); + ~CbcHeuristicNode(); + double distance(const CbcHeuristicNode* node) const; + double minDistance(const CbcHeuristicNodeList& nodeList) const; + bool minDistanceIsSmall(const CbcHeuristicNodeList& nodeList, + const double threshold) const; + double avgDistance(const CbcHeuristicNodeList& nodeList) const; +}; + +class CbcHeuristicNodeList { +private: + void gutsOfDelete(); + void gutsOfCopy(const CbcHeuristicNodeList& rhs); +private: + std::vector<CbcHeuristicNode*> nodes_; +public: + CbcHeuristicNodeList() {} + CbcHeuristicNodeList(const CbcHeuristicNodeList& rhs); + CbcHeuristicNodeList& operator=(const CbcHeuristicNodeList& rhs); + ~CbcHeuristicNodeList(); + + void append(CbcHeuristicNode*& node); + void append(const CbcHeuristicNodeList& nodes); + inline const CbcHeuristicNode* node(int i) const { + return nodes_[i]; + } + inline int size() const { + return static_cast<int>(nodes_.size()); + } +}; + +//############################################################################# +/** Heuristic base class */ + +class CbcHeuristic { +private: + void gutsOfDelete() {} + void gutsOfCopy(const CbcHeuristic & rhs); + +public: + // Default Constructor + CbcHeuristic (); + + // Constructor with model - assumed before cuts + CbcHeuristic (CbcModel & model); + + // Copy constructor + CbcHeuristic ( const CbcHeuristic &); + + virtual ~CbcHeuristic(); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Assignment operator + CbcHeuristic & operator=(const CbcHeuristic& rhs); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model) = 0; + + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution) = 0; + + /** returns 0 if no solution, 1 if valid solution, -1 if just + returning an estimate of best possible solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if nonzero code) + This is called at same time as cut generators - so can add cuts + Default is do nothing + */ + virtual int solution2(double & /*objectiveValue*/, + double * /*newSolution*/, + OsiCuts & /*cs*/) { + return 0; + } + + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() {} + + /** Sets "when" flag - 0 off, 1 at root, 2 other than root, 3 always. + If 10 added then don't worry if validate says there are funny objects + as user knows it will be fine + */ + inline void setWhen(int value) { + when_ = value; + } + /// Gets "when" flag - 0 off, 1 at root, 2 other than root, 3 always + inline int when() const { + return when_; + } + + /// Sets number of nodes in subtree (default 200) + inline void setNumberNodes(int value) { + numberNodes_ = value; + } + /// Gets number of nodes in a subtree (default 200) + inline int numberNodes() const { + return numberNodes_; + } + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + */ + inline void setSwitches(int value) { + switches_ = value; + } + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + 65536 bit and above used for temporary communication + */ + inline int switches() const { + return switches_; + } + /// Whether to exit at once on gap + bool exitNow(double bestObjective) const; + /// Sets feasibility pump options (-1 is off) + inline void setFeasibilityPumpOptions(int value) { + feasibilityPumpOptions_ = value; + } + /// Gets feasibility pump options (-1 is off) + inline int feasibilityPumpOptions() const { + return feasibilityPumpOptions_; + } + /// Just set model - do not do anything else + inline void setModelOnly(CbcModel * model) { + model_ = model; + } + + + /// Sets fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound (default 1.0) + inline void setFractionSmall(double value) { + fractionSmall_ = value; + } + /// Gets fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound (default 1.0) + inline double fractionSmall() const { + return fractionSmall_; + } + /// Get how many solutions the heuristic thought it got + inline int numberSolutionsFound() const { + return numberSolutionsFound_; + } + /// Increment how many solutions the heuristic thought it got + inline void incrementNumberSolutionsFound() { + numberSolutionsFound_++; + } + + /** Do mini branch and bound - return + 0 not finished - no solution + 1 not finished - solution + 2 finished - no solution + 3 finished - solution + (could add global cut if finished) + -1 returned on size + -2 time or user event + */ + int smallBranchAndBound(OsiSolverInterface * solver, int numberNodes, + double * newSolution, double & newSolutionValue, + double cutoff , std::string name) const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /// Create C++ lines to get to current state - does work for base class + void generateCpp( FILE * fp, const char * heuristic) ; + /// Returns true if can deal with "odd" problems e.g. sos type 2 + virtual bool canDealWithOdd() const { + return false; + } + /// return name of heuristic + inline const char *heuristicName() const { + return heuristicName_.c_str(); + } + /// set name of heuristic + inline void setHeuristicName(const char *name) { + heuristicName_ = name; + } + /// Set random number generator seed + void setSeed(int value); + /// Get random number generator seed + int getSeed() const; + /// Sets decay factor (for howOften) on failure + inline void setDecayFactor(double value) { + decayFactor_ = value; + } + /// Set input solution + void setInputSolution(const double * solution, double objValue); + /* Runs if bit set + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + inline void setWhereFrom(int value) { + whereFrom_ = value; + } + inline int whereFrom() const { + return whereFrom_; + } + /** Upto this depth we call the tree shallow and the heuristic can be called + multiple times. That is, the test whether the current node is far from + the others where the jeuristic was invoked will not be done, only the + frequency will be tested. After that depth the heuristic will can be + invoked only once per node, right before branching. That's when it'll be + tested whether the heur should run at all. */ + inline void setShallowDepth(int value) { + shallowDepth_ = value; + } + /** How often to invoke the heuristics in the shallow part of the tree */ + inline void setHowOftenShallow(int value) { + howOftenShallow_ = value; + } + /** How "far" should this node be from every other where the heuristic was + run in order to allow the heuristic to run in this node, too. Currently + this is tested, but we may switch to avgDistanceToRun_ in the future. */ + inline void setMinDistanceToRun(int value) { + minDistanceToRun_ = value; + } + + /** Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + virtual bool shouldHeurRun(int whereFrom); + /** Check whether the heuristic should run this time */ + bool shouldHeurRun_randomChoice(); + void debugNodes(); + void printDistanceToNodes(); + /// how many times the heuristic has actually run + inline int numRuns() const { + return numRuns_; + } + + /// How many times the heuristic could run + inline int numCouldRun() const { + return numCouldRun_; + } + /*! \brief Clone, but ... + + If type is + - 0 clone the solver for the model, + - 1 clone the continuous solver for the model + - Add 2 to say without integer variables which are at low priority + - Add 4 to say quite likely infeasible so give up easily (clp only). + */ + OsiSolverInterface * cloneBut(int type); +protected: + + /// Model + CbcModel * model_; + /// When flag - 0 off, 1 at root, 2 other than root, 3 always + int when_; + /// Number of nodes in any sub tree + int numberNodes_; + /** Feasibility pump options , -1 is off + >=0 for feasibility pump itself + -2 quick proximity search + -3 longer proximity search + */ + int feasibilityPumpOptions_; + /// Fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound + mutable double fractionSmall_; + /// Thread specific random number generator + CoinThreadRandom randomNumberGenerator_; + /// Name for printing + std::string heuristicName_; + + /// How often to do (code can change) + mutable int howOften_; + /// How much to increase how often + double decayFactor_; + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + */ + mutable int switches_; + /* Runs if bit set + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + int whereFrom_; + /** Upto this depth we call the tree shallow and the heuristic can be called + multiple times. That is, the test whether the current node is far from + the others where the jeuristic was invoked will not be done, only the + frequency will be tested. After that depth the heuristic will can be + invoked only once per node, right before branching. That's when it'll be + tested whether the heur should run at all. */ + int shallowDepth_; + /** How often to invoke the heuristics in the shallow part of the tree */ + int howOftenShallow_; + /** How many invocations happened within the same node when in a shallow + part of the tree. */ + int numInvocationsInShallow_; + /** How many invocations happened when in the deep part of the tree. For + every node we count only one invocation. */ + int numInvocationsInDeep_; + /** After how many deep invocations was the heuristic run last time */ + int lastRunDeep_; + /// how many times the heuristic has actually run + int numRuns_; + /** How "far" should this node be from every other where the heuristic was + run in order to allow the heuristic to run in this node, too. Currently + this is tested, but we may switch to avgDistanceToRun_ in the future. */ + int minDistanceToRun_; + + /// The description of the nodes where this heuristic has been applied + CbcHeuristicNodeList runNodes_; + + /// How many times the heuristic could run + int numCouldRun_; + + /// How many solutions the heuristic thought it got + int numberSolutionsFound_; + + /// How many nodes the heuristic did this go + mutable int numberNodesDone_; + + // Input solution - so can be used as seed + double * inputSolution_; + + +#ifdef JJF_ZERO + /// Lower bounds of last node where the heuristic found a solution + double * lowerBoundLastNode_; + /// Upper bounds of last node where the heuristic found a solution + double * upperBoundLastNode_; +#endif +}; +/** Rounding class + */ + +class CbcRounding : public CbcHeuristic { +public: + + // Default Constructor + CbcRounding (); + + // Constructor with model - assumed before cuts + CbcRounding (CbcModel & model); + + // Copy constructor + CbcRounding ( const CbcRounding &); + + // Destructor + ~CbcRounding (); + + /// Assignment operator + CbcRounding & operator=(const CbcRounding& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + Use solutionValue rather than solvers one + */ + virtual int solution(double & objectiveValue, + double * newSolution, + double solutionValue); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + + /// Set seed + void setSeed(int value) { + seed_ = value; + } + /** Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + virtual bool shouldHeurRun(int whereFrom); + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Original matrix by + CoinPackedMatrix matrixByRow_; + + // Down locks + unsigned short * down_; + + // Up locks + unsigned short * up_; + + // Equality locks + unsigned short * equal_; + + // Seed for random stuff + int seed_; +}; + +/** Partial solution class + If user knows a partial solution this tries to get an integer solution + it uses hotstart information + */ + +class CbcHeuristicPartial : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicPartial (); + + /** Constructor with model - assumed before cuts + Fixes all variables with priority <= given + and does given number of nodes + */ + CbcHeuristicPartial (CbcModel & model, int fixPriority = 10000, int numberNodes = 200); + + // Copy constructor + CbcHeuristicPartial ( const CbcHeuristicPartial &); + + // Destructor + ~CbcHeuristicPartial (); + + /// Assignment operator + CbcHeuristicPartial & operator=(const CbcHeuristicPartial& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + + /// Set priority level + void setFixPriority(int value) { + fixPriority_ = value; + } + + /** Check whether the heuristic should run at all */ + virtual bool shouldHeurRun(int whereFrom); + +protected: + // Data + + // All variables with abs priority <= this will be fixed + int fixPriority_; +}; + +/** heuristic - just picks up any good solution + found by solver - see OsiBabSolver + */ + +class CbcSerendipity : public CbcHeuristic { +public: + + // Default Constructor + CbcSerendipity (); + + /* Constructor with model + */ + CbcSerendipity (CbcModel & model); + + // Copy constructor + CbcSerendipity ( const CbcSerendipity &); + + // Destructor + ~CbcSerendipity (); + + /// Assignment operator + CbcSerendipity & operator=(const CbcSerendipity& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + +protected: +}; + +/** Just One class - this chooses one at random + */ + +class CbcHeuristicJustOne : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicJustOne (); + + // Constructor with model - assumed before cuts + CbcHeuristicJustOne (CbcModel & model); + + // Copy constructor + CbcHeuristicJustOne ( const CbcHeuristicJustOne &); + + // Destructor + ~CbcHeuristicJustOne (); + + /// Clone + virtual CbcHeuristicJustOne * clone() const; + + /// Assignment operator + CbcHeuristicJustOne & operator=(const CbcHeuristicJustOne& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + This does Fractional Diving + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + This is dummy as never called + */ + virtual bool selectVariableToBranch(OsiSolverInterface* /*solver*/, + const double* /*newSolution*/, + int& /*bestColumn*/, + int& /*bestRound*/) { + return true; + } + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + /// Adds an heuristic with probability + void addHeuristic(const CbcHeuristic * heuristic, double probability); + /// Normalize probabilities + void normalizeProbabilities(); +protected: + // Data + + // Probability of running a heuristic + double * probabilities_; + + // Heuristics + CbcHeuristic ** heuristic_; + + // Number of heuristics + int numberHeuristics_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDINS.hpp b/thirdparty/linux/include/coin/CbcHeuristicDINS.hpp new file mode 100644 index 0000000..49d0c1c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDINS.hpp @@ -0,0 +1,96 @@ +// $Id: CbcHeuristicDINS.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicDINS_H +#define CbcHeuristicDINS_H + +#include "CbcHeuristic.hpp" + + +class CbcHeuristicDINS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDINS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicDINS (CbcModel & model); + + // Copy constructor + CbcHeuristicDINS ( const CbcHeuristicDINS &); + + // Destructor + ~CbcHeuristicDINS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicDINS & operator=(const CbcHeuristicDINS& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Sets maximum number of solutions kept + inline void setMaximumKeep(int value) { + maximumKeepSolutions_ = value; + } + /// Sets tightness of extra constraint + inline void setConstraint(int value) { + localSpace_ = value; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /// Maximum number of solutions to keep + int maximumKeepSolutions_; + /// Number of solutions kept + int numberKeptSolutions_; + /// Number of integer variables + int numberIntegers_; + /// Local parameter + int localSpace_; + /// Values of integer variables + int ** values_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDW.hpp b/thirdparty/linux/include/coin/CbcHeuristicDW.hpp new file mode 100644 index 0000000..337bd0f --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDW.hpp @@ -0,0 +1,309 @@ +// $Id: CbcHeuristicDW.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef CbcHeuristicDW_H +#define CbcHeuristicDW_H + +#include "CbcHeuristic.hpp" + +/** + This is unlike the other heuristics in that it is very very compute intensive. + It tries to find a DW structure and use that + */ + +class CbcHeuristicDW : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDW (); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, int keepContinuous=0); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, + int callBack(CbcHeuristicDW * currentHeuristic, + CbcModel * thisModel, + int whereFrom), + int keepContinuous=0); + + // Copy constructor + CbcHeuristicDW ( const CbcHeuristicDW &); + + // Destructor + ~CbcHeuristicDW (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicDW & operator=(const CbcHeuristicDW& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /** Return number of blocks + <=0 - no usable structure */ + inline int numberBlocks() const + { return numberBlocks_;} + /// Pass in a solution + void passInSolution(const double * solution); + /// Pass in continuous solution + void passInContinuousSolution(const double * solution); + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + void setProposalActions(int fullDWEverySoOften); + /// Objective value when whichDw created + double objectiveValueWhen(int whichDW) const; + /// Number of columns in DW + int numberColumnsDW(int whichDW) const; + /// Solver + inline OsiSolverInterface * solver() const + { return solver_;} + /// DW model (user must delete) + OsiSolverInterface * DWModel(int whichDW) const; + /// Best objective value + inline double bestObjective() const + { return bestObjective_;} + /// Best solution found so far + inline const double * bestSolution() const + { return bestSolution_;} + /// Continuous solution + inline const double * continuousSolution() const + { return continuousSolution_;} + /// Reduced costs of fixed solution + inline const double * fixedDj() const + { return fixedDj_;} + /// Objective at which DW updated + inline const double * objectiveDW() const + { return objectiveDW_;} + /// Number of times we have added to DW model + inline int numberDWTimes() const + { return numberDWTimes_;} + /// Number of columns in DW + inline const int * numberColumnsDW() const + { return numberColumnsDW_;} + /// Set number of passes + inline void setNumberPasses(int value) + { numberPasses_ = value;} + /// Set number of passes without better solution + inline void setNumberBadPasses(int value) + { numberBadPasses_ = value;} + /// Set number free integers needed (Base value) + inline void setNumberNeeded(int value) + { nNeededBase_ = value;} + /// Get number free integers needed (Base value) + inline int getNumberNeeded() const + {return nNeededBase_;} + /// Set number free integers needed (Current value) + inline void setCurrentNumberNeeded(int value) + { nNeeded_ = value;} + /// Get number free integers needed (Current value) + inline int getCurrentNumberNeeded() const + {return nNeeded_;} + /// Set number nodes (could be done in callback) (Base value) + inline void setNumberNodes(int value) + { nNodesBase_ = value;} + /// Get number nodes (could be done in callback) (Base value) + inline int getNumberNodes() const + {return nNodesBase_;} + /// Set number nodes (could be done in callback) (Current value) + inline void setCurrentNumberNodes(int value) + { nNodes_ = value;} + /// Get number nodes (could be done in callback) (Current value) + inline int getCurrentNumberNodes() const + {return nNodes_;} + /// Set target objective + inline void setTargetObjective(double value) + { targetObjective_ = value;} + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Block for every row + inline const int * whichRowBlock() const + { return whichRowBlock_;} + /// Block for every column + inline const int * whichColumnBlock() const + { return whichColumnBlock_;} + /// Initial Lower bounds + inline double * initialLower() const + { return saveLower_;} + /// Initial Upper bounds + inline double * initialUpper() const + { return saveUpper_;} + /// Local integer arrays (each numberBlocks_ long) + inline int * intArrays() const + { return intArray_;} + /// Local double arrays (each numberBlocks_ long) + inline double * doubleArrays() const + { return doubleArray_;} + /// Phase of solution + inline int phase() const + { return phase_;} + /// Pass number + inline int pass() const + { return pass_;} + /// Which columns are in block + inline const int * columnsInBlock() const + { return columnsInBlock_;} + /// Starts for columnsInBlock + inline const int * startColumnBlock() const + { return startColumnBlock_;} + /// Number of integer variables in each block + inline const int * intsInBlock() const + { return intsInBlock_;} + /// Objective value (could also check validity) + double objectiveValue(const double * solution); +private: + /// Guts of copy + void gutsOfCopy(const CbcHeuristicDW & rhs); + /// Guts of delete + void gutsOfDelete(); + /// Set default values + void setDefaults(); + /// Find structure + void findStructure(); + /// Set up DW structure + void setupDWStructures(); + /// Add DW proposals + int addDW(const double * solution,int numberBlocksUsed, + const int * whichBlocks); +protected: + typedef int (*heuristicCallBack) (CbcHeuristicDW * ,CbcModel *, int) ; + // Data + /// Target objective + double targetObjective_; + /// Best objective value + double bestObjective_; + /// Objective value last time + double lastObjective_; + /** Call back + whereFrom - + 0 - after blocks found but before data setup + 1 - after blocks sorted but before used + 2 - just before normal branch and bound + 3 - after DW has been updated + 4 - if better solution found + 5 - every time a block might be used + next few for adjustment of nNeeded etc + 6 - complete search done - no solution + 7 - stopped on nodes - no improvement + 8 - improving (same as 4 but after nNeeded changed + Pointers to local data given by following pointers + */ + heuristicCallBack functionPointer_; + /// Local integer arrays (each numberBlocks_ long) + int * intArray_; + /// Local double arrays (each numberBlocks_ long) + double * doubleArray_; + /// Base solver + OsiSolverInterface * solver_; + /// DW solver + OsiSolverInterface * dwSolver_; + /// Best solution found so far + double * bestSolution_; + /// Continuous solution + double * continuousSolution_; + /// Reduced costs of fixed solution + double * fixedDj_; + /// Original lower bounds + double * saveLower_; + /// Original Upper bounds + double * saveUpper_; + /// random numbers for master rows + double * random_; + /// Weights for each proposal + double * weights_; + /// Objective at which DW updated + double * objectiveDW_; + /// Number of columns in each DW + int * numberColumnsDW_; + /// Block for every row + int * whichRowBlock_; + /// Block for every column + int * whichColumnBlock_; + /// Block number for each proposal + int * dwBlock_; + /// Points back to master rows + int * backwardRow_; + /// Which rows are in blocke + int * rowsInBlock_; + /// Which columns are in block + int * columnsInBlock_; + /// Starts for rowsInBlock + int * startRowBlock_; + /// Starts for columnsInBlock + int * startColumnBlock_; + /// Number of integer variables in each block + int * intsInBlock_; + /// Bits set for 1 integers in each block + unsigned int * fingerPrint_; + /// Affinity each block has for other (will be triangular?) + unsigned short * affinity_; + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + int fullDWEverySoOften_; + /// Number of passes + int numberPasses_; + /// How often to do (code can change) + int howOften_; + /// Current maximum number of DW proposals + int maximumDW_; + /// Number of DW proposals + int numberDW_; + /// Number of times we have added to DW model + int numberDWTimes_; + /// Number of unsigned ints needed for each block of fingerPrint + int sizeFingerPrint_; + /// Number of columns in master + int numberMasterColumns_; + /// Number of rows in master + int numberMasterRows_; + /// Number of blocks + int numberBlocks_; + /// Action on decomposition - 1 keep continuous, 0 don't + int keepContinuous_; + /// Phase of solution + int phase_; + /// Pass number + int pass_; + /// Base number of integers needed + int nNeededBase_; + /// Base number of nodes needed + int nNodesBase_; + /// Base number of integers needed + int nNeeded_; + /// Base number of nodes needed + int nNodes_; + /// Number of passes without better solution + int numberBadPasses_; + // 0 - fine, 1 can't be better, 2 max node + int solveState_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/CbcHeuristicDive.hpp b/thirdparty/linux/include/coin/CbcHeuristicDive.hpp new file mode 100644 index 0000000..ea583db --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDive.hpp @@ -0,0 +1,192 @@ +/* $Id: CbcHeuristicDive.hpp 2093 2014-11-06 16:17:38Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDive_H +#define CbcHeuristicDive_H + +#include "CbcHeuristic.hpp" +class CbcSubProblem; +class OsiRowCut; +struct PseudoReducedCost { + int var; + double pseudoRedCost; +}; + + +/** Dive class + */ + +class CbcHeuristicDive : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDive (); + + // Constructor with model - assumed before cuts + CbcHeuristicDive (CbcModel & model); + + // Copy constructor + CbcHeuristicDive ( const CbcHeuristicDive &); + + // Destructor + ~CbcHeuristicDive (); + + /// Clone + virtual CbcHeuristicDive * clone() const = 0; + + /// Assignment operator + CbcHeuristicDive & operator=(const CbcHeuristicDive& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /// Create C++ lines to get to current state - does work for base class + void generateCpp( FILE * fp, const char * heuristic); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + // REMLOVE using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + This does Fractional Diving + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// inner part of dive + int solution(double & objectiveValue, int & numberNodes, + int & numberCuts, OsiRowCut ** cuts, + CbcSubProblem ** & nodes, + double * newSolution); + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + also returns list of nodes + This does Fractional Diving + */ + int fathom(CbcModel * model, int & numberNodes,CbcSubProblem ** & nodes); + + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + /// Sets priorities if any + void setPriorities(); + + /// Select candidate binary variables for fixing + void selectBinaryVariables(); + + /// Set percentage of integer variables to fix at bounds + void setPercentageToFix(double value) { + percentageToFix_ = value; + } + + /// Set maximum number of iterations + void setMaxIterations(int value) { + maxIterations_ = value; + } + + /// Set maximum number of simplex iterations + void setMaxSimplexIterations(int value) { + maxSimplexIterations_ = value; + } + /// Get maximum number of simplex iterations + inline int maxSimplexIterations() const { + return maxSimplexIterations_; + } + + /// Set maximum number of simplex iterations at root node + void setMaxSimplexIterationsAtRoot(int value) { + maxSimplexIterationsAtRoot_ = value; + } + + /// Set maximum time allowed + void setMaxTime(double value) { + maxTime_ = value; + } + + /// Tests if the heuristic can run + virtual bool canHeuristicRun(); + + /** Selects the next variable to branch on + Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + /** Initializes any data which is going to be used repeatedly + in selectVariableToBranch */ + virtual void initializeData() {} + + /// Perform reduced cost fixing on integer variables + int reducedCostFix (OsiSolverInterface* solver); + /// Fix other variables at bounds + virtual int fixOtherVariables(OsiSolverInterface * solver, + const double * solution, + PseudoReducedCost * candidate, + const double * random); + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Original matrix by + CoinPackedMatrix matrixByRow_; + + // Down locks + unsigned short * downLocks_; + + // Up locks + unsigned short * upLocks_; + + /// Extra down array (number Integers long) + double * downArray_; + + /// Extra up array (number Integers long) + double * upArray_; + + /// Array of priorities + typedef struct { + unsigned int direction:3; // 0 bit off, 1 bit (0 down first, 1 up first) 2 bit non zero don't try other way + unsigned int priority:29; + } PriorityType; + PriorityType * priority_; + // Indexes of binary variables with 0 objective coefficient + // and in variable bound constraints + std::vector<int> binVarIndex_; + + // Indexes of variable bound rows for each binary variable + std::vector<int> vbRowIndex_; + + // Percentage of integer variables to fix at bounds + double percentageToFix_; + + // Maximum time allowed + double maxTime_; + + // Small objective (i.e. treat zero objective as this) + double smallObjective_; + + // Maximum number of major iterations + int maxIterations_; + + // Maximum number of simplex iterations + int maxSimplexIterations_; + + // Maximum number of simplex iterations at root node + int maxSimplexIterationsAtRoot_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDiveCoefficient.hpp b/thirdparty/linux/include/coin/CbcHeuristicDiveCoefficient.hpp new file mode 100644 index 0000000..d4b7b68 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDiveCoefficient.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveCoefficient.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveCoefficient_H +#define CbcHeuristicDiveCoefficient_H + +#include "CbcHeuristicDive.hpp" + +/** DiveCoefficient class + */ + +class CbcHeuristicDiveCoefficient : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveCoefficient (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveCoefficient (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveCoefficient ( const CbcHeuristicDiveCoefficient &); + + // Destructor + ~CbcHeuristicDiveCoefficient (); + + /// Clone + virtual CbcHeuristicDiveCoefficient * clone() const; + + /// Assignment operator + CbcHeuristicDiveCoefficient & operator=(const CbcHeuristicDiveCoefficient& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDiveFractional.hpp b/thirdparty/linux/include/coin/CbcHeuristicDiveFractional.hpp new file mode 100644 index 0000000..bc17047 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDiveFractional.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveFractional.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveFractional_H +#define CbcHeuristicDiveFractional_H + +#include "CbcHeuristicDive.hpp" + +/** DiveFractional class + */ + +class CbcHeuristicDiveFractional : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveFractional (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveFractional (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveFractional ( const CbcHeuristicDiveFractional &); + + // Destructor + ~CbcHeuristicDiveFractional (); + + /// Clone + virtual CbcHeuristicDiveFractional * clone() const; + + /// Assignment operator + CbcHeuristicDiveFractional & operator=(const CbcHeuristicDiveFractional& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDiveGuided.hpp b/thirdparty/linux/include/coin/CbcHeuristicDiveGuided.hpp new file mode 100644 index 0000000..2b369dc --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDiveGuided.hpp @@ -0,0 +1,55 @@ +/* $Id: CbcHeuristicDiveGuided.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveGuided_H +#define CbcHeuristicDiveGuided_H + +#include "CbcHeuristicDive.hpp" + +/** DiveGuided class + */ + +class CbcHeuristicDiveGuided : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveGuided (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveGuided (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveGuided ( const CbcHeuristicDiveGuided &); + + // Destructor + ~CbcHeuristicDiveGuided (); + + /// Clone + virtual CbcHeuristicDiveGuided * clone() const; + + /// Assignment operator + CbcHeuristicDiveGuided & operator=(const CbcHeuristicDiveGuided& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Tests if the heuristic can run + virtual bool canHeuristicRun(); + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDiveLineSearch.hpp b/thirdparty/linux/include/coin/CbcHeuristicDiveLineSearch.hpp new file mode 100644 index 0000000..30c5f63 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDiveLineSearch.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveLineSearch.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveLineSearch_H +#define CbcHeuristicDiveLineSearch_H + +#include "CbcHeuristicDive.hpp" + +/** DiveLineSearch class + */ + +class CbcHeuristicDiveLineSearch : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveLineSearch (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveLineSearch (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveLineSearch ( const CbcHeuristicDiveLineSearch &); + + // Destructor + ~CbcHeuristicDiveLineSearch (); + + /// Clone + virtual CbcHeuristicDiveLineSearch * clone() const; + + /// Assignment operator + CbcHeuristicDiveLineSearch & operator=(const CbcHeuristicDiveLineSearch& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDivePseudoCost.hpp b/thirdparty/linux/include/coin/CbcHeuristicDivePseudoCost.hpp new file mode 100644 index 0000000..4f0dcb0 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDivePseudoCost.hpp @@ -0,0 +1,60 @@ +/* $Id: CbcHeuristicDivePseudoCost.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDivePseudoCost_H +#define CbcHeuristicDivePseudoCost_H + +#include "CbcHeuristicDive.hpp" + +/** DivePseudoCost class + */ + +class CbcHeuristicDivePseudoCost : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDivePseudoCost (); + + // Constructor with model - assumed before cuts + CbcHeuristicDivePseudoCost (CbcModel & model); + + // Copy constructor + CbcHeuristicDivePseudoCost ( const CbcHeuristicDivePseudoCost &); + + // Destructor + ~CbcHeuristicDivePseudoCost (); + + /// Clone + virtual CbcHeuristicDivePseudoCost * clone() const; + + /// Assignment operator + CbcHeuristicDivePseudoCost & operator=(const CbcHeuristicDivePseudoCost& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + /** Initializes any data which is going to be used repeatedly + in selectVariableToBranch */ + virtual void initializeData() ; + /// Fix other variables at bounds + virtual int fixOtherVariables(OsiSolverInterface * solver, + const double * solution, + PseudoReducedCost * candidate, + const double * random); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicDiveVectorLength.hpp b/thirdparty/linux/include/coin/CbcHeuristicDiveVectorLength.hpp new file mode 100644 index 0000000..c83852f --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicDiveVectorLength.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveVectorLength.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveVectorLength_H +#define CbcHeuristicDiveVectorLength_H + +#include "CbcHeuristicDive.hpp" + +/** DiveVectorLength class + */ + +class CbcHeuristicDiveVectorLength : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveVectorLength (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveVectorLength (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveVectorLength ( const CbcHeuristicDiveVectorLength &); + + // Destructor + ~CbcHeuristicDiveVectorLength (); + + /// Clone + virtual CbcHeuristicDiveVectorLength * clone() const; + + /// Assignment operator + CbcHeuristicDiveVectorLength & operator=(const CbcHeuristicDiveVectorLength& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicFPump.hpp b/thirdparty/linux/include/coin/CbcHeuristicFPump.hpp new file mode 100644 index 0000000..1c1af86 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicFPump.hpp @@ -0,0 +1,340 @@ +/* $Id: CbcHeuristicFPump.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicFeasibilityPump_H +#define CbcHeuristicFeasibilityPump_H + +#include "CbcHeuristic.hpp" +#include "OsiClpSolverInterface.hpp" + +/** Feasibility Pump class + */ + +class CbcHeuristicFPump : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicFPump (); + + // Constructor with model - assumed before cuts + CbcHeuristicFPump (CbcModel & model, + double downValue = 0.5, bool roundExpensive = false); + + // Copy constructor + CbcHeuristicFPump ( const CbcHeuristicFPump &); + + // Destructor + ~CbcHeuristicFPump (); + + /// Assignment operator + CbcHeuristicFPump & operator=(const CbcHeuristicFPump& rhs); + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts. + + It may make sense for user to call this outside Branch and Cut to + get solution. Or normally is just at root node. + + * new meanings for when_ - on first try then set back to 1 + 11 - at end fix all integers at same bound throughout + 12 - also fix all integers staying at same internal integral value throughout + 13 - also fix all continuous variables staying at same bound throughout + 14 - also fix all continuous variables staying at same internal value throughout + 15 - as 13 but no internal integers + And beyond that, it's apparently possible for the range to be between 21 + and 25, in which case it's reduced on entry to solution() to be between + 11 and 15 and allSlack is set to true. Then, if we're not processing + general integers, we'll use an all-slack basis to solve ... what? Don't + see that yet. + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Set maximum Time (default off) - also sets starttime to current + void setMaximumTime(double value); + /// Get maximum Time (default 0.0 == time limit off) + inline double maximumTime() const { + return maximumTime_; + } + /// Set fake cutoff (default COIN_DBL_MAX == off) + inline void setFakeCutoff(double value) { + fakeCutoff_ = value; + } + /// Get fake cutoff (default 0.0 == off) + inline double fakeCutoff() const { + return fakeCutoff_; + } + /// Set absolute increment (default 0.0 == off) + inline void setAbsoluteIncrement(double value) { + absoluteIncrement_ = value; + } + /// Get absolute increment (default 0.0 == off) + inline double absoluteIncrement() const { + return absoluteIncrement_; + } + /// Set relative increment (default 0.0 == off) + inline void setRelativeIncrement(double value) { + relativeIncrement_ = value; + } + /// Get relative increment (default 0.0 == off) + inline double relativeIncrement() const { + return relativeIncrement_; + } + /// Set default rounding (default 0.5) + inline void setDefaultRounding(double value) { + defaultRounding_ = value; + } + /// Get default rounding (default 0.5) + inline double defaultRounding() const { + return defaultRounding_; + } + /// Set initial weight (default 0.0 == off) + inline void setInitialWeight(double value) { + initialWeight_ = value; + } + /// Get initial weight (default 0.0 == off) + inline double initialWeight() const { + return initialWeight_; + } + /// Set weight factor (default 0.1) + inline void setWeightFactor(double value) { + weightFactor_ = value; + } + /// Get weight factor (default 0.1) + inline double weightFactor() const { + return weightFactor_; + } + /// Set threshold cost for using original cost - even on continuous (default infinity) + inline void setArtificialCost(double value) { + artificialCost_ = value; + } + /// Get threshold cost for using original cost - even on continuous (default infinity) + inline double artificialCost() const { + return artificialCost_; + } + /// Get iteration to size ratio + inline double iterationRatio() const { + return iterationRatio_; + } + /// Set iteration to size ratio + inline void setIterationRatio(double value) { + iterationRatio_ = value; + } + /// Set maximum passes (default 100) + inline void setMaximumPasses(int value) { + maximumPasses_ = value; + } + /// Get maximum passes (default 100) + inline int maximumPasses() const { + return maximumPasses_; + } + /// Set maximum retries (default 1) + inline void setMaximumRetries(int value) { + maximumRetries_ = value; + } + /// Get maximum retries (default 1) + inline int maximumRetries() const { + return maximumRetries_; + } + /** Set use of multiple solutions and solves + 0 - do not reuse solves, do not accumulate integer solutions for local search + 1 - do not reuse solves, accumulate integer solutions for local search + 2 - reuse solves, do not accumulate integer solutions for local search + 3 - reuse solves, accumulate integer solutions for local search + If we add 4 then use second form of problem (with extra rows and variables for general integers) + At some point (date?), I added + + And then there are a few bit fields: + 4 - something about general integers + So my (lh) guess for 4 was at least in the ballpark, but I'll have to + rethink 8 entirely (and it may well not mean the same thing as it did + when I added that comment. + 8 - determines whether we process general integers + + And on 090831, John added + + If we add 4 then use second form of problem (with extra rows and + variables for general integers) + If we add 8 then can run after initial cuts (if no solution) + */ + inline void setAccumulate(int value) { + accumulate_ = value; + } + /// Get accumulation option + inline int accumulate() const { + return accumulate_; + } + /** Set whether to fix variables on known solution + 0 - do not fix + 1 - fix integers on reduced costs + 2 - fix integers on reduced costs but only on entry + */ + inline void setFixOnReducedCosts(int value) { + fixOnReducedCosts_ = value; + } + /// Get reduced cost option + inline int fixOnReducedCosts() const { + return fixOnReducedCosts_; + } + /** Set reduced cost multiplier + 1.0 as normal + <1.0 (x) - pretend gap is x* actual gap - just for fixing + */ + inline void setReducedCostMultiplier(double value) { + reducedCostMultiplier_ = value; + } + /// Get reduced cost multiplier + inline double reducedCostMultiplier() const { + return reducedCostMultiplier_; + } + +protected: + // Data + /// Start time + double startTime_; + /// Maximum Cpu seconds + double maximumTime_; + /** Fake cutoff value. + If set then better of real cutoff and this used to add a constraint + */ + double fakeCutoff_; + /// If positive carry on after solution expecting gain of at least this + double absoluteIncrement_; + /// If positive carry on after solution expecting gain of at least this times objective + double relativeIncrement_; + /// Default is round up if > this + double defaultRounding_; + /// Initial weight for true objective + double initialWeight_; + /// Factor for decreasing weight + double weightFactor_; + /// Threshold cost for using original cost - even on continuous + double artificialCost_; + /** If iterationRatio >0 use instead of maximumPasses_ + test is iterations > ratio*(2*nrow+ncol) */ + double iterationRatio_; + /** Reduced cost multiplier + 1.0 as normal + <1.0 (x) - pretend gap is x* actual gap - just for fixing + */ + double reducedCostMultiplier_; + /// Maximum number of passes + int maximumPasses_; + /** Maximum number of retries if we find a solution. + If negative we clean out used array + */ + int maximumRetries_; + /** Set use of multiple solutions and solves + 0 - do not reuse solves, do not accumulate integer solutions for local search + 1 - do not reuse solves, accumulate integer solutions for local search + 2 - reuse solves, do not accumulate integer solutions for local search + 3 - reuse solves, accumulate integer solutions for local search + If we add 4 then use second form of problem (with extra rows and variables for general integers) + If we do not accumulate solutions then no mini branch and bounds will be done + reuse - refers to initial solve after adding in new "cut" + If we add 8 then can run after initial cuts (if no solution) + */ + int accumulate_; + /** Set whether to fix variables on known solution + 0 - do not fix + 1 - fix integers on reduced costs + 2 - fix integers on reduced costs but only on entry + */ + int fixOnReducedCosts_; + /// If true round to expensive + bool roundExpensive_; + +private: + /** Rounds solution - down if < downValue + If roundExpensive then always to more expnsive. + returns 0 if current is solution + */ + int rounds(OsiSolverInterface * solver, double * solution, + /*const double * objective, */ + int numberIntegers, const int * integerVariable, + /*char * pumpPrint,*/int passNumber, + /*bool roundExpensive=false,*/ + double downValue = 0.5, int *flip = 0); + /* note for eagle eyed readers. + when_ can now be exotic - + <=10 normal + */ +}; + +# ifdef COIN_HAS_CLP + +class CbcDisasterHandler : public OsiClpDisasterHandler { +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ +#ifdef JJF_ZERO + /// Into simplex + virtual void intoSimplex(); + /// Checks if disaster + virtual bool check() const ; + /// saves information for next attempt + virtual void saveInfo(); +#endif + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CbcDisasterHandler(CbcModel * model = NULL); + /** Destructor */ + virtual ~CbcDisasterHandler(); + // Copy + CbcDisasterHandler(const CbcDisasterHandler&); + // Assignment + CbcDisasterHandler& operator=(const CbcDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setCbcModel(CbcModel * model); + /// Get model + inline CbcModel * cbcModel() const { + return cbcModel_; + } + + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to model + CbcModel * cbcModel_; + + //@} +}; +#endif + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicGreedy.hpp b/thirdparty/linux/include/coin/CbcHeuristicGreedy.hpp new file mode 100644 index 0000000..4a6a1f3 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicGreedy.hpp @@ -0,0 +1,280 @@ +/* $Id: CbcHeuristicGreedy.hpp 1585 2011-01-11 19:04:34Z forrest $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicGreedy_H +#define CbcHeuristicGreedy_H + +#include "CbcHeuristic.hpp" +/** Greedy heuristic classes + */ + +class CbcHeuristicGreedyCover : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedyCover (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedyCover (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedyCover ( const CbcHeuristicGreedyCover &); + + // Destructor + ~CbcHeuristicGreedyCover (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedyCover & operator=(const CbcHeuristicGreedyCover& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + if 100 added round up all >=0.5 + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } + +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + // original number of rows + int originalNumberRows_; + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + + +class CbcHeuristicGreedyEquality : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedyEquality (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedyEquality (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedyEquality ( const CbcHeuristicGreedyEquality &); + + // Destructor + ~CbcHeuristicGreedyEquality (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedyEquality & operator=(const CbcHeuristicGreedyEquality& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + if 100 added round up all >=0.5 + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Fraction of rhs to cover before branch and cut + inline void setFraction(double value) { + fraction_ = value; + } + inline double fraction() const { + return fraction_; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + // Fraction of rhs to cover before branch and cut + double fraction_; + // original number of rows + int originalNumberRows_; + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + +/** Greedy heuristic for SOS and L rows (and positive elements) + */ + +class CbcHeuristicGreedySOS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedySOS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedySOS (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedySOS ( const CbcHeuristicGreedySOS &); + + // Destructor + ~CbcHeuristicGreedySOS (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedySOS & operator=(const CbcHeuristicGreedySOS& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + Bits + 1 bit - use current model, otherwise original + 2 - use current solution as starting point, otherwise pure greedy + 4 - as 2 but use merit not merit/size + 8 - use duals to modify greedy + 16 - use duals on GUB/SOS in special way + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } + +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original RHS - if -1.0 then SOS otherwise <= value + double * originalRhs_; + // Original matrix by column + CoinPackedMatrix matrix_; + // original number of rows + int originalNumberRows_; + /* Algorithm + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicLocal.hpp b/thirdparty/linux/include/coin/CbcHeuristicLocal.hpp new file mode 100644 index 0000000..baed8d5 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicLocal.hpp @@ -0,0 +1,271 @@ +/* $Id: CbcHeuristicLocal.hpp 1943 2013-07-21 09:05:45Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicLocal_H +#define CbcHeuristicLocal_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicLocal : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicLocal (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicLocal (CbcModel & model); + + // Copy constructor + CbcHeuristicLocal ( const CbcHeuristicLocal &); + + // Destructor + ~CbcHeuristicLocal (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicLocal & operator=(const CbcHeuristicLocal& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + First tries setting a variable to better value. If feasible then + tries setting others. If not feasible then tries swaps + + ******** + + This first version does not do LP's and does swaps of two integer + variables. Later versions could do Lps. + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets type of search + inline void setSearchType(int value) { + swap_ = value; + } + /// Used array so we can set + inline int * used() const { + return used_; + } + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Number of solutions so we only do after new solution + int numberSolutions_; + // Type of search 0=normal, 1=BAB + int swap_; + /// Whether a variable has been in a solution (also when) + int * used_; +}; + +/** Proximity Search class + */ +class CbcHeuristicFPump; +class CbcHeuristicProximity : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicProximity (); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicProximity (CbcModel & model); + + // Copy constructor + CbcHeuristicProximity ( const CbcHeuristicProximity &); + + // Destructor + ~CbcHeuristicProximity (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicProximity & operator=(const CbcHeuristicProximity& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Set extra increment + inline void setIncrement(double value) + { increment_ = value;} + /// Used array so we can set + inline int * used() const { + return used_; + } + +protected: + // Data + /// Increment to use if no change + double increment_; + /// Copy of Feasibility pump + CbcHeuristicFPump * feasibilityPump_; + /// Number of solutions so we only do after new solution + int numberSolutions_; + /// Whether a variable has been in a solution (also when) + int * used_; +}; + + +/** Naive class + a) Fix all ints as close to zero as possible + b) Fix all ints with nonzero costs and < large to zero + c) Put bounds round continuous and UIs and maximize + */ + +class CbcHeuristicNaive : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicNaive (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicNaive (CbcModel & model); + + // Copy constructor + CbcHeuristicNaive ( const CbcHeuristicNaive &); + + // Destructor + ~CbcHeuristicNaive (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicNaive & operator=(const CbcHeuristicNaive& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Sets large cost value + inline void setLargeValue(double value) { + large_ = value; + } + /// Gets large cost value + inline double largeValue() const { + return large_; + } + +protected: + /// Data + /// Large value + double large_; +}; + +/** Crossover Search class + */ + +class CbcHeuristicCrossover : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicCrossover (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicCrossover (CbcModel & model); + + // Copy constructor + CbcHeuristicCrossover ( const CbcHeuristicCrossover &); + + // Destructor + ~CbcHeuristicCrossover (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicCrossover & operator=(const CbcHeuristicCrossover& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Fix variables if agree in useNumber_ solutions + when_ 0 off, 1 only at new solutions, 2 also every now and then + add 10 to make only if agree at lower bound + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Sets number of solutions to use + inline void setNumberSolutions(int value) { + if (value > 0 && value <= 10) + useNumber_ = value; + } + +protected: + // Data + /// Attempts + std::vector <double> attempts_; + /// Random numbers to stop same search happening + double random_[10]; + /// Number of solutions so we only do after new solution + int numberSolutions_; + /// Number of solutions to use + int useNumber_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicPivotAndFix.hpp b/thirdparty/linux/include/coin/CbcHeuristicPivotAndFix.hpp new file mode 100644 index 0000000..9a945f6 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicPivotAndFix.hpp @@ -0,0 +1,58 @@ +/* $Id: CbcHeuristicPivotAndFix.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicPivotAndFix_H +#define CbcHeuristicPivotAndFix_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicPivotAndFix : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicPivotAndFix (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicPivotAndFix (CbcModel & model); + + // Copy constructor + CbcHeuristicPivotAndFix ( const CbcHeuristicPivotAndFix &); + + // Destructor + ~CbcHeuristicPivotAndFix (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicPivotAndFix & operator=(const CbcHeuristicPivotAndFix& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + needs comments + */ + virtual int solution(double & objectiveValue, + double * newSolution); + +protected: +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicRENS.hpp b/thirdparty/linux/include/coin/CbcHeuristicRENS.hpp new file mode 100644 index 0000000..6cc96fa --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicRENS.hpp @@ -0,0 +1,77 @@ +// $Id: CbcHeuristicRENS.hpp 2105 2015-01-05 13:11:11Z forrest $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicRENS_H +#define CbcHeuristicRENS_H + +#include "CbcHeuristic.hpp" + +/** LocalSearch class + */ + +class CbcHeuristicRENS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRENS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRENS (CbcModel & model); + + // Copy constructor + CbcHeuristicRENS ( const CbcHeuristicRENS &); + + // Destructor + ~CbcHeuristicRENS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicRENS & operator=(const CbcHeuristicRENS& rhs); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Extension Neighborhood Search + Does not run if when_<2 and a solution exists + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Set type + inline void setRensType(int value) + { rensType_ = value;} + +protected: + // Data + /// Number of tries + int numberTries_; + /** Type + 0 - fix at LB + 1 - fix on dj + 2 - fix at UB as well + 3 - fix on 0.01*average dj + add 16 to allow two tries + 32 - if solution exists use to keep more variables + 64 - if priorities keep high priority + 128 - if priorities keep low priority + */ + int rensType_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicRINS.hpp b/thirdparty/linux/include/coin/CbcHeuristicRINS.hpp new file mode 100644 index 0000000..89281b5 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicRINS.hpp @@ -0,0 +1,102 @@ +/* $Id: CbcHeuristicRINS.hpp 1956 2013-08-17 15:28:45Z forrest $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicRINS_H +#define CbcHeuristicRINS_H + +#include "CbcHeuristic.hpp" +// for backward compatibility include 3 other headers +#include "CbcHeuristicRENS.hpp" +#include "CbcHeuristicDINS.hpp" +#include "CbcHeuristicVND.hpp" +/** LocalSearch class + */ + +class CbcHeuristicRINS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRINS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRINS (CbcModel & model); + + // Copy constructor + CbcHeuristicRINS ( const CbcHeuristicRINS &); + + // Destructor + ~CbcHeuristicRINS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicRINS & operator=(const CbcHeuristicRINS& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Used array so we can set + inline char * used() const { + return used_; + } + /// Resets lastNode + inline void setLastNode(int value) { + lastNode_ = value; + } + /// Resets number of solutions + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /** State of fixing continuous variables - + 0 - not tried + +n - this divisor makes small enough + -n - this divisor still not small enough + */ + int stateOfFixing_; + /// Node when last done + int lastNode_; + /// Whether a variable has been in a solution + char * used_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicRandRound.hpp b/thirdparty/linux/include/coin/CbcHeuristicRandRound.hpp new file mode 100644 index 0000000..dd1eedb --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicRandRound.hpp @@ -0,0 +1,58 @@ +/* $Id: CbcHeuristicRandRound.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicRandRound_H +#define CbcHeuristicRandRound_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicRandRound : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRandRound (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRandRound (CbcModel & model); + + // Copy constructor + CbcHeuristicRandRound ( const CbcHeuristicRandRound &); + + // Destructor + ~CbcHeuristicRandRound (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicRandRound & operator=(const CbcHeuristicRandRound& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + needs comments + */ + virtual int solution(double & objectiveValue, + double * newSolution); + +protected: +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcHeuristicVND.hpp b/thirdparty/linux/include/coin/CbcHeuristicVND.hpp new file mode 100644 index 0000000..a245ab0 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcHeuristicVND.hpp @@ -0,0 +1,94 @@ +// $Id: CbcHeuristicVND.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicVND_H +#define CbcHeuristicVND_H + +#include "CbcHeuristic.hpp" + + +/** LocalSearch class + */ + +class CbcHeuristicVND : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicVND (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicVND (CbcModel & model); + + // Copy constructor + CbcHeuristicVND ( const CbcHeuristicVND &); + + // Destructor + ~CbcHeuristicVND (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicVND & operator=(const CbcHeuristicVND& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// base solution array so we can set + inline double * baseSolution() const { + return baseSolution_; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /// Node when last done + int lastNode_; + /// Step size for decomposition + int stepSize_; + int k_; + int kmax_; + int nDifferent_; + /// Base solution + double * baseSolution_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcLinked.hpp b/thirdparty/linux/include/coin/CbcLinked.hpp new file mode 100644 index 0000000..daa977c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcLinked.hpp @@ -0,0 +1,1406 @@ +/* $Id: CbcLinked.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglLinked_H +#define CglLinked_H +/* THIS CONTAINS STUFF THAT SHOULD BE IN + OsiSolverLink + OsiBranchLink + CglTemporary +*/ +#include "CoinModel.hpp" +#include "OsiClpSolverInterface.hpp" +#include "OsiChooseVariable.hpp" +#include "CbcFathom.hpp" +class CbcModel; +class CoinPackedMatrix; +class OsiLinkedBound; +class OsiObject; +class CglStored; +class CglTemporary; +/** + +This is to allow the user to replace initialSolve and resolve +This version changes coefficients +*/ + +class OsiSolverLink : public CbcOsiSolver { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /** + Problem specific + Returns -1 if node fathomed and no solution + 0 if did nothing + 1 if node fathomed and solution + allFixed is true if all LinkedBound variables are fixed + */ + virtual int fathom(bool allFixed) ; + /** Solves nonlinear problem from CoinModel using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + Returns solution array + */ + double * nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solve linearized quadratic objective branch and bound. + Return cutoff and OA cut + */ + double linearizedBAB(CglStored * cut) ; + /** Solves nonlinear problem from CoinModel using SLP - and then tries to get + heuristic solution + Returns solution array + mode - + 0 just get continuous + 1 round and try normal bab + 2 use defaultBound_ to bound integer variables near current solution + */ + double * heuristicSolution(int numberPasses, double deltaTolerance, int mode); + + /// Do OA cuts + int doAOCuts(CglTemporary * cutGen, const double * solution, const double * solution2); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLink (); + + /** This creates from a coinModel object + + if errors.then number of sets is -1 + + This creates linked ordered sets information. It assumes - + + for product terms syntax is yy*f(zz) + also just f(zz) is allowed + and even a constant + + modelObject not const as may be changed as part of process. + */ + OsiSolverLink( CoinModel & modelObject); + // Other way with existing object + void load( CoinModel & modelObject, bool tightenBounds = false, int logLevel = 1); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLink (const OsiSolverLink &); + + /// Assignment operator + OsiSolverLink & operator=(const OsiSolverLink& rhs); + + /// Destructor + virtual ~OsiSolverLink (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, int whichVariableAffected, + double multiplier = 1.0); + /// Update coefficients - returns number updated if in updating mode + int updateCoefficients(ClpSimplex * solver, CoinPackedMatrix * matrix); + /// Analyze constraints to see which are convex (quadratic) + void analyzeObjects(); + /// Add reformulated bilinear constraints + void addTighterConstraints(); + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Set objective value of best solution found internally + inline void setBestObjectiveValue(double value) { + bestObjectiveValue_ = value; + } + /// Best solution found internally + inline const double * bestSolution() const { + return bestSolution_; + } + /// Set best solution found internally + void setBestSolution(const double * solution, int numberColumns); + /// Set special options + inline void setSpecialOptions2(int value) { + specialOptions2_ = value; + } + /// Say convex (should work it out) - if convex false then strictly concave + void sayConvex(bool convex); + /// Get special options + inline int specialOptions2() const { + return specialOptions2_; + } + /** Clean copy of matrix + So we can add rows + */ + CoinPackedMatrix * cleanMatrix() const { + return matrix_; + } + /** Row copy of matrix + Just genuine columns and rows + Linear part + */ + CoinPackedMatrix * originalRowCopy() const { + return originalRowCopy_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + /// Gets correct form for a quadratic row - user to delete + CoinPackedMatrix * quadraticRow(int rowNumber, double * linear) const; + /// Default meshSize + inline double defaultMeshSize() const { + return defaultMeshSize_; + } + inline void setDefaultMeshSize(double value) { + defaultMeshSize_ = value; + } + /// Default maximumbound + inline double defaultBound() const { + return defaultBound_; + } + inline void setDefaultBound(double value) { + defaultBound_ = value; + } + /// Set integer priority + inline void setIntegerPriority(int value) { + integerPriority_ = value; + } + /// Get integer priority + inline int integerPriority() const { + return integerPriority_; + } + /// Objective transfer variable if one + inline int objectiveVariable() const { + return objectiveVariable_; + } + /// Set biLinear priority + inline void setBiLinearPriority(int value) { + biLinearPriority_ = value; + } + /// Get biLinear priority + inline int biLinearPriority() const { + return biLinearPriority_; + } + /// Return CoinModel + inline const CoinModel * coinModel() const { + return &coinModel_; + } + /// Set all biLinear priorities on x-x variables + void setBiLinearPriorities(int value, double meshSize = 1.0); + /** Set options and priority on all or some biLinear variables + 1 - on I-I + 2 - on I-x + 4 - on x-x + or combinations. + -1 means leave (for priority value and strategy value) + */ + void setBranchingStrategyOnVariables(int strategyValue, int priorityValue = -1, + int mode = 7); + /// Set all mesh sizes on x-x variables + void setMeshSizes(double value); + /** Two tier integer problem where when set of variables with priority + less than this are fixed the problem becomes an easier integer problem + */ + void setFixedPriority(int priorityValue); + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + /// Do real work of initialize + //void initialize(ClpSimplex * & solver, OsiObject ** & object) const; + /// Do real work of delete + void gutsOfDestructor(bool justNullify = false); + /// Do real work of copy + void gutsOfCopy(const OsiSolverLink & rhs) ; + //@} + + /**@name Private member data */ + //@{ + /** Clean copy of matrix + Marked coefficients will be multiplied by L or U + */ + CoinPackedMatrix * matrix_; + /** Row copy of matrix + Just genuine columns and rows + */ + CoinPackedMatrix * originalRowCopy_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Number of rows with nonLinearities + int numberNonLinearRows_; + /// Starts of lists + int * startNonLinear_; + /// Row number for a list + int * rowNonLinear_; + /** Indicator whether is convex, concave or neither + -1 concave, 0 neither, +1 convex + */ + int * convex_; + /// Indices in a list/row + int * whichNonLinear_; + /// Model in CoinModel format + CoinModel coinModel_; + /// Number of variables in tightening phase + int numberVariables_; + /// Information + OsiLinkedBound * info_; + /** + 0 bit (1) - call fathom (may do mini B&B) + 1 bit (2) - quadratic only in objective (add OA cuts) + 2 bit (4) - convex + 3 bit (8) - try adding OA cuts + 4 bit (16) - add linearized constraints + */ + int specialOptions2_; + /// Objective transfer row if one + int objectiveRow_; + /// Objective transfer variable if one + int objectiveVariable_; + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Default mesh + double defaultMeshSize_; + /// Default maximum bound + double defaultBound_; + /// Best solution found internally + double * bestSolution_; + /// Priority for integers + int integerPriority_; + /// Priority for bilinear + int biLinearPriority_; + /// Number of variables which when fixed help + int numberFix_; + /// list of fixed variables + int * fixVariables_; + //@} +}; +/** + List of bounds which depend on other bounds +*/ + +class OsiLinkedBound { + +public: + //--------------------------------------------------------------------------- + /**@name Action methods */ + //@{ + /// Update other bounds + void updateBounds(ClpSimplex * solver); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiLinkedBound (); + /// Useful Constructor + OsiLinkedBound(OsiSolverInterface * model, int variable, + int numberAffected, const int * positionL, + const int * positionU, const double * multiplier); + + /// Copy constructor + OsiLinkedBound (const OsiLinkedBound &); + + /// Assignment operator + OsiLinkedBound & operator=(const OsiLinkedBound& rhs); + + /// Destructor + ~OsiLinkedBound (); + + //@} + + /**@name Sets and Gets */ + //@{ + /// Get variable + inline int variable() const { + return variable_; + } + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, + double multiplier = 1.0); + //@} + +private: + typedef struct { + double multiplier; // to use in computation + int affected; // variable or element affected + /* + 0 - LB of variable affected + 1 - UB of variable affected + 2 - element in position (affected) affected + */ + unsigned char affect; + unsigned char ubUsed; // nonzero if UB of this variable is used + /* + 0 - use x*multiplier + 1 - use multiplier/x + 2 - if UB use min of current upper and x*multiplier, if LB use max of current lower and x*multiplier + */ + unsigned char type; // type of computation + } boundElementAction; + + /**@name Private member data */ + //@{ + /// Pointer back to model + OsiSolverInterface * model_; + /// Variable + int variable_; + /// Number of variables/elements affected + int numberAffected_; + /// Maximum number of variables/elements affected + int maximumAffected_; + /// Actions + boundElementAction * affected_; + //@} +}; +#include "CbcHeuristic.hpp" +/** heuristic - just picks up any good solution + */ + +class CbcHeuristicDynamic3 : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDynamic3 (); + + /* Constructor with model + */ + CbcHeuristicDynamic3 (CbcModel & model); + + // Copy constructor + CbcHeuristicDynamic3 ( const CbcHeuristicDynamic3 &); + + // Destructor + ~CbcHeuristicDynamic3 (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// update model + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /// Returns true if can deal with "odd" problems e.g. sos type 2 + virtual bool canDealWithOdd() const { + return true; + } + +protected: +private: + /// Illegal Assignment operator + CbcHeuristicDynamic3 & operator=(const CbcHeuristicDynamic3& rhs); +}; + +#include "OsiBranchingObject.hpp" + +/** Define Special Linked Ordered Sets. + +*/ +class CoinWarmStartBasis; + +class OsiOldLink : public OsiSOS { + +public: + + // Default Constructor + OsiOldLink (); + + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables in matrix are the numberInSet*numberLink + starting at first. If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int first, + const double * weights, int setNumber); + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables are given by list - grouped. + If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int typeSOS, const int * which, + const double * weights, int setNumber); + + // Copy constructor + OsiOldLink ( const OsiOldLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiOldLink & operator=( const OsiOldLink& rhs); + + // Destructor + virtual ~OsiOldLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + + /// Number of links + int numberLinks_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiOldLinkBranchingObject : public OsiSOSBranchingObject { + +public: + + // Default Constructor + OsiOldLinkBranchingObject (); + + // Useful constructor + OsiOldLinkBranchingObject (OsiSolverInterface * solver, const OsiOldLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiOldLinkBranchingObject ( const OsiOldLinkBranchingObject &); + + // Assignment operator + OsiOldLinkBranchingObject & operator=( const OsiOldLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiOldLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define data for one link + +*/ + + +class OsiOneLink { + +public: + + // Default Constructor + OsiOneLink (); + + /** Useful constructor - + + */ + OsiOneLink (const OsiSolverInterface * solver, int xRow, int xColumn, int xyRow, + const char * functionString); + + // Copy constructor + OsiOneLink ( const OsiOneLink &); + + // Assignment operator + OsiOneLink & operator=( const OsiOneLink& rhs); + + // Destructor + virtual ~OsiOneLink (); + + /// data + + /// Row which defines x (if -1 then no x) + int xRow_; + /// Column which defines x + int xColumn_; + /// Output row + int xyRow; + /// Function + std::string function_; +}; +/** Define Special Linked Ordered Sets. New style + + members and weights may be stored in SOS object + + This is for y and x*f(y) and z*g(y) etc + +*/ + + +class OsiLink : public OsiSOS { + +public: + + // Default Constructor + OsiLink (); + + /** Useful constructor - + + */ + OsiLink (const OsiSolverInterface * solver, int yRow, + int yColumn, double meshSize); + + // Copy constructor + OsiLink ( const OsiLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLink & operator=( const OsiLink& rhs); + + // Destructor + virtual ~OsiLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + /// Current increment for y points + double meshSize_; + /// Links + OsiOneLink * data_; + /// Number of links + int numberLinks_; + /// Row which defines y + int yRow_; + /// Column which defines y + int yColumn_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiLinkBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiLinkBranchingObject (); + + // Useful constructor + OsiLinkBranchingObject (OsiSolverInterface * solver, const OsiLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiLinkBranchingObject ( const OsiLinkBranchingObject &); + + // Assignment operator + OsiLinkBranchingObject & operator=( const OsiLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define BiLinear objects + + This models x*y where one or both are integer + +*/ + + +class OsiBiLinear : public OsiObject2 { + +public: + + // Default Constructor + OsiBiLinear (); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const solver + */ + OsiBiLinear (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const model + */ + OsiBiLinear (CoinModel * coinModel, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + // Copy constructor + OsiBiLinear ( const OsiBiLinear &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinear & operator=( const OsiBiLinear& rhs); + + // Destructor + virtual ~OsiBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return (branchingStrategy_&4) != 0; + } + /// X column + inline int xColumn() const { + return xColumn_; + } + /// Y column + inline int yColumn() const { + return yColumn_; + } + /// X row + inline int xRow() const { + return xRow_; + } + /// Y row + inline int yRow() const { + return yRow_; + } + /// XY row + inline int xyRow() const { + return xyRow_; + } + /// Coefficient + inline double coefficient() const { + return coefficient_; + } + /// Set coefficient + inline void setCoefficient(double value) { + coefficient_ = value; + } + /// First lambda (of 4) + inline int firstLambda() const { + return firstLambda_; + } + /// X satisfied if less than this away from mesh + inline double xSatisfied() const { + return xSatisfied_; + } + inline void setXSatisfied(double value) { + xSatisfied_ = value; + } + /// Y satisfied if less than this away from mesh + inline double ySatisfied() const { + return ySatisfied_; + } + inline void setYSatisfied(double value) { + ySatisfied_ = value; + } + /// X other satisfied if less than this away from mesh + inline double xOtherSatisfied() const { + return xOtherSatisfied_; + } + inline void setXOtherSatisfied(double value) { + xOtherSatisfied_ = value; + } + /// Y other satisfied if less than this away from mesh + inline double yOtherSatisfied() const { + return yOtherSatisfied_; + } + inline void setYOtherSatisfied(double value) { + yOtherSatisfied_ = value; + } + /// X meshSize + inline double xMeshSize() const { + return xMeshSize_; + } + inline void setXMeshSize(double value) { + xMeshSize_ = value; + } + /// Y meshSize + inline double yMeshSize() const { + return yMeshSize_; + } + inline void setYMeshSize(double value) { + yMeshSize_ = value; + } + /// XY satisfied if two version differ by less than this + inline double xySatisfied() const { + return xySatisfied_; + } + inline void setXYSatisfied(double value) { + xySatisfied_ = value; + } + /// Set sizes and other stuff + void setMeshSizes(const OsiSolverInterface * solver, double x, double y); + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + inline int branchingStrategy() const { + return branchingStrategy_; + } + inline void setBranchingStrategy(int value) { + branchingStrategy_ = value; + } + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + inline int boundType() const { + return boundType_; + } + inline void setBoundType(int value) { + boundType_ = value; + } + /// Does work of branching + void newBounds(OsiSolverInterface * solver, int way, short xOrY, double separator) const; + /// Updates coefficients - returns number updated + int updateCoefficients(const double * lower, const double * upper, double * objective, + CoinPackedMatrix * matrix, CoinWarmStartBasis * basis) const; + /// Returns true value of single xyRow coefficient + double xyCoefficient(const double * solution) const; + /// Get LU coefficients from matrix + void getCoefficients(const OsiSolverInterface * solver, double xB[2], double yB[2], double xybar[4]) const; + /// Compute lambdas (third entry in each .B is current value) (nonzero if bad) + double computeLambdas(const double xB[3], const double yB[3], const double xybar[4], double lambda[4]) const; + /// Adds in data for extra row with variable coefficients + void addExtraRow(int row, double multiplier); + /// Sets infeasibility and other when pseudo shadow prices + void getPseudoShadow(const OsiBranchingInformation * info); + /// Gets sum of movements to correct value + double getMovement(const OsiBranchingInformation * info); + +protected: + /// Compute lambdas if coefficients not changing + void computeLambdas(const OsiSolverInterface * solver, double lambda[4]) const; + /// data + + /// Coefficient + double coefficient_; + /// x mesh + double xMeshSize_; + /// y mesh + double yMeshSize_; + /// x satisfied if less than this away from mesh + double xSatisfied_; + /// y satisfied if less than this away from mesh + double ySatisfied_; + /// X other satisfied if less than this away from mesh + double xOtherSatisfied_; + /// Y other satisfied if less than this away from mesh + double yOtherSatisfied_; + /// xy satisfied if less than this away from true + double xySatisfied_; + /// value of x or y to branch about + mutable double xyBranchValue_; + /// x column + int xColumn_; + /// y column + int yColumn_; + /// First lambda (of 4) + int firstLambda_; + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + int branchingStrategy_; + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + int boundType_; + /// x row + int xRow_; + /// y row (-1 if x*x) + int yRow_; + /// Output row + int xyRow_; + /// Convexity row + int convexity_; + /// Number of extra rows (coefficients to be modified) + int numberExtraRows_; + /// Multiplier for coefficient on row + double * multiplier_; + /// Row number + int * extraRow_; + /// Which chosen -1 none, 0 x, 1 y + mutable short chosen_; +}; +/** Branching object for BiLinear objects + + */ +class OsiBiLinearBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiBiLinearBranchingObject (); + + // Useful constructor + OsiBiLinearBranchingObject (OsiSolverInterface * solver, const OsiBiLinear * originalObject, + int way, + double separator, int chosen); + + // Copy constructor + OsiBiLinearBranchingObject ( const OsiBiLinearBranchingObject &); + + // Assignment operator + OsiBiLinearBranchingObject & operator=( const OsiBiLinearBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiBiLinearBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const; +private: + /// data + /// 1 means branch on x, 2 branch on y + short chosen_; +}; +/** Define Continuous BiLinear objects for an == bound + + This models x*y = b where both are continuous + +*/ + + +class OsiBiLinearEquality : public OsiBiLinear { + +public: + + // Default Constructor + OsiBiLinearEquality (); + + /** Useful constructor - + This Adds in rows and variables to construct Ordered Set + for x*y = b + So note not const solver + */ + OsiBiLinearEquality (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double rhs, + double xMesh); + + // Copy constructor + OsiBiLinearEquality ( const OsiBiLinearEquality &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinearEquality & operator=( const OsiBiLinearEquality& rhs); + + // Destructor + virtual ~OsiBiLinearEquality (); + + /// Possible improvement + virtual double improvement(const OsiSolverInterface * solver) const; + /** change grid + if type 0 then use solution and make finer + if 1 then back to original + returns mesh size + */ + double newGrid(OsiSolverInterface * solver, int type) const; + /// Number of points + inline int numberPoints() const { + return numberPoints_; + } + inline void setNumberPoints(int value) { + numberPoints_ = value; + } + +private: + /// Number of points + int numberPoints_; +}; +/// Define a single integer class - but one where you keep branching until fixed even if satisfied + + +class OsiSimpleFixedInteger : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiSimpleFixedInteger (); + + /// Useful constructor - passed solver index + OsiSimpleFixedInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleFixedInteger (int iColumn, double lower, double upper); + + /// Useful constructor - passed simple integer + OsiSimpleFixedInteger (const OsiSimpleInteger &); + + /// Copy constructor + OsiSimpleFixedInteger ( const OsiSimpleFixedInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleFixedInteger & operator=( const OsiSimpleFixedInteger& rhs); + + /// Destructor + virtual ~OsiSimpleFixedInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; +protected: + /// data + +}; +/** Define a single variable class which is involved with OsiBiLinear objects. + This is used so can make better decision on where to branch as it can look at + all objects. + + This version sees if it can re-use code from OsiSimpleInteger + even if not an integer variable. If not then need to duplicate code. +*/ + + +class OsiUsesBiLinear : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiUsesBiLinear (); + + /// Useful constructor - passed solver index + OsiUsesBiLinear (const OsiSolverInterface * solver, int iColumn, int type); + + /// Useful constructor - passed solver index and original bounds + OsiUsesBiLinear (int iColumn, double lower, double upper, int type); + + /// Useful constructor - passed simple integer + OsiUsesBiLinear (const OsiSimpleInteger & rhs, int type); + + /// Copy constructor + OsiUsesBiLinear ( const OsiUsesBiLinear & rhs); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiUsesBiLinear & operator=( const OsiUsesBiLinear& rhs); + + /// Destructor + virtual ~OsiUsesBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current value. + + Given an current value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /// Add all bi-linear objects + void addBiLinearObjects(OsiSolverLink * solver); +protected: + /// data + /// Number of bilinear objects (maybe could be more general) + int numberBiLinear_; + /// Type of variable - 0 continuous, 1 integer + int type_; + /// Objects + OsiObject ** objects_; +}; +/** This class chooses a variable to branch on + + This is just as OsiChooseStrong but it fakes it so only + first so many are looked at in this phase + +*/ + +class OsiChooseStrongSubset : public OsiChooseStrong { + +public: + + /// Default Constructor + OsiChooseStrongSubset (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrongSubset (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrongSubset (const OsiChooseStrongSubset &); + + /// Assignment operator + OsiChooseStrongSubset & operator= (const OsiChooseStrongSubset& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrongSubset (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /// Number of objects to use + inline int numberObjectsToUse() const { + return numberObjectsToUse_; + } + /// Set number of objects to use + inline void setNumberObjectsToUse(int value) { + numberObjectsToUse_ = value; + } + +protected: + // Data + /// Number of objects to be used (and set in solver) + int numberObjectsToUse_; +}; + +#include <string> + +#include "CglStored.hpp" + +class CoinWarmStartBasis; +/** Stored Temporary Cut Generator Class - destroyed after first use */ +class CglTemporary : public CglStored { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Stored cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + This generator just looks at previously stored cuts + and inserts any that are violated by enough + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglTemporary (); + + /// Copy constructor + CglTemporary (const CglTemporary & rhs); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglTemporary & + operator=(const CglTemporary& rhs); + + /// Destructor + virtual + ~CglTemporary (); + //@} + +private: + +// Private member methods + + // Private member data +}; +//############################################################################# + +/** + +This is to allow the user to replace initialSolve and resolve +*/ + +class OsiSolverLinearizedQuadratic : public OsiClpSolverInterface { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLinearizedQuadratic (); + /// Useful constructor (solution should be good) + OsiSolverLinearizedQuadratic( ClpSimplex * quadraticModel); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLinearizedQuadratic (const OsiSolverLinearizedQuadratic &); + + /// Assignment operator + OsiSolverLinearizedQuadratic & operator=(const OsiSolverLinearizedQuadratic& rhs); + + /// Destructor + virtual ~OsiSolverLinearizedQuadratic (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Best solution found internally + const double * bestSolution() const { + return bestSolution_; + } + /// Set special options + inline void setSpecialOptions3(int value) { + specialOptions3_ = value; + } + /// Get special options + inline int specialOptions3() const { + return specialOptions3_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + + /**@name Private member data */ + //@{ + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Best solution found internally + double * bestSolution_; + /** + 0 bit (1) - don't do mini B&B + 1 bit (2) - quadratic only in objective + */ + int specialOptions3_; + //@} +}; +class ClpSimplex; +/** Return an approximate solution to a CoinModel. + Lots of bounds may be odd to force a solution. + mode = 0 just tries to get a continuous solution +*/ +ClpSimplex * approximateSolution(CoinModel & coinModel, + int numberPasses, double deltaTolerance, + int mode = 0); +#endif + diff --git a/thirdparty/linux/include/coin/CbcMessage.hpp b/thirdparty/linux/include/coin/CbcMessage.hpp new file mode 100644 index 0000000..50690cf --- /dev/null +++ b/thirdparty/linux/include/coin/CbcMessage.hpp @@ -0,0 +1,94 @@ +/* $Id: CbcMessage.hpp 1791 2012-06-08 15:15:10Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcMessage_H +#define CbcMessage_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +/** This deals with Cbc messages (as against Clp messages etc). + CoinMessageHandler.hpp is the general part of message handling. + All it has are enum's for the various messages. + CbcMessage.cpp has text in various languages. + + It is trivial to use the .hpp and .cpp file as a basis for + messages for other components. + */ + +#include "CoinMessageHandler.hpp" +enum CBC_Message { + CBC_END_GOOD, + CBC_MAXNODES, + CBC_MAXTIME, + CBC_MAXSOLS, + CBC_EVENT, + CBC_MAXITERS, + CBC_SOLUTION, + CBC_END_SOLUTION, + CBC_SOLUTION2, + CBC_END, + CBC_INFEAS, + CBC_STRONG, + CBC_SOLINDIVIDUAL, + CBC_INTEGERINCREMENT, + CBC_STATUS, + CBC_GAP, + CBC_ROUNDING, + CBC_TREE_SOL, + CBC_ROOT, + CBC_GENERATOR, + CBC_BRANCH, + CBC_STRONGSOL, + CBC_NOINT, + CBC_VUB_PASS, + CBC_VUB_END, + CBC_NOTFEAS1, + CBC_NOTFEAS2, + CBC_NOTFEAS3, + CBC_CUTOFF_WARNING1, + CBC_ITERATE_STRONG, + CBC_PRIORITY, + CBC_WARNING_STRONG, + CBC_START_SUB, + CBC_END_SUB, + CBC_THREAD_STATS, + CBC_CUTS_STATS, + CBC_STRONG_STATS, + CBC_UNBOUNDED, + CBC_OTHER_STATS, + CBC_HEURISTICS_OFF, + CBC_STATUS2, + CBC_FPUMP1, + CBC_FPUMP2, + CBC_STATUS3, + CBC_OTHER_STATS2, + CBC_RELAXED1, + CBC_RELAXED2, + CBC_RESTART, + CBC_GENERAL, + CBC_ROOT_DETAIL, +#ifndef NO_FATHOM_PRINT + CBC_FATHOM_CHANGE, +#endif + CBC_DUMMY_END +}; + +class CbcMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + CbcMessage(Language language = us_en); + //@} + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcMipStartIO.hpp b/thirdparty/linux/include/coin/CbcMipStartIO.hpp new file mode 100644 index 0000000..58e6c0a --- /dev/null +++ b/thirdparty/linux/include/coin/CbcMipStartIO.hpp @@ -0,0 +1,26 @@ +#ifndef MIPSTARTIO_HPP_INCLUDED +#define MIPSTARTIO_HPP_INCLUDED + +#include <vector> +#include <string> +#include <utility> +class CbcModel; + +class OsiSolverInterface; + +/* tries to read mipstart (solution file) from + fileName, filling colValues and obj + returns 0 with success, + 1 otherwise */ +int readMIPStart( CbcModel * model, const char *fileName, + std::vector< std::pair< std::string, double > > &colValues, + double &solObj ); + +/* from a partial list of variables tries to fill the + remaining variable values */ +int computeCompleteSolution( CbcModel * model, + const std::vector< std::string > colNames, + const std::vector< std::pair< std::string, double > > &colValues, + double *sol, double &obj ); + +#endif // MIPSTARTIO_HPP_INCLUDED diff --git a/thirdparty/linux/include/coin/CbcModel.hpp b/thirdparty/linux/include/coin/CbcModel.hpp new file mode 100644 index 0000000..ceef661 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcModel.hpp @@ -0,0 +1,2952 @@ +/* $Id: CbcModel.hpp 2206 2015-07-07 20:44:40Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcModel_H +#define CbcModel_H +#include <string> +#include <vector> +#include "CoinMessageHandler.hpp" +#include "OsiSolverInterface.hpp" +#include "OsiBranchingObject.hpp" +#include "OsiCuts.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCountRowCut.hpp" +#include "CbcMessage.hpp" +#include "CbcEventHandler.hpp" +#include "ClpDualRowPivot.hpp" + + +class CbcCutGenerator; +class CbcBaseModel; +class OsiRowCut; +class OsiBabSolver; +class OsiRowCutDebugger; +class CglCutGenerator; +class CglStored; +class CbcCutModifier; +class CglTreeProbingInfo; +class CbcHeuristic; +class OsiObject; +class CbcThread; +class CbcTree; +class CbcStrategy; +class CbcSymmetry; +class CbcFeasibilityBase; +class CbcStatistics; +class CbcFullNodeInfo; +class CbcEventHandler ; +class CglPreProcess; +class OsiClpSolverInterface; +class ClpNodeStuff; + +// #define CBC_CHECK_BASIS 1 + +//############################################################################# + +/** Simple Branch and bound class + + The initialSolve() method solves the initial LP relaxation of the MIP + problem. The branchAndBound() method can then be called to finish using + a branch and cut algorithm. + + <h3>Search Tree Traversal</h3> + + Subproblems (aka nodes) requiring additional evaluation are stored using + the CbcNode and CbcNodeInfo objects. Ancestry linkage is maintained in the + CbcNodeInfo object. Evaluation of a subproblem within branchAndBound() + proceeds as follows: + <ul> + <li> The node representing the most promising parent subproblem is popped + from the heap which holds the set of subproblems requiring further + evaluation. + <li> Using branching instructions stored in the node, and information in + its ancestors, the model and solver are adjusted to create the + active subproblem. + <li> If the parent subproblem will require further evaluation + (<i>i.e.</i>, there are branches remaining) its node is pushed back + on the heap. Otherwise, the node is deleted. This may trigger + recursive deletion of ancestors. + <li> The newly created subproblem is evaluated. + <li> If the subproblem requires further evaluation, a node is created. + All information needed to recreate the subproblem (branching + information, row and column cuts) is placed in the node and the node + is added to the set of subproblems awaiting further evaluation. + </ul> + Note that there is never a node representing the active subproblem; the model + and solver represent the active subproblem. + + <h3>Row (Constraint) Cut Handling</h3> + + For a typical subproblem, the sequence of events is as follows: + <ul> + <li> The subproblem is rebuilt for further evaluation: One result of a + call to addCuts() is a traversal of ancestors, leaving a list of all + cuts used in the ancestors in #addedCuts_. This list is then scanned + to construct a basis that includes only tight cuts. Entries for + loose cuts are set to NULL. + <li> The subproblem is evaluated: One result of a call to solveWithCuts() + is the return of a set of newly generated cuts for the subproblem. + #addedCuts_ is also kept up-to-date as old cuts become loose. + <li> The subproblem is stored for further processing: A call to + CbcNodeInfo::addCuts() adds the newly generated cuts to the + CbcNodeInfo object associated with this node. + </ul> + See CbcCountRowCut for details of the bookkeeping associated with cut + management. +*/ + +class CbcModel { + +public: + + enum CbcIntParam { + /** The maximum number of nodes before terminating */ + CbcMaxNumNode = 0, + /** The maximum number of solutions before terminating */ + CbcMaxNumSol, + /** Fathoming discipline + + Controls objective function comparisons for purposes of fathoming by bound + or determining monotonic variables. + + If 1, action is taken only when the current objective is strictly worse + than the target. Implementation is handled by adding a small tolerance to + the target. + */ + CbcFathomDiscipline, + /** Adjusts printout + 1 does different node message with number unsatisfied on last branch + */ + CbcPrinting, + /** Number of branches (may be more than number of nodes as may + include strong branching) */ + CbcNumberBranches, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastIntParam + }; + + enum CbcDblParam { + /** The maximum amount the value of an integer variable can vary from + integer and still be considered feasible. */ + CbcIntegerTolerance = 0, + /** The objective is assumed to worsen by this amount for each + integer infeasibility. */ + CbcInfeasibilityWeight, + /** The amount by which to tighten the objective function cutoff when + a new solution is discovered. */ + CbcCutoffIncrement, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcAllowableGap, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this + fraction of of the absolute value of best known solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcAllowableFractionGap, + /** \brief The maximum number of seconds before terminating. + A double should be adequate! */ + CbcMaximumSeconds, + /// Cutoff - stored for speed + CbcCurrentCutoff, + /// Optimization direction - stored for speed + CbcOptimizationDirection, + /// Current objective value + CbcCurrentObjectiveValue, + /// Current minimization objective value + CbcCurrentMinimizationObjectiveValue, + /** \brief The time at start of model. + So that other pieces of code can access */ + CbcStartSeconds, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcHeuristicGap, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this fraction of of the absolute value of best known + solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcHeuristicFractionGap, + /// Smallest non-zero change on a branch + CbcSmallestChange, + /// Sum of non-zero changes on a branch + CbcSumChange, + /// Largest non-zero change on a branch + CbcLargestChange, + /// Small non-zero change on a branch to be used as guess + CbcSmallChange, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastDblParam + }; + + //--------------------------------------------------------------------------- + +public: + ///@name Solve methods + //@{ + /** \brief Solve the initial LP relaxation + + Invoke the solver's %initialSolve() method. + */ + void initialSolve(); + + /** \brief Invoke the branch \& cut algorithm + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node, then proceeds to explore the + branch & cut search tree. The search ends when the tree is exhausted or + one of several execution limits is reached. + If doStatistics is 1 summary statistics are printed + if 2 then also the path to best solution (if found by branching) + if 3 then also one line per node + */ + void branchAndBound(int doStatistics = 0); +private: + + /** \brief Evaluate a subproblem using cutting planes and heuristics + + The method invokes a main loop which generates cuts, applies heuristics, + and reoptimises using the solver's native %resolve() method. + It returns true if the subproblem remains feasible at the end of the + evaluation. + */ + bool solveWithCuts(OsiCuts & cuts, int numberTries, CbcNode * node); + /** Generate one round of cuts - serial mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int serialCuts(OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Generate one round of cuts - parallel mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int parallelCuts(CbcBaseModel * master, OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Input one node output N nodes to put on tree and optional solution update + This should be able to operate in parallel so is given a solver and is const(ish) + However we will need to keep an array of solver_ and bases and more + status is 0 for normal, 1 if solution + Calling code should always push nodes back on tree + */ + CbcNode ** solveOneNode(int whichSolver, CbcNode * node, + int & numberNodesOutput, int & status) ; + /// Update size of whichGenerator + void resizeWhichGenerator(int numberNow, int numberAfter); +public: +#ifdef CBC_KEEP_DEPRECATED + // See if anyone is using these any more!! + /** \brief create a clean model from partially fixed problem + + The method creates a new model with given bounds and with no tree. + */ + CbcModel * cleanModel(const double * lower, const double * upper); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method presolves the given model and does branch and cut. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + Normally okay to do cleanModel immediately followed by subBranchandBound + (== other form of subBranchAndBound) + but may need to get at model for advanced features. + + Deletes model2 + */ + int subBranchAndBound(CbcModel * model2, + CbcModel * presolvedModel, + int maximumNodes); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method creates a new model with given bounds, presolves it + then proceeds to explore the branch & cut search tree. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + This is just subModel immediately followed by other version of + subBranchandBound. + + */ + int subBranchAndBound(const double * lower, const double * upper, + int maximumNodes); + + /** \brief Process root node and return a strengthened model + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node and then returns a pointer + to the strengthened model (or NULL if infeasible) + */ + OsiSolverInterface * strengthenedModel(); + /** preProcess problem - replacing solver + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + If makeEquality is 1 add slacks to get cliques, + if 2 add slacks to get sos (but only if looks plausible) and keep sos info + */ + CglPreProcess * preProcess( int makeEquality = 0, int numberPasses = 5, + int tuning = 5); + /** Does postprocessing - original solver back. + User has to delete process */ + void postProcess(CglPreProcess * process); +#endif + /// Adds an update information object + void addUpdateInformation(const CbcObjectUpdateData & data); + /** Do one node - broken out for clarity? + also for parallel (when baseModel!=this) + Returns 1 if solution found + node NULL on return if no branches left + newNode NULL if no new node created + */ + int doOneNode(CbcModel * baseModel, CbcNode * & node, CbcNode * & newNode); + +public: + /** \brief Reoptimise an LP relaxation + + Invoke the solver's %resolve() method. + whereFrom - + 0 - initial continuous + 1 - resolve on branch (before new cuts) + 2 - after new cuts + 3 - obsolete code or something modified problem in unexpected way + 10 - after strong branching has fixed variables at root + 11 - after strong branching has fixed variables in tree + + returns 1 feasible, 0 infeasible, -1 feasible but skip cuts + */ + int resolve(CbcNodeInfo * parent, int whereFrom, + double * saveSolution = NULL, + double * saveLower = NULL, + double * saveUpper = NULL); + /// Make given rows (L or G) into global cuts and remove from lp + void makeGlobalCuts(int numberRows, const int * which); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut * cut); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut & cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut * cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut & cut); + /// Make partial cut into a global cut and save + void makePartialCut(const OsiRowCut * cut, const OsiSolverInterface * solver=NULL); + /// Make partial cuts into global cuts + void makeGlobalCuts(); + /// Which cut generator generated this cut + inline const int * whichGenerator() const + { return whichGenerator_;} + //@} + + /** \name Presolve methods */ + //@{ + + /** Identify cliques and construct corresponding objects. + + Find cliques with size in the range + [\p atLeastThisMany, \p lessThanThis] and construct corresponding + CbcClique objects. + If \p makeEquality is true then a new model may be returned if + modifications had to be made, otherwise \c this is returned. + If the problem is infeasible #numberObjects_ is set to -1. + A client must use deleteObjects() before a second call to findCliques(). + If priorities exist, clique priority is set to the default. + */ + CbcModel * findCliques(bool makeEquality, int atLeastThisMany, + int lessThanThis, int defaultValue = 1000); + + /** Do integer presolve, creating a new (presolved) model. + + Returns the new model, or NULL if feasibility is lost. + If weak is true then just does a normal presolve + + \todo It remains to work out the cleanest way of getting a solution to + the original problem at the end. So this is very preliminary. + */ + CbcModel * integerPresolve(bool weak = false); + + /** Do integer presolve, modifying the current model. + + Returns true if the model remains feasible after presolve. + */ + bool integerPresolveThisModel(OsiSolverInterface * originalSolver, bool weak = false); + + + /// Put back information into the original model after integer presolve. + void originalModel(CbcModel * presolvedModel, bool weak); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + Returns false if feasibility is lost. + If CglProbing is available, it will be tried as well to see if it can + tighten bounds. + This routine is just a front end for tightenVubs(int,const int*,double). + + If <tt>type = -1</tt> all variables are processed (could be very slow). + If <tt>type = 0</tt> only variables involved in VUBs are processed. + If <tt>type = n > 0</tt>, only the n most expensive VUB variables + are processed, where it is assumed that x is at its maximum so delta + would have to go to 1 (if x not at bound). + + If \p allowMultipleBinary is true, then a VUB constraint is a row with + one continuous variable and any number of binary variables. + + If <tt>useCutoff < 1.0e30</tt>, the original objective is installed as a + constraint with \p useCutoff as a bound. + */ + bool tightenVubs(int type, bool allowMultipleBinary = false, + double useCutoff = 1.0e50); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + This version is just handed a list of variables to be processed. + */ + bool tightenVubs(int numberVubs, const int * which, + double useCutoff = 1.0e50); + /** + Analyze problem to find a minimum change in the objective function. + */ + void analyzeObjective(); + + /** + Add additional integers. + */ + void AddIntegers(); + /** + Save copy of the model. + */ + void saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible); + /** + Flip direction of optimization on all models + */ + void flipModel(); + + //@} + + /** \name Object manipulation routines + + See OsiObject for an explanation of `object' in the context of CbcModel. + */ + //@{ + + /// Get the number of objects + inline int numberObjects() const { + return numberObjects_; + } + /// Set the number of objects + inline void setNumberObjects(int number) { + numberObjects_ = number; + } + + /// Get the array of objects + inline OsiObject ** objects() const { + return object_; + } + + /// Get the specified object + const inline OsiObject * object(int which) const { + return object_[which]; + } + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { + return object_[which]; + } + + void setOptionalInteger(int index); + + /// Delete all object information (and just back to integers if true) + void deleteObjects(bool findIntegers = true); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, CbcObject ** objects); + + /// Ensure attached objects point to this model. + void synchronizeModel() ; + + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an CbcSimpleInteger object for each + one. + If \p startAgain is true, a new scan is forced, overwriting any existing + integer variable information. + If type > 0 then 1==PseudoCost, 2 new ones low priority + */ + + void findIntegers(bool startAgain, int type = 0); + +#ifdef SWITCH_VARIABLES + /// Convert Dynamic to Switching + int findSwitching(); + /// Fix associated variables + int fixAssociated(OsiSolverInterface * solver,int cleanBasis); + /// Debug associated variables + int checkAssociated(const OsiSolverInterface * solver, + const double * solution, int printLevel); +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + /// Set an integer parameter + inline bool setIntParam(CbcIntParam key, int value) { + intParam_[key] = value; + return true; + } + /// Set a double parameter + inline bool setDblParam(CbcDblParam key, double value) { + dblParam_[key] = value; + return true; + } + /// Get an integer parameter + inline int getIntParam(CbcIntParam key) const { + return intParam_[key]; + } + /// Get a double parameter + inline double getDblParam(CbcDblParam key) const { + return dblParam_[key]; + } + /*! \brief Set cutoff bound on the objective function. + + When using strict comparison, the bound is adjusted by a tolerance to + avoid accidentally cutting off the optimal solution. + */ + void setCutoff(double value) ; + + /// Get the cutoff bound on the objective function - always as minimize + inline double getCutoff() const { //double value ; + //solver_->getDblParam(OsiDualObjectiveLimit,value) ; + //assert( dblParam_[CbcCurrentCutoff]== value * solver_->getObjSense()); + return dblParam_[CbcCurrentCutoff]; + } + + /// Set the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline bool setMaximumNodes( int value) { + return setIntParam(CbcMaxNumNode, value); + } + + /// Get the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline int getMaximumNodes() const { + return getIntParam(CbcMaxNumNode); + } + + /** Set the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline bool setMaximumSolutions( int value) { + return setIntParam(CbcMaxNumSol, value); + } + /** Get the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline int getMaximumSolutions() const { + return getIntParam(CbcMaxNumSol); + } + /// Set the printing mode + inline bool setPrintingMode( int value) { + return setIntParam(CbcPrinting, value); + } + + /// Get the printing mode + inline int getPrintingMode() const { + return getIntParam(CbcPrinting); + } + + /** Set the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline bool setMaximumSeconds( double value) { + return setDblParam(CbcMaximumSeconds, value); + } + /** Get the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline double getMaximumSeconds() const { + return getDblParam(CbcMaximumSeconds); + } + /// Current time since start of branchAndbound + double getCurrentSeconds() const ; + + /// Return true if maximum time reached + bool maximumSecondsReached() const ; + + /** Set the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline bool setIntegerTolerance( double value) { + return setDblParam(CbcIntegerTolerance, value); + } + /** Get the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline double getIntegerTolerance() const { + return getDblParam(CbcIntegerTolerance); + } + + /** Set the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline bool setInfeasibilityWeight( double value) { + return setDblParam(CbcInfeasibilityWeight, value); + } + /** Get the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline double getInfeasibilityWeight() const { + return getDblParam(CbcInfeasibilityWeight); + } + + /** Set the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableGap( double value) { + return setDblParam(CbcAllowableGap, value); + } + /** Get the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableGap() const { + return getDblParam(CbcAllowableGap); + } + + /** Set the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableFractionGap( double value) { + return setDblParam(CbcAllowableFractionGap, value); + } + /** Get the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableFractionGap() const { + return getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowablePercentageGap( double value) { + return setDblParam(CbcAllowableFractionGap, value*0.01); + } + /** Get the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowablePercentageGap() const { + return 100.0*getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicGap( double value) { + return setDblParam(CbcHeuristicGap, value); + } + /** Get the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicGap() const { + return getDblParam(CbcHeuristicGap); + } + + /** Set the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicFractionGap( double value) { + return setDblParam(CbcHeuristicFractionGap, value); + } + /** Get the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicFractionGap() const { + return getDblParam(CbcHeuristicFractionGap); + } + /** Set the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline bool setCutoffIncrement( double value) { + return setDblParam(CbcCutoffIncrement, value); + } + /** Get the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline double getCutoffIncrement() const { + return getDblParam(CbcCutoffIncrement); + } + /// See if can stop on gap + bool canStopOnGap() const; + + /** Pass in target solution and optional priorities. + If priorities then >0 means only branch if incorrect + while <0 means branch even if correct. +1 or -1 are + highest priority */ + void setHotstartSolution(const double * solution, const int * priorities = NULL) ; + + /// Set the minimum drop to continue cuts + inline void setMinimumDrop(double value) { + minimumDrop_ = value; + } + /// Get the minimum drop to continue cuts + inline double getMinimumDrop() const { + return minimumDrop_; + } + + /** Set the maximum number of cut passes at root node (default 20) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPassesAtRoot(int value) { + maximumCutPassesAtRoot_ = value; + } + /** Get the maximum number of cut passes at root node */ + inline int getMaximumCutPassesAtRoot() const { + return maximumCutPassesAtRoot_; + } + + /** Set the maximum number of cut passes at other nodes (default 10) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPasses(int value) { + maximumCutPasses_ = value; + } + /** Get the maximum number of cut passes at other nodes (default 10) */ + inline int getMaximumCutPasses() const { + return maximumCutPasses_; + } + /** Get current cut pass number in this round of cuts. + (1 is first pass) */ + inline int getCurrentPassNumber() const { + return currentPassNumber_; + } + /** Set current cut pass number in this round of cuts. + (1 is first pass) */ + inline void setCurrentPassNumber(int value) { + currentPassNumber_ = value; + } + + /** Set the maximum number of candidates to be evaluated for strong + branching. + + A value of 0 disables strong branching. + */ + void setNumberStrong(int number); + /** Get the maximum number of candidates to be evaluated for strong + branching. + */ + inline int numberStrong() const { + return numberStrong_; + } + /** Set global preferred way to branch + -1 down, +1 up, 0 no preference */ + inline void setPreferredWay(int value) { + preferredWay_ = value; + } + /** Get the preferred way to branch (default 0) */ + inline int getPreferredWay() const { + return preferredWay_; + } + /// Get at which depths to do cuts + inline int whenCuts() const { + return whenCuts_; + } + /// Set at which depths to do cuts + inline void setWhenCuts(int value) { + whenCuts_ = value; + } + /** Return true if we want to do cuts + If allowForTopOfTree zero then just does on multiples of depth + if 1 then allows for doing at top of tree + if 2 then says if cuts allowed anywhere apart from root + */ + bool doCutsNow(int allowForTopOfTree) const; + + /** Set the number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 disables dynamic strong branching. + */ + void setNumberBeforeTrust(int number); + /** get the number of branches before pseudo costs believed + in dynamic strong branching. */ + inline int numberBeforeTrust() const { + return numberBeforeTrust_; + } + /** Set the number of variables for which to compute penalties + in dynamic strong branching. + + A value of 0 disables penalties. + */ + void setNumberPenalties(int number); + /** get the number of variables for which to compute penalties + in dynamic strong branching. */ + inline int numberPenalties() const { + return numberPenalties_; + } + /// Pointer to top of tree + inline const CbcFullNodeInfo * topOfTree() const + { return topOfTree_;} + /// Number of analyze iterations to do + inline void setNumberAnalyzeIterations(int number) { + numberAnalyzeIterations_ = number; + } + inline int numberAnalyzeIterations() const { + return numberAnalyzeIterations_; + } + /** Get scale factor to make penalties match strong. + Should/will be computed */ + inline double penaltyScaleFactor() const { + return penaltyScaleFactor_; + } + /** Set scale factor to make penalties match strong. + Should/will be computed */ + void setPenaltyScaleFactor(double value); + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + 4 - all +- 1 or all +1 and odd + */ + void inline setProblemType(int number) { + problemType_ = number; + } + inline int problemType() const { + return problemType_; + } + /// Current depth + inline int currentDepth() const { + return currentDepth_; + } + + /// Set how often to scan global cuts + void setHowOftenGlobalScan(int number); + /// Get how often to scan global cuts + inline int howOftenGlobalScan() const { + return howOftenGlobalScan_; + } + /// Original columns as created by integerPresolve or preprocessing + inline int * originalColumns() const { + return originalColumns_; + } + /// Set original columns as created by preprocessing + void setOriginalColumns(const int * originalColumns, + int numberGood=COIN_INT_MAX) ; + /// Create conflict cut (well - most of) + OsiRowCut * conflictCut(const OsiSolverInterface * solver, bool & localCuts); + + /** Set the print frequency. + + Controls the number of nodes evaluated between status prints. + If <tt>number <=0</tt> the print frequency is set to 100 nodes for large + problems, 1000 for small problems. + Print frequency has very slight overhead if small. + */ + inline void setPrintFrequency(int number) { + printFrequency_ = number; + } + /// Get the print frequency + inline int printFrequency() const { + return printFrequency_; + } + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + bool isAbandoned() const; + /// Is optimality proven? + bool isProvenOptimal() const; + /// Is infeasiblity proven (or none better than cutoff)? + bool isProvenInfeasible() const; + /// Was continuous solution unbounded + bool isContinuousUnbounded() const; + /// Was continuous solution unbounded + bool isProvenDualInfeasible() const; + /// Node limit reached? + bool isNodeLimitReached() const; + /// Time limit reached? + bool isSecondsLimitReached() const; + /// Solution limit reached? + bool isSolutionLimitReached() const; + /// Get how many iterations it took to solve the problem. + inline int getIterationCount() const { + return numberIterations_; + } + /// Increment how many iterations it took to solve the problem. + inline void incrementIterationCount(int value) { + numberIterations_ += value; + } + /// Get how many Nodes it took to solve the problem (including those in complete fathoming B&B inside CLP). + inline int getNodeCount() const { + return numberNodes_; + } + /// Increment how many nodes it took to solve the problem. + inline void incrementNodeCount(int value) { + numberNodes_ += value; + } + /// Get how many Nodes were enumerated in complete fathoming B&B inside CLP + inline int getExtraNodeCount() const { + return numberExtraNodes_; + } + /// Get how many times complete fathoming B&B was done + inline int getFathomCount() const { + return numberFathoms_; + } + /** Final status of problem + Some of these can be found out by is...... functions + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + */ + inline int status() const { + return status_; + } + inline void setProblemStatus(int value) { + status_ = value; + } + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + 8 stopped on iteration limit + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int value) { + secondaryStatus_ = value; + } + /// Are there numerical difficulties (for initialSolve) ? + bool isInitialSolveAbandoned() const ; + /// Is optimality proven (for initialSolve) ? + bool isInitialSolveProvenOptimal() const ; + /// Is primal infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenPrimalInfeasible() const ; + /// Is dual infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenDualInfeasible() const ; + + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Number of rows in continuous (root) problem. + inline int numberRowsAtContinuous() const { + return numberRowsAtContinuous_; + } + + /// Get number of columns + inline int getNumCols() const { + return solver_->getNumCols(); + } + + /// Get number of rows + inline int getNumRows() const { + return solver_->getNumRows(); + } + + /// Get number of nonzero elements + inline CoinBigIndex getNumElements() const { + return solver_->getNumElements(); + } + + /// Number of integers in problem + inline int numberIntegers() const { + return numberIntegers_; + } + // Integer variables + inline const int * integerVariable() const { + return integerVariable_; + } + /// Whether or not integer + inline char integerType(int i) const { + assert (integerInfo_); + assert (integerInfo_[i] == 0 || integerInfo_[i] == 1); + return integerInfo_[i]; + } + /// Whether or not integer + inline const char * integerType() const { + return integerInfo_; + } + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const { + return solver_->getColLower(); + } + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const { + return solver_->getColUpper(); + } + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + inline const char * getRowSense() const { + return solver_->getRowSense(); + } + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + inline const double * getRightHandSide() const { + return solver_->getRightHandSide(); + } + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + */ + inline const double * getRowRange() const { + return solver_->getRowRange(); + } + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const { + return solver_->getRowLower(); + } + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const { + return solver_->getRowUpper(); + } + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const { + return solver_->getObjCoefficients(); + } + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const { + //assert (dblParam_[CbcOptimizationDirection]== solver_->getObjSense()); + return dblParam_[CbcOptimizationDirection]; + } + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const { + return solver_->isContinuous(colIndex); + } + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const { + return solver_->isBinary(colIndex); + } + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + inline bool isInteger(int colIndex) const { + return solver_->isInteger(colIndex); + } + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const { + return solver_->isIntegerNonBinary(colIndex); + } + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const { + return solver_->isFreeBinary(colIndex) ; + } + + /// Get pointer to row-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByRow() const { + return solver_->getMatrixByRow(); + } + + /// Get pointer to column-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByCol() const { + return solver_->getMatrixByCol(); + } + + /// Get solver's value for infinity + inline double getInfinity() const { + return solver_->getInfinity(); + } + /// Get pointer to array[getNumCols()] (for speed) of column lower bounds + inline const double * getCbcColLower() const { + return cbcColLower_; + } + /// Get pointer to array[getNumCols()] (for speed) of column upper bounds + inline const double * getCbcColUpper() const { + return cbcColUpper_; + } + /// Get pointer to array[getNumRows()] (for speed) of row lower bounds + inline const double * getCbcRowLower() const { + return cbcRowLower_; + } + /// Get pointer to array[getNumRows()] (for speed) of row upper bounds + inline const double * getCbcRowUpper() const { + return cbcRowUpper_; + } + /// Get pointer to array[getNumCols()] (for speed) of primal solution vector + inline const double * getCbcColSolution() const { + return cbcColSolution_; + } + /// Get pointer to array[getNumRows()] (for speed) of dual prices + inline const double * getCbcRowPrice() const { + return cbcRowPrice_; + } + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + inline const double * getCbcReducedCost() const { + return cbcReducedCost_; + } + /// Get pointer to array[getNumRows()] (for speed) of row activity levels. + inline const double * getCbcRowActivity() const { + return cbcRowActivity_; + } + //@} + + + /**@name Methods related to querying the solution */ + //@{ + /// Holds solution at continuous (after cuts if branchAndBound called) + inline double * continuousSolution() const { + return continuousSolution_; + } + /** Array marked whenever a solution is found if non-zero. + Code marks if heuristic returns better so heuristic + need only mark if it wants to on solutions which + are worse than current */ + inline int * usedInSolution() const { + return usedInSolution_; + } + /// Increases usedInSolution for nonzeros + void incrementUsed(const double * solution); + /// Record a new incumbent solution and update objectiveValue + void setBestSolution(CBC_Message how, + double & objectiveValue, const double *solution, + int fixVariables = 0); + /// Just update objectiveValue + void setBestObjectiveValue( double objectiveValue); + /// Deals with event handler and solution + CbcEventHandler::CbcAction dealWithEventHandler(CbcEventHandler::CbcEvent event, + double objValue, + const double * solution); + + /** Call this to really test if a valid solution can be feasible + Solution is number columns in size. + If fixVariables true then bounds of continuous solver updated. + Returns objective value (worse than cutoff if not feasible) + Previously computed objective value is now passed in (in case user does not do solve) + virtual so user can override + */ + virtual double checkSolution(double cutoff, double * solution, + int fixVariables, double originalObjValue); + /** Test the current solution for feasiblility. + + Scan all objects for indications of infeasibility. This is broken down + into simple integer infeasibility (\p numberIntegerInfeasibilities) + and all other reports of infeasibility (\p numberObjectInfeasibilities). + */ + bool feasibleSolution(int & numberIntegerInfeasibilities, + int & numberObjectInfeasibilities) const; + + /** Solution to the most recent lp relaxation. + + The solver's solution to the most recent lp relaxation. + */ + + inline double * currentSolution() const { + return currentSolution_; + } + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + inline const double * testSolution() const { + return testSolution_; + } + inline void setTestSolution(const double * solution) { + testSolution_ = solution; + } + /// Make sure region there and optionally copy solution + void reserveCurrentSolution(const double * solution = NULL); + + /// Get pointer to array[getNumCols()] of primal solution vector + inline const double * getColSolution() const { + return solver_->getColSolution(); + } + + /// Get pointer to array[getNumRows()] of dual prices + inline const double * getRowPrice() const { + return solver_->getRowPrice(); + } + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const { + return solver_->getReducedCost(); + } + + /// Get pointer to array[getNumRows()] of row activity levels. + inline const double * getRowActivity() const { + return solver_->getRowActivity(); + } + + /// Get current objective function value + inline double getCurrentObjValue() const { + return dblParam_[CbcCurrentObjectiveValue]; + } + /// Get current minimization objective function value + inline double getCurrentMinimizationObjValue() const { + return dblParam_[CbcCurrentMinimizationObjectiveValue]; + } + + /// Get best objective function value as minimization + inline double getMinimizationObjValue() const { + return bestObjective_; + } + /// Set best objective function value as minimization + inline void setMinimizationObjValue(double value) { + bestObjective_ = value; + } + + /// Get best objective function value + inline double getObjValue() const { + return bestObjective_ * solver_->getObjSense() ; + } + /** Get best possible objective function value. + This is better of best possible left on tree + and best solution found. + If called from within branch and cut may be optimistic. + */ + double getBestPossibleObjValue() const; + /// Set best objective function value + inline void setObjValue(double value) { + bestObjective_ = value * solver_->getObjSense() ; + } + /// Get solver objective function value (as minimization) + inline double getSolverObjValue() const { + return solver_->getObjValue() * solver_->getObjSense() ; + } + + /** The best solution to the integer programming problem. + + The best solution to the integer programming problem found during + the search. If no solution is found, the method returns null. + */ + + inline double * bestSolution() const { + return bestSolution_; + } + /** User callable setBestSolution. + If check false does not check valid + If true then sees if feasible and warns if objective value + worse than given (so just set to COIN_DBL_MAX if you don't care). + If check true then does not save solution if not feasible + */ + void setBestSolution(const double * solution, int numberColumns, + double objectiveValue, bool check = false); + + /// Get number of solutions + inline int getSolutionCount() const { + return numberSolutions_; + } + + /// Set number of solutions (so heuristics will be different) + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } + /// Number of saved solutions (including best) + int numberSavedSolutions() const; + /// Maximum number of extra saved solutions + inline int maximumSavedSolutions() const { + return maximumSavedSolutions_; + } + /// Set maximum number of extra saved solutions + void setMaximumSavedSolutions(int value); + /// Return a saved solution (0==best) - NULL if off end + const double * savedSolution(int which) const; + /// Return a saved solution objective (0==best) - COIN_DBL_MAX if off end + double savedSolutionObjective(int which) const; + /// Delete a saved solution and move others up + void deleteSavedSolution(int which); + + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + inline int phase() const { + return phase_; + } + + /// Get number of heuristic solutions + inline int getNumberHeuristicSolutions() const { + return numberHeuristicSolutions_; + } + /// Set number of heuristic solutions + inline void setNumberHeuristicSolutions(int value) { + numberHeuristicSolutions_ = value; + } + + /// Set objective function sense (1 for min (default), -1 for max,) + inline void setObjSense(double s) { + dblParam_[CbcOptimizationDirection] = s; + solver_->setObjSense(s); + } + + /// Value of objective at continuous + inline double getContinuousObjective() const { + return originalContinuousObjective_; + } + inline void setContinuousObjective(double value) { + originalContinuousObjective_ = value; + } + /// Number of infeasibilities at continuous + inline int getContinuousInfeasibilities() const { + return continuousInfeasibilities_; + } + inline void setContinuousInfeasibilities(int value) { + continuousInfeasibilities_ = value; + } + /// Value of objective after root node cuts added + inline double rootObjectiveAfterCuts() const { + return continuousObjective_; + } + /// Sum of Changes to objective by first solve + inline double sumChangeObjective() const { + return sumChangeObjective1_; + } + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + inline int numberGlobalViolations() const { + return numberGlobalViolations_; + } + inline void clearNumberGlobalViolations() { + numberGlobalViolations_ = 0; + } + /// Whether to force a resolve after takeOffCuts + inline bool resolveAfterTakeOffCuts() const { + return resolveAfterTakeOffCuts_; + } + inline void setResolveAfterTakeOffCuts(bool yesNo) { + resolveAfterTakeOffCuts_ = yesNo; + } + /// Maximum number of rows + inline int maximumRows() const { + return maximumRows_; + } + /// Work basis for temporary use + inline CoinWarmStartBasis & workingBasis() { + return workingBasis_; + } + /// Get number of "iterations" to stop after + inline int getStopNumberIterations() const { + return stopNumberIterations_; + } + /// Set number of "iterations" to stop after + inline void setStopNumberIterations(int value) { + stopNumberIterations_ = value; + } + /// A pointer to model from CbcHeuristic + inline CbcModel * heuristicModel() const + { return heuristicModel_;} + /// Set a pointer to model from CbcHeuristic + inline void setHeuristicModel(CbcModel * model) + { heuristicModel_ = model;} + //@} + + /** \name Node selection */ + //@{ + // Comparison functions (which may be overridden by inheritance) + inline CbcCompareBase * nodeComparison() const { + return nodeCompare_; + } + void setNodeComparison(CbcCompareBase * compare); + void setNodeComparison(CbcCompareBase & compare); + //@} + + /** \name Problem feasibility checking */ + //@{ + // Feasibility functions (which may be overridden by inheritance) + inline CbcFeasibilityBase * problemFeasibility() const { + return problemFeasibility_; + } + void setProblemFeasibility(CbcFeasibilityBase * feasibility); + void setProblemFeasibility(CbcFeasibilityBase & feasibility); + //@} + + /** \name Tree methods and subtree methods */ + //@{ + /// Tree method e.g. heap (which may be overridden by inheritance) + inline CbcTree * tree() const { + return tree_; + } + /// For modifying tree handling (original is cloned) + void passInTreeHandler(CbcTree & tree); + /** For passing in an CbcModel to do a sub Tree (with derived tree handlers). + Passed in model must exist for duration of branch and bound + */ + void passInSubTreeModel(CbcModel & model); + /** For retrieving a copy of subtree model with given OsiSolver. + If no subtree model will use self (up to user to reset cutoff etc). + If solver NULL uses current + */ + CbcModel * subTreeModel(OsiSolverInterface * solver = NULL) const; + /// Returns number of times any subtree stopped on nodes, time etc + inline int numberStoppedSubTrees() const { + return numberStoppedSubTrees_; + } + /// Says a sub tree was stopped + inline void incrementSubTreeStopped() { + numberStoppedSubTrees_++; + } + /** Whether to automatically do presolve before branch and bound (subTrees). + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + inline int typePresolve() const { + return presolve_; + } + inline void setTypePresolve(int value) { + presolve_ = value; + } + + //@} + + /** \name Branching Decisions + + See the CbcBranchDecision class for additional information. + */ + //@{ + + /// Get the current branching decision method. + inline CbcBranchDecision * branchingMethod() const { + return branchingMethod_; + } + /// Set the branching decision method. + inline void setBranchingMethod(CbcBranchDecision * method) { + delete branchingMethod_; + branchingMethod_ = method->clone(); + } + /** Set the branching method + + \overload + */ + inline void setBranchingMethod(CbcBranchDecision & method) { + delete branchingMethod_; + branchingMethod_ = method.clone(); + } + /// Get the current cut modifier method + inline CbcCutModifier * cutModifier() const { + return cutModifier_; + } + /// Set the cut modifier method + void setCutModifier(CbcCutModifier * modifier); + /** Set the cut modifier method + + \overload + */ + void setCutModifier(CbcCutModifier & modifier); + //@} + + /** \name Row (constraint) and Column (variable) cut generation */ + //@{ + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + inline int stateOfSearch() const { + return stateOfSearch_; + } + inline void setStateOfSearch(int state) { + stateOfSearch_ = state; + } + /// Strategy worked out - mainly at root node for use by CbcNode + inline int searchStrategy() const { + return searchStrategy_; + } + /// Set strategy worked out - mainly at root node for use by CbcNode + inline void setSearchStrategy(int value) { + searchStrategy_ = value; + } + /// Stong branching strategy + inline int strongStrategy() const { + return strongStrategy_; + } + /// Set strong branching strategy + inline void setStrongStrategy(int value) { + strongStrategy_ = value; + } + + /// Get the number of cut generators + inline int numberCutGenerators() const { + return numberCutGenerators_; + } + /// Get the list of cut generators + inline CbcCutGenerator ** cutGenerators() const { + return generator_; + } + ///Get the specified cut generator + inline CbcCutGenerator * cutGenerator(int i) const { + return generator_[i]; + } + ///Get the specified cut generator before any changes + inline CbcCutGenerator * virginCutGenerator(int i) const { + return virginGenerator_[i]; + } + /** Add one generator - up to user to delete generators. + howoften affects how generator is used. 0 or 1 means always, + >1 means every that number of nodes. Negative values have same + meaning as positive but they may be switched off (-> -100) by code if + not many cuts generated at continuous. -99 is just done at root. + Name is just for printout. + If depth >0 overrides how often generator is called (if howOften==-1 or >0). + */ + void addCutGenerator(CglCutGenerator * generator, + int howOften = 1, const char * name = NULL, + bool normal = true, bool atSolution = false, + bool infeasible = false, int howOftenInSub = -100, + int whatDepth = -1, int whatDepthInSub = -1); +//@} + /** \name Strategy and sub models + + See the CbcStrategy class for additional information. + */ + //@{ + + /// Get the current strategy + inline CbcStrategy * strategy() const { + return strategy_; + } + /// Set the strategy. Clones + void setStrategy(CbcStrategy & strategy); + /// Set the strategy. assigns + inline void setStrategy(CbcStrategy * strategy) { + strategy_ = strategy; + } + /// Get the current parent model + inline CbcModel * parentModel() const { + return parentModel_; + } + /// Set the parent model + inline void setParentModel(CbcModel & parentModel) { + parentModel_ = &parentModel; + } + //@} + + + /** \name Heuristics and priorities */ + //@{ + /*! \brief Add one heuristic - up to user to delete + + The name is just used for print messages. + */ + void addHeuristic(CbcHeuristic * generator, const char *name = NULL, + int before = -1); + ///Get the specified heuristic + inline CbcHeuristic * heuristic(int i) const { + return heuristic_[i]; + } + /// Get the number of heuristics + inline int numberHeuristics() const { + return numberHeuristics_; + } + /// Set the number of heuristics + inline void setNumberHeuristics(int value) { + numberHeuristics_ = value; + } + /// Pointer to heuristic solver which found last solution (or NULL) + inline CbcHeuristic * lastHeuristic() const { + return lastHeuristic_; + } + /// set last heuristic which found a solution + inline void setLastHeuristic(CbcHeuristic * last) { + lastHeuristic_ = last; + } + + /** Pass in branching priorities. + + If ifClique then priorities are on cliques otherwise priorities are + on integer variables. + Other type (if exists set to default) + 1 is highest priority. (well actually -INT_MAX is but that's ugly) + If hotstart > 0 then branches are created to force + the variable to the value given by best solution. This enables a + sort of hot start. The node choice should be greatest depth + and hotstart should normally be switched off after a solution. + + If ifNotSimpleIntegers true then appended to normal integers + + This is now deprecated except for simple usage. If user + creates Cbcobjects then set priority in them + + \internal Added for Kurt Spielberg. + */ + void passInPriorities(const int * priorities, bool ifNotSimpleIntegers); + + /// Returns priority level for an object (or 1000 if no priorities exist) + inline int priority(int sequence) const { + return object_[sequence]->priority(); + } + + /*! \brief Set an event handler + + A clone of the handler passed as a parameter is stored in CbcModel. + */ + void passInEventHandler(const CbcEventHandler *eventHandler) ; + + /*! \brief Retrieve a pointer to the event handler */ + inline CbcEventHandler* getEventHandler() const { + return (eventHandler_) ; + } + + //@} + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + + /// Get application data + void * getApplicationData() const; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. Information could be built into + OsiSolverInterface but this is an alternative so that that interface + does not have to be changed. If something similar is useful to + enough solvers then it could be migrated + You can also pass in by using solver->setAuxiliaryInfo. + You should do that if solver is odd - if solver is normal simplex + then use this. + NOTE - characteristics are not cloned + */ + void passInSolverCharacteristics(OsiBabSolver * solverCharacteristics); + /// Get solver characteristics + inline const OsiBabSolver * solverCharacteristics() const { + return solverCharacteristics_; + } + //@} + + //--------------------------------------------------------------------------- + + /**@name Message handling etc */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages & messages() { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return &messages_; + } + /// Set log level + void setLogLevel(int value); + /// Get log level + inline int logLevel() const { + return handler_->logLevel(); + } + /** Set flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + inline void setDefaultHandler(bool yesNo) { + defaultHandler_ = yesNo; + } + /// Check default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + //@} + //--------------------------------------------------------------------------- + ///@name Specialized + //@{ + + /** + Set special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + inline void setSpecialOptions(int value) { + specialOptions_ = value; + } + /// Get special options + inline int specialOptions() const { + return specialOptions_; + } + /// Set random seed + inline void setRandomSeed(int value) { + randomSeed_ = value; + } + /// Get random seed + inline int getRandomSeed() const { + return randomSeed_; + } + /// Set multiple root tries + inline void setMultipleRootTries(int value) { + multipleRootTries_ = value; + } + /// Get multiple root tries + inline int getMultipleRootTries() const { + return multipleRootTries_; + } + /// Tell model to stop on event + inline void sayEventHappened() + { eventHappened_=true;} + /// Says if normal solver i.e. has well defined CoinPackedMatrix + inline bool normalSolver() const { + return (specialOptions_&16) == 0; + } + /** Says if model is sitting there waiting for mini branch and bound to finish + This is because an event handler may only have access to parent model in + mini branch and bound + */ + inline bool waitingForMiniBranchAndBound() const { + return (specialOptions_&1048576) != 0; + } + /** Set more special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + 22 bit (4194304) - Conflict analysis + 23 bit (8388608) - Conflict analysis - temporary bit + 24 bit (16777216) - Add cutoff as LP constraint (out) + 25 bit (33554432) - diving/reordering + 26 bit (67108864) - load global cuts from file + 27 bit (134217728) - append binding global cuts to file + 28 bit (268435456) - idiot branching + 29 bit (536870912) - don't make fake objective + 30 bit (1073741824) - Funny SOS or similar - be careful + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + /// Get more special options + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + 13/14 bit 8192 - go to bitter end in strong branching (first time) + */ + inline void setMoreSpecialOptions2(int value) { + moreSpecialOptions2_ = value; + } + /// Get more special options2 + inline int moreSpecialOptions2() const { + return moreSpecialOptions2_; + } + /// Set cutoff as constraint + inline void setCutoffAsConstraint(bool yesNo) { + cutoffRowNumber_ = (yesNo) ? -2 : -1; + } + /// Set time method + inline void setUseElapsedTime(bool yesNo) { + if (yesNo) + moreSpecialOptions_ |= 131072; + else + moreSpecialOptions_ &= ~131072; + } + /// Get time method + inline bool useElapsedTime() const { + return (moreSpecialOptions_&131072)!=0; + } + /// Get useful temporary pointer + inline void * temporaryPointer() const + { return temporaryPointer_;} + /// Set useful temporary pointer + inline void setTemporaryPointer(void * pointer) + { temporaryPointer_=pointer;} + /// Go to dantzig pivot selection if easy problem (clp only) + void goToDantzig(int numberNodes, ClpDualRowPivot *& savePivotMethod); + /// Now we may not own objects - just point to solver's objects + inline bool ownObjects() const { + return ownObjects_; + } + /// Check original model before it gets messed up + void checkModel(); + //@} + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcModel(); + + /// Constructor from solver + CbcModel(const OsiSolverInterface &); + + /** Assign a solver to the model (model assumes ownership) + + On return, \p solver will be NULL. + If deleteSolver then current solver deleted (if model owned) + + \note Parameter settings in the outgoing solver are not inherited by + the incoming solver. + */ + void assignSolver(OsiSolverInterface *&solver, bool deleteSolver = true); + + /** \brief Set ownership of solver + + A parameter of false tells CbcModel it does not own the solver and + should not delete it. Once you claim ownership of the solver, you're + responsible for eventually deleting it. Note that CbcModel clones + solvers with abandon. Unless you have a deep understanding of the + workings of CbcModel, the only time you want to claim ownership is when + you're about to delete the CbcModel object but want the solver to + continue to exist (as, for example, when branchAndBound has finished + and you want to hang on to the answer). + */ + inline void setModelOwnsSolver (bool ourSolver) { + ownership_ = ourSolver ? (ownership_ | 0x80000000) : (ownership_ & (~0x80000000)) ; + } + + /*! \brief Get ownership of solver + + A return value of true means that CbcModel owns the solver and will + take responsibility for deleting it when that becomes necessary. + */ + inline bool modelOwnsSolver () { + return ((ownership_&0x80000000) != 0) ; + } + + /** Copy constructor . + If cloneHandler is true then message handler is cloned + */ + CbcModel(const CbcModel & rhs, bool cloneHandler = false); + + /** Clone */ + virtual CbcModel *clone (bool cloneHandler); + + /// Assignment operator + CbcModel & operator=(const CbcModel& rhs); + + /// Destructor + virtual ~CbcModel (); + + /// Returns solver - has current state + inline OsiSolverInterface * solver() const { + return solver_; + } + + /// Returns current solver - sets new one + inline OsiSolverInterface * swapSolver(OsiSolverInterface * solver) { + OsiSolverInterface * returnSolver = solver_; + solver_ = solver; + return returnSolver; + } + + /// Returns solver with continuous state + inline OsiSolverInterface * continuousSolver() const { + return continuousSolver_; + } + + /// Create solver with continuous state + inline void createContinuousSolver() { + continuousSolver_ = solver_->clone(); + } + /// Clear solver with continuous state + inline void clearContinuousSolver() { + delete continuousSolver_; + continuousSolver_ = NULL; + } + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + inline OsiSolverInterface * referenceSolver() const { + return referenceSolver_; + } + + /// Save a copy of the current solver so can be reset to + void saveReferenceSolver(); + + /** Uses a copy of reference solver to be current solver. + Because of possible mismatches all exotic integer information is loat + (apart from normal information in OsiSolverInterface) + so SOS etc and priorities will have to be redone + */ + void resetToReferenceSolver(); + + /// Clears out as much as possible (except solver) + void gutsOfDestructor(); + /** Clears out enough to reset CbcModel as if no branch and bound done + */ + void gutsOfDestructor2(); + /** Clears out enough to reset CbcModel cutoff etc + */ + void resetModel(); + /** Most of copy constructor + mode - 0 copy but don't delete before + 1 copy and delete before + 2 copy and delete before (but use virgin generators) + */ + void gutsOfCopy(const CbcModel & rhs, int mode = 0); + /// Move status, nodes etc etc across + void moveInfo(const CbcModel & rhs); + //@} + + ///@name Multithreading + //@{ + /// Indicates whether Cbc library has been compiled with multithreading support + static bool haveMultiThreadSupport(); + /// Get pointer to masterthread + CbcThread * masterThread() const { + return masterThread_; + } + /// Get pointer to walkback + CbcNodeInfo ** walkback() const { + return walkback_; + } + /// Get number of threads + inline int getNumberThreads() const { + return numberThreads_; + } + /// Set number of threads + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + /// Get thread mode + inline int getThreadMode() const { + return threadMode_; + } + /** Set thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + 8 set and numberThreads - do heuristics numberThreads at a time + 8 set and numberThreads==0 do all heuristics at once + default is 0 + */ + inline void setThreadMode(int value) { + threadMode_ = value; + } + /** Return + -2 if deterministic threaded and main thread + -1 if deterministic threaded and serial thread + 0 if serial + 1 if opportunistic threaded + */ + inline int parallelMode() const { + if (!numberThreads_) { + if ((threadMode_&1) == 0) + return 0; + else + return -1; + return 0; + } else { + if ((threadMode_&1) == 0) + return 1; + else + return -2; + } + } + /// Thread stuff for master + inline CbcBaseModel * master() const + { return master_;} + /// From here to end of section - code in CbcThread.cpp until class changed + /// Returns true if locked + bool isLocked() const; +#ifdef CBC_THREAD + /** + Locks a thread if parallel so that stuff like cut pool + can be updated and/or used. + */ + void lockThread(); + /** + Unlocks a thread if parallel to say cut pool stuff not needed + */ + void unlockThread(); +#else + inline void lockThread() {} + inline void unlockThread() {} +#endif + /** Set information in a child + -3 pass pointer to child thread info + -2 just stop + -1 delete simple child stuff + 0 delete opportunistic child stuff + 1 delete deterministic child stuff + */ + void setInfoInChild(int type, CbcThread * info); + /** Move/copy information from one model to another + -1 - initialization + 0 - from base model + 1 - to base model (and reset) + 2 - add in final statistics etc (and reset so can do clean destruction) + */ + void moveToModel(CbcModel * baseModel, int mode); + /// Split up nodes + int splitModel(int numberModels, CbcModel ** model, + int numberNodes); + /// Start threads + void startSplitModel(int numberIterations); + /// Merge models + void mergeModels(int numberModel, CbcModel ** model, + int numberNodes); + //@} + + ///@name semi-private i.e. users should not use + //@{ + /// Get how many Nodes it took to solve the problem. + int getNodeCount2() const { + return numberNodes2_; + } + /// Set pointers for speed + void setPointers(const OsiSolverInterface * solver); + /** Perform reduced cost fixing + + Fixes integer variables at their current value based on reduced cost + penalties. Returns number fixed + */ + int reducedCostFix() ; + /** Makes all handlers same. If makeDefault 1 then makes top level + default and rest point to that. If 2 then each is copy + */ + void synchronizeHandlers(int makeDefault); + /// Save a solution to saved list + void saveExtraSolution(const double * solution, double objectiveValue); + /// Save a solution to best and move current to saved + void saveBestSolution(const double * solution, double objectiveValue); + /// Delete best and saved solutions + void deleteSolutions(); + /// Encapsulates solver resolve + int resolve(OsiSolverInterface * solver); +#ifdef CLP_RESOLVE + /// Special purpose resolve + int resolveClp(OsiClpSolverInterface * solver, int type); +#endif + + /** Encapsulates choosing a variable - + anyAction -2, infeasible (-1 round again), 0 done + */ + int chooseBranch(CbcNode * & newNode, int numberPassesLeft, + CbcNode * oldNode, OsiCuts & cuts, + bool & resolved, CoinWarmStartBasis *lastws, + const double * lowerBefore, const double * upperBefore, + OsiSolverBranch * & branches); + int chooseBranch(CbcNode * newNode, int numberPassesLeft, bool & resolved); + + /** Return an empty basis object of the specified size + + A useful utility when constructing a basis for a subproblem from scratch. + The object returned will be of the requested capacity and appropriate for + the solver attached to the model. + */ + CoinWarmStartBasis *getEmptyBasis(int ns = 0, int na = 0) const ; + + /** Remove inactive cuts from the model + + An OsiSolverInterface is expected to maintain a valid basis, but not a + valid solution, when loose cuts are deleted. Restoring a valid solution + requires calling the solver to reoptimise. If it's certain the solution + will not be required, set allowResolve to false to suppress + reoptimisation. + If saveCuts then slack cuts will be saved + On input current cuts are cuts and newCuts + on exit current cuts will be correct. Returns number dropped + */ + int takeOffCuts(OsiCuts &cuts, + bool allowResolve, OsiCuts * saveCuts, + int numberNewCuts = 0, const OsiRowCut ** newCuts = NULL) ; + + /** Determine and install the active cuts that need to be added for + the current subproblem + + The whole truth is a bit more complicated. The first action is a call to + addCuts1(). addCuts() then sorts through the list, installs the tight + cuts in the model, and does bookkeeping (adjusts reference counts). + The basis returned from addCuts1() is adjusted accordingly. + + If it turns out that the node should really be fathomed by bound, + addCuts() simply treats all the cuts as loose as it does the bookkeeping. + + */ + int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws); + + /** Traverse the tree from node to root and prep the model + + addCuts1() begins the job of prepping the model to match the current + subproblem. The model is stripped of all cuts, and the search tree is + traversed from node to root to determine the changes required. Appropriate + bounds changes are installed, a list of cuts is collected but not + installed, and an appropriate basis (minus the cuts, but big enough to + accommodate them) is constructed. + + Returns true if new problem similar to old + + \todo addCuts1() is called in contexts where it's known in advance that + all that's desired is to determine a list of cuts and do the + bookkeeping (adjust the reference counts). The work of installing + bounds and building a basis goes to waste. + */ + bool addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws); + /** Returns bounds just before where - initially original bounds. + Also sets downstream nodes (lower if force 1, upper if 2) + */ + void previousBounds (CbcNode * node, CbcNodeInfo * where, int iColumn, + double & lower, double & upper, int force); + /** Set objective value in a node. This is separated out so that + odd solvers can use. It may look at extra information in + solverCharacteriscs_ and will also use bound from parent node + */ + void setObjectiveValue(CbcNode * thisNode, const CbcNode * parentNode) const; + + /** If numberBeforeTrust >0 then we are going to use CbcBranchDynamic. + Scan and convert CbcSimpleInteger objects + */ + void convertToDynamic(); + /// Set numberBeforeTrust in all objects + void synchronizeNumberBeforeTrust(int type = 0); + /// Zap integer information in problem (may leave object info) + void zapIntegerInformation(bool leaveObjects = true); + /// Use cliques for pseudocost information - return nonzero if infeasible + int cliquePseudoCosts(int doStatistics); + /// Fill in useful estimates + void pseudoShadow(int type); + /** Return pseudo costs + If not all integers or not pseudo costs - returns all zero + Length of arrays are numberIntegers() and entries + correspond to integerVariable()[i] + User must allocate arrays before call + */ + void fillPseudoCosts(double * downCosts, double * upCosts, + int * priority = NULL, + int * numberDown = NULL, int * numberUp = NULL, + int * numberDownInfeasible = NULL, + int * numberUpInfeasible = NULL) const; + /** Do heuristics at root. + 0 - don't delete + 1 - delete + 2 - just delete - don't even use + */ + void doHeuristicsAtRoot(int deleteHeuristicsAfterwards = 0); + /// Adjust heuristics based on model + void adjustHeuristics(); + /// Get the hotstart solution + inline const double * hotstartSolution() const { + return hotstartSolution_; + } + /// Get the hotstart priorities + inline const int * hotstartPriorities() const { + return hotstartPriorities_; + } + + /// Return the list of cuts initially collected for this subproblem + inline CbcCountRowCut ** addedCuts() const { + return addedCuts_; + } + /// Number of entries in the list returned by #addedCuts() + inline int currentNumberCuts() const { + return currentNumberCuts_; + } + /// Global cuts + inline CbcRowCuts * globalCuts() { + return &globalCuts_; + } + /// Get rid of global cuts + inline void zapGlobalCuts() { + globalCuts_ = CbcRowCuts(); + } + /// Copy and set a pointer to a row cut which will be added instead of normal branching. + void setNextRowCut(const OsiRowCut & cut); + /// Get a pointer to current node (be careful) + inline CbcNode * currentNode() const { + return currentNode_; + } + /// Get a pointer to probing info + inline CglTreeProbingInfo * probingInfo() const { + return probingInfo_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Set the number of iterations done in strong branching. + inline void setNumberStrongIterations(int number) { + numberStrongIterations_ = number; + } + /// Get the number of iterations done in strong branching. + inline int numberStrongIterations() const { + return numberStrongIterations_; + } + /// Get maximum number of iterations (designed to be used in heuristics) + inline int maximumNumberIterations() const { + return maximumNumberIterations_; + } + /// Set maximum number of iterations (designed to be used in heuristics) + inline void setMaximumNumberIterations(int value) { + maximumNumberIterations_ = value; + } + /// Symmetry information + inline CbcSymmetry * symmetryInfo() const + { return symmetryInfo_;} + /// Set depth for fast nodes + inline void setFastNodeDepth(int value) { + fastNodeDepth_ = value; + } + /// Get depth for fast nodes + inline int fastNodeDepth() const { + return fastNodeDepth_; + } + /// Get anything with priority >= this can be treated as continuous + inline int continuousPriority() const { + return continuousPriority_; + } + /// Set anything with priority >= this can be treated as continuous + inline void setContinuousPriority(int value) { + continuousPriority_ = value; + } + inline void incrementExtra(int nodes, int iterations, int fathoms=1) { + numberExtraNodes_ += nodes; + numberExtraIterations_ += iterations; + numberFathoms_ += fathoms; + } + /// Zero extra + inline void zeroExtra() { + numberExtraNodes_ = 0; + numberExtraIterations_ = 0; + numberFathoms_ = 0; + } + /// Number of extra iterations + inline int numberExtraIterations() const { + return numberExtraIterations_; + } + /// Increment strong info + void incrementStrongInfo(int numberTimes, int numberIterations, + int numberFixed, bool ifInfeasible); + /// Return strong info + inline const int * strongInfo() const { + return strongInfo_; + } + + /// Return mutable strong info + inline int * mutableStrongInfo() { + return strongInfo_; + } + /// Get stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts() const { + return storedRowCuts_; + } + /// Set stored row cuts for donor/recipient CbcModel + void setStoredRowCuts(CglStored * cuts) { + storedRowCuts_ = cuts; + } + /// Says whether all dynamic integers + inline bool allDynamic () const { + return ((ownership_&0x40000000) != 0) ; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, int options); + /// Generate an OsiBranchingInformation object + OsiBranchingInformation usefulInformation() const; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + inline void setBestSolutionBasis(const CoinWarmStartBasis & bestSolutionBasis) { + bestSolutionBasis_ = bestSolutionBasis; + } + /// Redo walkback arrays + void redoWalkBack(); + //@} + + void setMIPStart( const std::vector< std::pair< std::string, double > > &mips ) { + this->mipStart_ = mips; + } + + const std::vector< std::pair< std::string, double > > &getMIPStart() { + return this->mipStart_; + } + + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + + /// The solver associated with this model. + OsiSolverInterface * solver_; + + /** Ownership of objects and other stuff + + 0x80000000 model owns solver + 0x40000000 all variables CbcDynamicPseudoCost + */ + unsigned int ownership_ ; + + /// A copy of the solver, taken at the continuous (root) node. + OsiSolverInterface * continuousSolver_; + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + OsiSolverInterface * referenceSolver_; + + /// Message handler + CoinMessageHandler * handler_; + + /** Flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + bool defaultHandler_; + + /// Cbc messages + CoinMessages messages_; + + /// Array for integer parameters + int intParam_[CbcLastIntParam]; + + /// Array for double parameters + double dblParam_[CbcLastDblParam]; + + /** Pointer to an empty warm start object + + It turns out to be useful to have this available as a base from + which to build custom warm start objects. This is typed as CoinWarmStart + rather than CoinWarmStartBasis to allow for the possibility that a + client might want to apply a solver that doesn't use a basis-based warm + start. See getEmptyBasis for an example of how this field can be used. + */ + mutable CoinWarmStart *emptyWarmStart_ ; + + /// Best objective + double bestObjective_; + /// Best possible objective + double bestPossibleObjective_; + /// Sum of Changes to objective by first solve + double sumChangeObjective1_; + /// Sum of Changes to objective by subsequent solves + double sumChangeObjective2_; + + /// Array holding the incumbent (best) solution. + double * bestSolution_; + /// Arrays holding other solutions. + double ** savedSolutions_; + + /** Array holding the current solution. + + This array is used more as a temporary. + */ + double * currentSolution_; + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + mutable const double * testSolution_; + /** MIPstart values + values for integer variables which will be converted to a complete integer initial feasible solution + */ + std::vector< std::pair< std::string, double > > mipStart_; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + CoinWarmStartBasis bestSolutionBasis_ ; + /// Global cuts + CbcRowCuts globalCuts_; + /// Global conflict cuts + CbcRowCuts * globalConflictCuts_; + + /// Minimum degradation in objective value to continue cut generation + double minimumDrop_; + /// Number of solutions + int numberSolutions_; + /// Number of saved solutions + int numberSavedSolutions_; + /// Maximum number of saved solutions + int maximumSavedSolutions_; + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// At which depths to do cuts + int whenCuts_; + /// Hotstart solution + double * hotstartSolution_; + /// Hotstart priorities + int * hotstartPriorities_; + /// Number of heuristic solutions + int numberHeuristicSolutions_; + /// Cumulative number of nodes + int numberNodes_; + /** Cumulative number of nodes for statistics. + Must fix to match up + */ + int numberNodes2_; + /// Cumulative number of iterations + int numberIterations_; + /// Cumulative number of solves + int numberSolves_; + /// Status of problem - 0 finished, 1 stopped, 2 difficulties + int status_; + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + */ + int secondaryStatus_; + /// Number of integers in problem + int numberIntegers_; + /// Number of rows at continuous + int numberRowsAtContinuous_; + /** + -1 - cutoff as constraint not activated + -2 - waiting to activate + >=0 - activated + */ + int cutoffRowNumber_; + /// Maximum number of cuts + int maximumNumberCuts_; + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + int phase_; + + /// Number of entries in #addedCuts_ + int currentNumberCuts_; + + /** Current limit on search tree depth + + The allocated size of #walkback_. Increased as needed. + */ + int maximumDepth_; + /** Array used to assemble the path between a node and the search tree root + + The array is resized when necessary. #maximumDepth_ is the current + allocated size. + */ + CbcNodeInfo ** walkback_; + CbcNodeInfo ** lastNodeInfo_; + const OsiRowCut ** lastCut_; + int lastDepth_; + int lastNumberCuts2_; + int maximumCuts_; + int * lastNumberCuts_; + + /** The list of cuts initially collected for this subproblem + + When the subproblem at this node is rebuilt, a set of cuts is collected + for inclusion in the constraint system. If any of these cuts are + subsequently removed because they have become loose, the corresponding + entry is set to NULL. + */ + CbcCountRowCut ** addedCuts_; + + /** A pointer to a row cut which will be added instead of normal branching. + After use it should be set to NULL. + */ + OsiRowCut * nextRowCut_; + + /// Current node so can be used elsewhere + CbcNode * currentNode_; + + /// Indices of integer variables + int * integerVariable_; + /// Whether of not integer + char * integerInfo_; + /// Holds solution at continuous (after cuts) + double * continuousSolution_; + /// Array marked whenever a solution is found if non-zero + int * usedInSolution_; + /** + Special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + int specialOptions_; + /** More special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + */ + int moreSpecialOptions_; + /** More more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + */ + int moreSpecialOptions2_; + /// User node comparison function + CbcCompareBase * nodeCompare_; + /// User feasibility function (see CbcFeasibleBase.hpp) + CbcFeasibilityBase * problemFeasibility_; + /// Tree + CbcTree * tree_; + /// Pointer to top of tree + CbcFullNodeInfo * topOfTree_; + /// A pointer to model to be used for subtrees + CbcModel * subTreeModel_; + /// A pointer to model from CbcHeuristic + CbcModel * heuristicModel_; + /// Number of times any subtree stopped on nodes, time etc + int numberStoppedSubTrees_; + /// Variable selection function + CbcBranchDecision * branchingMethod_; + /// Cut modifier function + CbcCutModifier * cutModifier_; + /// Strategy + CbcStrategy * strategy_; + /// Parent model + CbcModel * parentModel_; + /** Whether to automatically do presolve before branch and bound. + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + /// Pointer to array[getNumCols()] (for speed) of column lower bounds + const double * cbcColLower_; + /// Pointer to array[getNumCols()] (for speed) of column upper bounds + const double * cbcColUpper_; + /// Pointer to array[getNumRows()] (for speed) of row lower bounds + const double * cbcRowLower_; + /// Pointer to array[getNumRows()] (for speed) of row upper bounds + const double * cbcRowUpper_; + /// Pointer to array[getNumCols()] (for speed) of primal solution vector + const double * cbcColSolution_; + /// Pointer to array[getNumRows()] (for speed) of dual prices + const double * cbcRowPrice_; + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + const double * cbcReducedCost_; + /// Pointer to array[getNumRows()] (for speed) of row activity levels. + const double * cbcRowActivity_; + /// Pointer to user-defined data structure + void * appData_; + /// Presolve for CbcTreeLocal + int presolve_; + /** Maximum number of candidates to consider for strong branching. + To disable strong branching, set this to 0. + */ + int numberStrong_; + /** \brief The number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 is off. + */ + int numberBeforeTrust_; + /** \brief The number of variables for which to compute penalties + in dynamic strong branching. + */ + int numberPenalties_; + /// For threads - stop after this many "iterations" + int stopNumberIterations_; + /** Scale factor to make penalties match strong. + Should/will be computed */ + double penaltyScaleFactor_; + /// Number of analyze iterations to do + int numberAnalyzeIterations_; + /// Arrays with analysis results + double * analyzeResults_; + /// Useful temporary pointer + void * temporaryPointer_; + /// Number of nodes infeasible by normal branching (before cuts) + int numberInfeasibleNodes_; + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + */ + int problemType_; + /// Print frequency + int printFrequency_; + /// Number of cut generators + int numberCutGenerators_; + // Cut generators + CbcCutGenerator ** generator_; + // Cut generators before any changes + CbcCutGenerator ** virginGenerator_; + /// Number of heuristics + int numberHeuristics_; + /// Heuristic solvers + CbcHeuristic ** heuristic_; + /// Pointer to heuristic solver which found last solution (or NULL) + CbcHeuristic * lastHeuristic_; + /// Depth for fast nodes + int fastNodeDepth_; + /*! Pointer to the event handler */ +# ifdef CBC_ONLY_CLP + ClpEventHandler *eventHandler_ ; +# else + CbcEventHandler *eventHandler_ ; +# endif + /// Symmetry information + CbcSymmetry * symmetryInfo_; + /// Total number of objects + int numberObjects_; + + /** \brief Integer and Clique and ... information + + \note The code assumes that the first objects on the list will be + SimpleInteger objects for each integer variable, followed by + Clique objects. Portions of the code that understand Clique objects + will fail if they do not immediately follow the SimpleIntegers. + Large chunks of the code will fail if the first objects are not + SimpleInteger. As of 2003.08, SimpleIntegers and Cliques are the only + objects. + */ + OsiObject ** object_; + /// Now we may not own objects - just point to solver's objects + bool ownObjects_; + + /// Original columns as created by integerPresolve or preprocessing + int * originalColumns_; + /// How often to scan global cuts + int howOftenGlobalScan_; + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + int numberGlobalViolations_; + /// Number of extra iterations in fast lp + int numberExtraIterations_; + /// Number of extra nodes in fast lp + int numberExtraNodes_; + /// Number of times fast lp entered + int numberFathoms_; + /** Value of objective at continuous + (Well actually after initial round of cuts) + */ + double continuousObjective_; + /** Value of objective before root node cuts added + */ + double originalContinuousObjective_; + /// Number of infeasibilities at continuous + int continuousInfeasibilities_; + /// Maximum number of cut passes at root + int maximumCutPassesAtRoot_; + /// Maximum number of cut passes + int maximumCutPasses_; + /// Preferred way of branching + int preferredWay_; + /// Current cut pass number + int currentPassNumber_; + /// Maximum number of cuts (for whichGenerator_) + int maximumWhich_; + /// Maximum number of rows + int maximumRows_; + /// Random seed + int randomSeed_; + /// Multiple root tries + int multipleRootTries_; + /// Current depth + int currentDepth_; + /// Thread specific random number generator + mutable CoinThreadRandom randomNumberGenerator_; + /// Work basis for temporary use + CoinWarmStartBasis workingBasis_; + /// Which cut generator generated this cut + int * whichGenerator_; + /// Maximum number of statistics + int maximumStatistics_; + /// statistics + CbcStatistics ** statistics_; + /// Maximum depth reached + int maximumDepthActual_; + /// Number of reduced cost fixings + double numberDJFixed_; + /// Probing info + CglTreeProbingInfo * probingInfo_; + /// Number of fixed by analyze at root + int numberFixedAtRoot_; + /// Number fixed by analyze so far + int numberFixedNow_; + /// Whether stopping on gap + bool stoppedOnGap_; + /// Whether event happened + mutable bool eventHappened_; + /// Number of long strong goes + int numberLongStrong_; + /// Number of old active cuts + int numberOldActiveCuts_; + /// Number of new cuts + int numberNewCuts_; + /// Strategy worked out - mainly at root node + int searchStrategy_; + /** Strategy for strong branching + 0 - normal + when to do all fractional + 1 - root node + 2 - depth less than modifier + 4 - if objective == best possible + 6 - as 2+4 + when to do all including satisfied + 10 - root node etc. + If >=100 then do when depth <= strategy/100 (otherwise 5) + */ + int strongStrategy_; + /// Number of iterations in strong branching + int numberStrongIterations_; + /** 0 - number times strong branching done, 1 - number fixed, 2 - number infeasible + Second group of three is a snapshot at node [6] */ + int strongInfo_[7]; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. This gives characteristics - just for one BAB. + For actually saving/restoring a solution you need the actual solver one. + */ + OsiBabSolver * solverCharacteristics_; + /// Whether to force a resolve after takeOffCuts + bool resolveAfterTakeOffCuts_; + /// Maximum number of iterations (designed to be used in heuristics) + int maximumNumberIterations_; + /// Anything with priority >= this can be treated as continuous + int continuousPriority_; + /// Number of outstanding update information items + int numberUpdateItems_; + /// Maximum number of outstanding update information items + int maximumNumberUpdateItems_; + /// Update items + CbcObjectUpdateData * updateItems_; + /// Stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts_; + /** + Parallel + 0 - off + 1 - testing + 2-99 threads + other special meanings + */ + int numberThreads_; + /** thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + default is 0 + */ + int threadMode_; + /// Number of global cuts on entry to a node + int numberGlobalCutsIn_; + /// Thread stuff for master + CbcBaseModel * master_; + /// Pointer to masterthread + CbcThread * masterThread_; +//@} +}; +/// So we can use osiObject or CbcObject during transition +void getIntegerInformation(const OsiObject * object, double & originalLower, + double & originalUpper) ; +// So we can call from other programs +// Real main program +class OsiClpSolverInterface; +int CbcMain (int argc, const char *argv[], OsiClpSolverInterface & solver, CbcModel ** babSolver); +int CbcMain (int argc, const char *argv[], CbcModel & babSolver); +// four ways of calling +int callCbc(const char * input2, OsiClpSolverInterface& solver1); +int callCbc(const char * input2); +int callCbc(const std::string input2, OsiClpSolverInterface& solver1); +int callCbc(const std::string input2) ; +// When we want to load up CbcModel with options first +void CbcMain0 (CbcModel & babSolver); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver); +// two ways of calling +int callCbc(const char * input2, CbcModel & babSolver); +int callCbc(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize +int callCbc1(const char * input2, CbcModel & babSolver); +int callCbc1(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize (with call back) (see CbcMain1 for whereFrom) +int callCbc1(const char * input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int callCbc1(const std::string input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +// For uniform setting of cut and heuristic options +void setCutAndHeuristicOptions(CbcModel & model); +#endif + diff --git a/thirdparty/linux/include/coin/CbcNWay.hpp b/thirdparty/linux/include/coin/CbcNWay.hpp new file mode 100644 index 0000000..d74c724 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcNWay.hpp @@ -0,0 +1,166 @@ +// $Id: CbcNWay.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +/** Define an n-way class for variables. + Only valid value is one at UB others at LB + Normally 0-1 +*/ +#ifndef CbcNWay_H +#define CbcNWay_H + +class CbcNWay : public CbcObject { + +public: + + // Default Constructor + CbcNWay (); + + /** Useful constructor (which are matrix indices) + */ + CbcNWay (CbcModel * model, int numberMembers, + const int * which, int identifier); + + // Copy constructor + CbcNWay ( const CbcNWay &); + + /// Clone + virtual CbcObject * clone() const; + + /// Assignment operator + CbcNWay & operator=( const CbcNWay& rhs); + + /// Destructor + virtual ~CbcNWay (); + + /// Set up a consequence for a single member + void setConsequence(int iColumn, const CbcConsequence & consequence); + + /// Applies a consequence for a single member + void applyConsequence(int iSequence, int state) const; + + /// Infeasibility - large is 0.5 (and 0.5 will give this) + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const { + return members_; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Number of members + int numberMembers_; + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /// Consequences (normally NULL) + CbcConsequence ** consequence_; +}; +/** N way branching Object class. + Variable is number of set. + */ +class CbcNWayBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcNWayBranchingObject (); + + /** Useful constructor - order had matrix indices + way_ -1 corresponds to setting first, +1 to second, +3 etc. + this is so -1 and +1 have similarity to normal + */ + CbcNWayBranchingObject (CbcModel * model, const CbcNWay * nway, + int numberBranches, const int * order); + + // Copy constructor + CbcNWayBranchingObject ( const CbcNWayBranchingObject &); + + // Assignment operator + CbcNWayBranchingObject & operator=( const CbcNWayBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcNWayBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + +#ifdef JJF_ZERO + // FIXME: what do we need to do here? + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /** The number of branch arms created for this branching object + */ + virtual int numberBranches() const { + return numberInSet_; + } + /// Is this a two way object (-1 down, +1 up) + virtual bool twoWay() const { + return false; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return NWayBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// order of branching - points back to CbcNWay + int * order_; + /// Points back to object + const CbcNWay * object_; + /// Number in set + int numberInSet_; +}; +#endif diff --git a/thirdparty/linux/include/coin/CbcNode.hpp b/thirdparty/linux/include/coin/CbcNode.hpp new file mode 100644 index 0000000..69b6737 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcNode.hpp @@ -0,0 +1,351 @@ +/* $Id: CbcNode.hpp 1957 2013-08-27 15:19:55Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcNode_H +#define CbcNode_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" +#include "CbcFullNodeInfo.hpp" +#include "CbcPartialNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +/** Information required while the node is live + + When a subproblem is initially created, it is represented by an CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information (depth, branching instructions), that's + needed while the subproblem remains `live', <i>i.e.</i>, while the + subproblem is not fathomed and there are branch arms still be be + evaluated. The CbcNode is deleted when the last branch arm has been + evaluated. + + The CbcNodeInfo object contains the information needed to maintain the + search tree and recreate the subproblem for the node. It remains in + existence until there are no nodes remaining in the subtree rooted at this + node. +*/ + +class CbcNode : public CoinTreeNode { + +public: + + /// Default Constructor + CbcNode (); + + /// Construct and increment parent reference count + CbcNode (CbcModel * model, CbcNode * lastNode); + + /// Copy constructor + CbcNode (const CbcNode &); + + /// Assignment operator + CbcNode & operator= (const CbcNode& rhs); + + /// Destructor + ~CbcNode (); + + /** Create a description of the subproblem at this node + + The CbcNodeInfo structure holds the information (basis & variable bounds) + required to recreate the subproblem for this node. It also links the node + to its parent (via the parent's CbcNodeInfo object). + + If lastNode == NULL, a CbcFullNodeInfo object will be created. All + parameters except \p model are unused. + + If lastNode != NULL, a CbcPartialNodeInfo object will be created. Basis and + bounds information will be stored in the form of differences between the + parent subproblem and this subproblem. + (More precisely, \p lastws, \p lastUpper, \p lastLower, + \p numberOldActiveCuts, and \p numberNewCuts are used.) + */ + void + createInfo(CbcModel * model, + CbcNode * lastNode, + const CoinWarmStartBasis *lastws, + const double * lastLower, const double * lastUpper, + int numberOldActiveCuts, int numberNewCuts); + + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseBranch (CbcModel * model, + CbcNode * lastNode, + int numberPassesLeft); + /** Create a branching object for the node - when dynamic pseudo costs + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + This version gives preference in evaluation to variables which + have not been evaluated many times. It also uses numberStrong + to say give up if last few tries have not changed incumbent. + See Achterberg, Koch and Martin. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + <li> >0: Number of quich branching objects (and branches will be non NULL) + </ul> + */ + int chooseDynamicBranch (CbcModel * model, + CbcNode * lastNode, + OsiSolverBranch * & branches, + int numberPassesLeft); + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + Branch state: + <ul> + <li> -1: start + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseOsiBranch (CbcModel * model, + CbcNode * lastNode, + OsiBranchingInformation * usefulInfo, + int branchState); + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. It then solves a + series of problems and a CbcGeneral branch object is installed. + + If evaluation determines that an object is infeasible, + the routine returns immediately. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseClpBranch (CbcModel * model, + CbcNode * lastNode); + int analyze(CbcModel * model, double * results); + /// Decrement active cut counts + void decrementCuts(int change = 1); + + /// Decrement all active cut counts in chain starting at parent + void decrementParentCuts(CbcModel * model, int change = 1); + + /// Nulls out node info + void nullNodeInfo(); + /** Initialize reference counts in attached CbcNodeInfo + + This is a convenience routine, which will initialize the reference counts + in the attached CbcNodeInfo object based on the attached + OsiBranchingObject. + + \sa CbcNodeInfo::initializeInfo(int). + */ + void initializeInfo(); + + /// Does next branch and updates state + int branch(OsiSolverInterface * solver); + + /** Double checks in case node can change its mind! + Returns objective value + Can change objective etc */ + double checkIsCutoff(double cutoff); + // Information to make basis and bounds + inline CbcNodeInfo * nodeInfo() const { + return nodeInfo_; + } + + // Objective value + inline double objectiveValue() const { + return objectiveValue_; + } + inline void setObjectiveValue(double value) { + objectiveValue_ = value; + } + /// Number of arms defined for the attached OsiBranchingObject. + inline int numberBranches() const { + if (branch_) + return (branch_->numberBranches()) ; + else + return (-1) ; + } + + /* Active arm of the attached OsiBranchingObject. + + In the simplest instance, coded -1 for the down arm of the branch, +1 for + the up arm. But see OsiBranchingObject::way() + Use nodeInfo--.numberBranchesLeft_ to see how active + */ + int way() const; + /// Depth in branch-and-cut search tree + inline int depth() const { + return depth_; + } + /// Set depth in branch-and-cut search tree + inline void setDepth(int value) { + depth_ = value; + } + /// Get the number of objects unsatisfied at this node. + inline int numberUnsatisfied() const { + return numberUnsatisfied_; + } + /// Set the number of objects unsatisfied at this node. + inline void setNumberUnsatisfied(int value) { + numberUnsatisfied_ = value; + } + /// Get sum of "infeasibilities" reported by each object + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Set sum of "infeasibilities" reported by each object + inline void setSumInfeasibilities(double value) { + sumInfeasibilities_ = value; + } + // Guessed objective value (for solution) + inline double guessedObjectiveValue() const { + return guessedObjectiveValue_; + } + inline void setGuessedObjectiveValue(double value) { + guessedObjectiveValue_ = value; + } + /// Branching object for this node + inline const OsiBranchingObject * branchingObject() const { + return branch_; + } + /// Modifiable branching object for this node + inline OsiBranchingObject * modifiableBranchingObject() const { + return branch_; + } + /// Set branching object for this node (takes ownership) + inline void setBranchingObject(OsiBranchingObject * branchingObject) { + branch_ = branchingObject; + } + /// The node number + inline int nodeNumber() const { + return nodeNumber_; + } + inline void setNodeNumber(int node) { + nodeNumber_ = node; + } + /// Returns true if on tree + inline bool onTree() const { + return (state_&1) != 0; + } + /// Sets true if on tree + inline void setOnTree(bool yesNo) { + if (yesNo) state_ |= 1; + else state_ &= ~1; + } + /// Returns true if active + inline bool active() const { + return (state_&2) != 0; + } + /// Sets true if active + inline void setActive(bool yesNo) { + if (yesNo) state_ |= 2; + else state_ &= ~2; + } + /// Get state (really for debug) + inline int getState() const + { return state_;} + /// Set state (really for debug) + inline void setState(int value) + { state_ = value;} + /// Print + void print() const; + /// Debug + inline void checkInfo() const { + assert (nodeInfo_->numberBranchesLeft() == + branch_->numberBranchesLeft()); + } + +private: + // Data + /// Information to make basis and bounds + CbcNodeInfo * nodeInfo_; + /// Objective value + double objectiveValue_; + /// Guessed satisfied Objective value + double guessedObjectiveValue_; + /// Sum of "infeasibilities" reported by each object + double sumInfeasibilities_; + /// Branching object for this node + OsiBranchingObject * branch_; + /// Depth of the node in the search tree + int depth_; + /// The number of objects unsatisfied at this node. + int numberUnsatisfied_; + /// The node number + int nodeNumber_; + /** State + 1 - on tree + 2 - active + */ + int state_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcNodeInfo.hpp b/thirdparty/linux/include/coin/CbcNodeInfo.hpp new file mode 100644 index 0000000..914a347 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcNodeInfo.hpp @@ -0,0 +1,349 @@ +// $Id: CbcNodeInfo.hpp 2048 2014-07-16 09:29:16Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcNodeInfo_H +#define CbcNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +//############################################################################# +/** Information required to recreate the subproblem at this node + + When a subproblem is initially created, it is represented by a CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information needed while the subproblem remains live. + The CbcNode is deleted when the last branch arm has been evaluated. + + The CbcNodeInfo contains information required to maintain the branch-and-cut + search tree structure (links and reference counts) and to recreate the + subproblem for this node (basis, variable bounds, cutting planes). A + CbcNodeInfo object remains in existence until all nodes have been pruned from + the subtree rooted at this node. + + The principle used to maintain the reference count is that the reference + count is always the sum of all potential and actual children of the node. + Specifically, + <ul> + <li> Once it's determined how the node will branch, the reference count + is set to the number of potential children (<i>i.e.</i>, the number + of arms of the branch). + <li> As each child is created by CbcNode::branch() (converting a potential + child to the active subproblem), the reference count is decremented. + <li> If the child survives and will become a node in the search tree + (converting the active subproblem into an actual child), increment the + reference count. + </ul> + Notice that the active subproblem lives in a sort of limbo, neither a + potential or an actual node in the branch-and-cut tree. + + CbcNodeInfo objects come in two flavours. A CbcFullNodeInfo object contains + a full record of the information required to recreate a subproblem. + A CbcPartialNodeInfo object expresses this information in terms of + differences from the parent. +*/ + +class CbcNodeInfo { + +public: + + /** \name Constructors & destructors */ +//@{ + /** Default Constructor + + Creates an empty NodeInfo object. + */ + CbcNodeInfo (); + + /// Copy constructor + CbcNodeInfo ( const CbcNodeInfo &); + +#ifdef JJF_ZERO + /** Construct with parent + + Creates a NodeInfo object which knows its parent and assumes it will + in turn have two children. + */ + CbcNodeInfo (CbcNodeInfo * parent); +#endif + + /** Construct with parent and owner + + As for `construct with parent', and attached to \p owner. + */ + CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner); + + /** Destructor + + Note that the destructor will recursively delete the parent if this + nodeInfo is the last child. + */ + virtual ~CbcNodeInfo(); +//@} + + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound and basis + information at node and adds any cuts to the addCuts array. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const = 0 ; + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) = 0; + + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const = 0; + /// Clone + virtual CbcNodeInfo * clone() const = 0; + /// Called when number branches left down to zero + virtual void allBranchesGone() {} +#ifndef JJF_ONE + /// Increment number of references + inline void increment(int amount = 1) { + numberPointingToThis_ += amount;/*printf("CbcNodeInfo %x incremented by %d to %d\n",this,amount,numberPointingToThis_);*/ + } + + /// Decrement number of references and return number left + inline int decrement(int amount = 1) { + numberPointingToThis_ -= amount;/*printf("CbcNodeInfo %x decremented by %d to %d\n",this,amount,numberPointingToThis_);*/ + return numberPointingToThis_; + } +#else + /// Increment number of references + void increment(int amount = 1); + /// Decrement number of references and return number left + int decrement(int amount = 1); +#endif + /** Initialize reference counts + + Initialize the reference counts used for tree maintenance. + */ + + inline void initializeInfo(int number) { + numberPointingToThis_ = number; + numberBranchesLeft_ = number; + } + + /// Return number of branches left in object + inline int numberBranchesLeft() const { + return numberBranchesLeft_; + } + + /// Set number of branches left in object + inline void setNumberBranchesLeft(int value) { + numberBranchesLeft_ = value; + } + + /// Return number of objects pointing to this + inline int numberPointingToThis() const { + return numberPointingToThis_; + } + + /// Set number of objects pointing to this + inline void setNumberPointingToThis(int number) { + numberPointingToThis_ = number; + } + + /// Increment number of objects pointing to this + inline void incrementNumberPointingToThis() { + numberPointingToThis_ ++; + } + + /// Say one branch taken + inline int branchedOn() { + numberPointingToThis_--; + numberBranchesLeft_--; + return numberBranchesLeft_; + } + + /// Say thrown away + inline void throwAway() { + numberPointingToThis_ -= numberBranchesLeft_; + numberBranchesLeft_ = 0; + } + + /// Parent of this + CbcNodeInfo * parent() const { + return parent_; + } + /// Set parent null + inline void nullParent() { + parent_ = NULL; + } + + void addCuts(OsiCuts & cuts, int numberToBranch, //int * whichGenerator, + int numberPointingToThis); + void addCuts(int numberCuts, CbcCountRowCut ** cuts, int numberToBranch); + /** Delete cuts (decrements counts) + Slow unless cuts in same order as saved + */ + void deleteCuts(int numberToDelete, CbcCountRowCut ** cuts); + void deleteCuts(int numberToDelete, int * which); + + /// Really delete a cut + void deleteCut(int whichOne); + + /// Decrement active cut counts + void decrementCuts(int change = 1); + + /// Increment active cut counts + void incrementCuts(int change = 1); + + /// Decrement all active cut counts in chain starting at parent + void decrementParentCuts(CbcModel * model, int change = 1); + + /// Increment all active cut counts in parent chain + void incrementParentCuts(CbcModel * model, int change = 1); + + /// Array of pointers to cuts + inline CbcCountRowCut ** cuts() const { + return cuts_; + } + + /// Number of row cuts (this node) + inline int numberCuts() const { + return numberCuts_; + } + inline void setNumberCuts(int value) { + numberCuts_ = value; + } + + /// Set owner null + inline void nullOwner() { + owner_ = NULL; + } + const inline CbcNode * owner() const { + return owner_; + } + inline CbcNode * mutableOwner() const { + return owner_; + } + /// The node number + inline int nodeNumber() const { + return nodeNumber_; + } + inline void setNodeNumber(int node) { + nodeNumber_ = node; + } + /** Deactivate node information. + 1 - bounds + 2 - cuts + 4 - basis! + 8 - just marked + 16 - symmetry branching worked + */ + void deactivate(int mode = 3); + /// Say if normal + inline bool allActivated() const { + return ((active_&7) == 7); + } + /// Say if marked + inline bool marked() const { + return ((active_&8) != 0); + } + /// Mark + inline void mark() { + active_ |= 8; + } + /// Unmark + inline void unmark() { + active_ &= ~8; + } + /// Get symmetry value (true worked at this node) + inline bool symmetryWorked() const + { return (active_&16) !=0;} + /// Say symmetry worked at this node) + inline void setSymmetryWorked() + { active_ |= 16;} + + /// Branching object for the parent + inline const OsiBranchingObject * parentBranch() const { + return parentBranch_; + } + /// If we need to take off parent based data + void unsetParentBasedData(); +protected: + + /** Number of other nodes pointing to this node. + + Number of existing and potential search tree nodes pointing to this node. + `Existing' means referenced by #parent_ of some other CbcNodeInfo. + `Potential' means children still to be created (#numberBranchesLeft_ of + this CbcNodeInfo). + */ + int numberPointingToThis_; + + /// parent + CbcNodeInfo * parent_; + + /// Copy of the branching object of the parent when the node is created + OsiBranchingObject * parentBranch_; + + /// Owner + CbcNode * owner_; + + /// Number of row cuts (this node) + int numberCuts_; + + /// The node number + int nodeNumber_; + + /// Array of pointers to cuts + CbcCountRowCut ** cuts_; + + /** Number of rows in problem (before these cuts). This + means that for top of chain it must be rows at continuous */ + int numberRows_; + + /** Number of branch arms left to explore at this node + + \todo There seems to be redundancy between this field and + CbcBranchingObject::numberBranchesLeft_. It'd be good to sort out if + both are necessary. + */ + int numberBranchesLeft_; + /** Active node information. + 1 - bounds + 2 - cuts + 4 - basis! + */ + int active_; + +private: + + /// Illegal Assignment operator + CbcNodeInfo & operator=(const CbcNodeInfo& rhs); + + /// routine common to constructors + void setParentBasedData(); +}; + +#endif // CbcNodeInfo_H + diff --git a/thirdparty/linux/include/coin/CbcObject.hpp b/thirdparty/linux/include/coin/CbcObject.hpp new file mode 100644 index 0000000..2fb6794 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcObject.hpp @@ -0,0 +1,272 @@ +// $Id: CbcObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcObject_H +#define CbcObject_H + +#include <string> +#include <vector> +#include "OsiBranchingObject.hpp" +class OsiSolverInterface; +class OsiSolverBranch; + +class CbcModel; +class CbcNode; +class CbcNodeInfo; +class CbcBranchingObject; +class OsiChooseVariable; +class CbcObjectUpdateData; +//############################################################################# + +/** Abstract base class for `objects'. + It now just has stuff that OsiObject does not have + + The branching model used in Cbc is based on the idea of an <i>object</i>. + In the abstract, an object is something that has a feasible region, can be + evaluated for infeasibility, can be branched on (<i>i.e.</i>, there's some + constructive action to be taken to move toward feasibility), and allows + comparison of the effect of branching. + + This class (CbcObject) is the base class for an object. To round out the + branching model, the class CbcBranchingObject describes how to perform a + branch, and the class CbcBranchDecision describes how to compare two + CbcBranchingObjects. + + To create a new type of object you need to provide three methods: + #infeasibility(), #feasibleRegion(), and #createCbcBranch(), described below. + + This base class is primarily virtual to allow for any form of structure. + Any form of discontinuity is allowed. + + \todo The notion that all branches are binary (two arms) is wired into the + implementation of CbcObject, CbcBranchingObject, and + CbcBranchDecision. Changing this will require a moderate amount of + recoding. + */ +// This can be used if object wants to skip strong branching +typedef struct { + CbcBranchingObject * possibleBranch; // what a branch would do + double upMovement; // cost going up (and initial away from feasible) + double downMovement; // cost going down + int numIntInfeasUp ; // without odd ones + int numObjInfeasUp ; // just odd ones + bool finishedUp; // true if solver finished + int numItersUp ; // number of iterations in solver + int numIntInfeasDown ; // without odd ones + int numObjInfeasDown ; // just odd ones + bool finishedDown; // true if solver finished + int numItersDown; // number of iterations in solver + int objectNumber; // Which object it is + int fix; // 0 if no fix, 1 if we can fix up, -1 if we can fix down +} CbcStrongInfo; + +class CbcObject : public OsiObject { + +public: + + // Default Constructor + CbcObject (); + + // Useful constructor + CbcObject (CbcModel * model); + + // Copy constructor + CbcObject ( const CbcObject &); + + // Assignment operator + CbcObject & operator=( const CbcObject& rhs); + + /// Clone + virtual CbcObject * clone() const = 0; + + /// Destructor + virtual ~CbcObject (); + + /** Infeasibility of the object + + This is some measure of the infeasibility of the object. It should be + scaled to be in the range [0.0, 0.5], with 0.0 indicating the object + is satisfied. + + The preferred branching direction is returned in preferredWay, + + This is used to prepare for strong branching but should also think of + case when no strong branching + + The object may also compute an estimate of cost of going "up" or "down". + This will probably be based on pseudo-cost ideas + */ +#ifdef CBC_NEW_STYLE_BRANCH + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const = 0; +#else + virtual double infeasibility(const OsiBranchingInformation * /*info*/, + int &preferredWay) const { + return infeasibility(preferredWay); + } + virtual double infeasibility(int &/*preferredWay*/) const { + throw CoinError("Need code", "infeasibility", "CbcBranchBase"); + } +#endif + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + */ + virtual void feasibleRegion() = 0; + /// Dummy one for compatibility + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + */ + virtual double feasibleRegion(OsiSolverInterface * solver) const ; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ +#ifdef CBC_NEW_STYLE_BRANCH + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) = 0; +#else + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * + /* solver */, + const OsiBranchingInformation * + /* info */, int /* way */) { + // return createBranch(solver, info, way); + return NULL; + } + virtual OsiBranchingObject * createBranch(OsiSolverInterface * /*solver*/, + const OsiBranchingInformation * /*info*/, int /*way*/) const { + throw CoinError("Need code", "createBranch", "CbcBranchBase"); + } +#endif + /** Create an Osibranching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual OsiBranchingObject * createOsiBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a good direction. + + If the method cannot generate a feasible point (because there aren't + any, or because it isn't bright enough to find one), it should + return null. + */ + virtual CbcBranchingObject * preferredNewFeasible() const { + return NULL; + } + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + If the method cannot generate a feasible point (because there aren't + any, or because it isn't bright enough to find one), it should + return null. + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const { + return NULL; + } + + /** Reset variable bounds to their original values. + + Bounds may be tightened, so it may be good to be able to set this info in object. + */ + virtual void resetBounds(const OsiSolverInterface * ) {} + + /** Returns floor and ceiling i.e. closest valid points + */ + virtual void floorCeiling(double & floorValue, double & ceilingValue, double value, + double tolerance) const; + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & ) {} + + /// Identifier (normally column number in matrix) + inline int id() const { + return id_; + } + + /** Set identifier (normally column number in matrix) + but 1000000000 to 1100000000 means optional branching object + i.e. code would work without it */ + inline void setId(int value) { + id_ = value; + } + + /** Return true if optional branching object + i.e. code would work without it */ + inline bool optionalObject() const { + return (id_ >= 1000000000 && id_ < 1100000000); + } + + /// Get position in object_ list + inline int position() const { + return position_; + } + + /// Set position in object_ list + inline void setPosition(int position) { + position_ = position; + } + + /// update model + inline void setModel(CbcModel * model) { + model_ = model; + } + + /// Return model + inline CbcModel * model() const { + return model_; + } + + /// If -1 down always chosen first, +1 up always, 0 normal + inline int preferredWay() const { + return preferredWay_; + } + /// Set -1 down always chosen first, +1 up always, 0 normal + inline void setPreferredWay(int value) { + preferredWay_ = value; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * , int , const int * ) {} + /// Initialize for branching + virtual void initializeForBranching(CbcModel * ) {} + +protected: + /// data + + /// Model + CbcModel * model_; + /// Identifier (normally column number in matrix) + int id_; + /// Position in object list + int position_; + /// If -1 down always chosen first, +1 up always, 0 normal + int preferredWay_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcObjectUpdateData.hpp b/thirdparty/linux/include/coin/CbcObjectUpdateData.hpp new file mode 100644 index 0000000..997ad9e --- /dev/null +++ b/thirdparty/linux/include/coin/CbcObjectUpdateData.hpp @@ -0,0 +1,64 @@ +// $Id: CbcObjectUpdateData.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcObjectUpdateData_H +#define CbcObjectUpdateData_H + +#include "CbcObject.hpp" +/* This stores data so an object can be updated + */ +class CbcObjectUpdateData { + +public: + + /// Default Constructor + CbcObjectUpdateData (); + + /// Useful constructor + CbcObjectUpdateData (CbcObject * object, + int way, + double change, + int status, + int intDecrease_, + double branchingValue); + + /// Copy constructor + CbcObjectUpdateData ( const CbcObjectUpdateData &); + + /// Assignment operator + CbcObjectUpdateData & operator=( const CbcObjectUpdateData& rhs); + + /// Destructor + virtual ~CbcObjectUpdateData (); + + +public: + /// data + + /// Object + CbcObject * object_; + /// Branch as defined by instance of CbcObject + int way_; + /// Object number + int objectNumber_; + /// Change in objective + double change_; + /// Status 0 Optimal, 1 infeasible, 2 unknown + int status_; + /// Decrease in number unsatisfied + int intDecrease_; + /// Branching value + double branchingValue_; + /// Objective value before branching + double originalObjective_; + /// Current cutoff + double cutoff_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/CbcOrClpParam.cpp b/thirdparty/linux/include/coin/CbcOrClpParam.cpp index b434fe0..86365ca 100644 --- a/thirdparty/linux/include/coin/CbcOrClpParam.cpp +++ b/thirdparty/linux/include/coin/CbcOrClpParam.cpp @@ -1,4 +1,4 @@ -/* $Id: CbcOrClpParam.cpp 2079 2015-01-05 13:11:35Z forrest $ */ +/* $Id: CbcOrClpParam.cpp 2175 2015-10-06 08:56:43Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -48,12 +48,15 @@ static char coin_prompt[] = "Clp:"; #include "AbcCommon.hpp" #endif static bool doPrinting = true; -std::string afterEquals = ""; +static std::string afterEquals = ""; static char printArray[200]; #if COIN_INT_MAX==0 #undef COIN_INT_MAX #define COIN_INT_MAX 2147483647 #endif +#if FLUSH_PRINT_BUFFER > 2 +int coinFlushBufferFlag=0; +#endif void setCbcOrClpPrinting(bool yesNo) { doPrinting = yesNo; @@ -1088,6 +1091,10 @@ CbcOrClpParam::setCurrentOption ( const std::string value ) int action = parameterOption(value); if (action >= 0) currentKeyWord_ = action; +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif } // Sets current parameter option void @@ -1098,6 +1105,10 @@ CbcOrClpParam::setCurrentOption ( int value , bool printIt) << definedKeyWords_[currentKeyWord_] << " to " << definedKeyWords_[value] << std::endl; +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif currentKeyWord_ = value; } // Sets current parameter option and returns printable string @@ -1121,6 +1132,10 @@ CbcOrClpParam::setCurrentOptionWithMessage ( int value ) sprintf(newString,"plus%d",value-1000); sprintf(printArray, "Option for %s changed from %s to %s", name_.c_str(), current, newString); +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif currentKeyWord_ = value; } else { printArray[0] = '\0'; @@ -1135,6 +1150,10 @@ CbcOrClpParam::setCurrentOptionWithMessage ( const std::string value ) char current[100]; printArray[0] = '\0'; if (action >= 0) { +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif if (action == currentKeyWord_) return NULL; if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) @@ -1647,6 +1666,17 @@ have more rounds of cuts - see passC!uts and passT!ree." parameters[numberParameters-1].append("on1"); parameters[numberParameters-1].append("off2"); parameters[numberParameters-1].append("on2"); +#if FLUSH_PRINT_BUFFER > 2 + parameters[numberParameters++] = + CbcOrClpParam("buff!eredMode", "Whether to flush print buffer", + "on", CLP_PARAM_STR_BUFFER_MODE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Default is on, off switches on unbuffered output" + ); + parameters[numberParameters-1].setIntValue(0); +#endif parameters[numberParameters++] = CbcOrClpParam("chol!esky", "Which cholesky algorithm", "native", CLP_PARAM_STR_CHOLESKY, 7); diff --git a/thirdparty/linux/include/coin/CbcOrClpParam.hpp b/thirdparty/linux/include/coin/CbcOrClpParam.hpp index d76d966..5e0794a 100644 --- a/thirdparty/linux/include/coin/CbcOrClpParam.hpp +++ b/thirdparty/linux/include/coin/CbcOrClpParam.hpp @@ -1,5 +1,5 @@ -/* $Id: CbcOrClpParam.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +/* $Id: CbcOrClpParam.hpp 2175 2015-10-06 08:56:43Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -170,6 +170,7 @@ enum CbcOrClpParameterType CLP_PARAM_STR_ALLCOMMANDS, CLP_PARAM_STR_TIME_MODE, CLP_PARAM_STR_ABCWANTED, + CLP_PARAM_STR_BUFFER_MODE, CBC_PARAM_STR_NODESTRATEGY = 251, CBC_PARAM_STR_BRANCHSTRATEGY, diff --git a/thirdparty/linux/include/coin/CbcParam.hpp b/thirdparty/linux/include/coin/CbcParam.hpp new file mode 100644 index 0000000..5b37348 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcParam.hpp @@ -0,0 +1,324 @@ +/* $Id: CbcParam.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcParam_H +#define CbcParam_H + +#include "OsiSolverInterface.hpp" +#include "CbcModel.hpp" +class ClpSimplex; +/*! \brief Parameter codes + + Parameter type ranges are allocated as follows + <ul> + <li> 1 -- 100 double parameters + <li> 101 -- 200 integer parameters + <li> 201 -- 250 string parameters + <li> 251 -- 300 cuts etc(string but broken out for clarity) + <li> 301 -- 400 `actions' + </ul> + + `Actions' do not necessarily invoke an immediate action; it's just that they + don't fit neatly into the parameters array. + + This coding scheme is in flux. + CBC_PARAM_STR_NODESTRATEGY, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_NOTUSED_ADDCUTSSTRATEGY, + CLP_PARAM_ACTION_CLEARCUTS, + CBC_PARAM_NOTUSED_OSLSTUFF, + CBC_PARAM_NOTUSED_CBCSTUFF are not used at present (03.10.24). +*/ + +enum CbcParameterType + +{ CBC_PARAM_GENERALQUERY = -100, + CBC_PARAM_FULLGENERALQUERY, + + CLP_PARAM_DBL_PRIMALTOLERANCE = 1, + CLP_PARAM_DBL_DUALTOLERANCE, + CBC_PARAM_DBL_CUTOFF, + CLP_PARAM_DBL_TIMELIMIT, + CLP_PARAM_DBL_DUALBOUND, + CLP_PARAM_DBL_PRIMALWEIGHT, + CLP_PARAM_DBL_OBJSCALE, + CLP_PARAM_DBL_RHSSCALE, + + CBC_PARAM_DBL_INFEASIBILITYWEIGHT = 51, + CBC_PARAM_DBL_INTEGERTOLERANCE, + CBC_PARAM_DBL_INCREMENT, + CBC_PARAM_DBL_ALLOWABLEGAP, + + CBC_PARAM_DBL_DJFIX = 81, + CBC_PARAM_DBL_GAPRATIO, + CBC_PARAM_DBL_TIGHTENFACTOR, + + CLP_PARAM_INT_LOGLEVEL = 101, + CLP_PARAM_INT_SOLVERLOGLEVEL, + CBC_PARAM_INT_MAXNODES, + CBC_PARAM_INT_STRONGBRANCHING, + CLP_PARAM_INT_MAXFACTOR, + CLP_PARAM_INT_PERTVALUE, + CLP_PARAM_INT_MAXITERATION, + CLP_PARAM_INT_PRESOLVEPASS, + CLP_PARAM_INT_IDIOT, + CLP_PARAM_INT_SPRINT, + CLP_PARAM_INT_OUTPUTFORMAT, + CLP_PARAM_INT_SLPVALUE, + CLP_PARAM_INT_PRESOLVEOPTIONS, + CLP_PARAM_INT_PRINTOPTIONS, + CLP_PARAM_INT_SPECIALOPTIONS, + + CLP_PARAM_STR_DIRECTION = 201, + CLP_PARAM_STR_DUALPIVOT, + CLP_PARAM_STR_SCALING, + CLP_PARAM_STR_ERRORSALLOWED, + CLP_PARAM_STR_KEEPNAMES, + CLP_PARAM_STR_SPARSEFACTOR, + CLP_PARAM_STR_PRIMALPIVOT, + CLP_PARAM_STR_PRESOLVE, + CLP_PARAM_STR_CRASH, + CLP_PARAM_STR_BIASLU, + CLP_PARAM_STR_PERTURBATION, + CLP_PARAM_STR_MESSAGES, + CLP_PARAM_STR_AUTOSCALE, + CLP_PARAM_STR_CHOLESKY, + CLP_PARAM_STR_KKT, + CLP_PARAM_STR_BARRIERSCALE, + CLP_PARAM_STR_GAMMA, + CLP_PARAM_STR_CROSSOVER, + CLP_PARAM_STR_PFI, + CLP_PARAM_NOTUSED_ALGORITHM, + + CBC_PARAM_STR_NODESTRATEGY = 251, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_NOTUSED_ADDCUTSSTRATEGY, + CBC_PARAM_STR_GOMORYCUTS, + CBC_PARAM_STR_PROBINGCUTS, + CBC_PARAM_STR_KNAPSACKCUTS, + CBC_PARAM_NOTUSED_ODDHOLECUTS, + CBC_PARAM_STR_ROUNDING, + CBC_PARAM_STR_SOLVER, + CBC_PARAM_STR_CLIQUECUTS, + CBC_PARAM_STR_COSTSTRATEGY, + CBC_PARAM_STR_FLOWCUTS, + CBC_PARAM_STR_MIXEDCUTS, + CBC_PARAM_STR_TWOMIRCUTS, + CBC_PARAM_STR_PREPROCESS, + + CLP_PARAM_ACTION_DIRECTORY = 301, + CLP_PARAM_ACTION_IMPORT, + CLP_PARAM_ACTION_EXPORT, + CLP_PARAM_ACTION_RESTORE, + CLP_PARAM_ACTION_SAVE, + CLP_PARAM_ACTION_DUALSIMPLEX, + CLP_PARAM_ACTION_PRIMALSIMPLEX, + CLP_PARAM_ACTION_MAXIMIZE, + CLP_PARAM_ACTION_MINIMIZE, + CLP_PARAM_ACTION_EXIT, + CLP_PARAM_ACTION_STDIN, + CLP_PARAM_ACTION_UNITTEST, + CLP_PARAM_ACTION_NETLIB_DUAL, + CLP_PARAM_ACTION_NETLIB_PRIMAL, + CLP_PARAM_ACTION_SOLUTION, + CLP_PARAM_ACTION_TIGHTEN, + CLP_PARAM_ACTION_FAKEBOUND, + CLP_PARAM_ACTION_HELP, + CLP_PARAM_ACTION_PLUSMINUS, + CLP_PARAM_ACTION_NETWORK, + CLP_PARAM_ACTION_ALLSLACK, + CLP_PARAM_ACTION_REVERSE, + CLP_PARAM_ACTION_BARRIER, + CLP_PARAM_ACTION_NETLIB_BARRIER, + CLP_PARAM_ACTION_REALLY_SCALE, + CLP_PARAM_ACTION_BASISIN, + CLP_PARAM_ACTION_BASISOUT, + CLP_PARAM_ACTION_SOLVECONTINUOUS, + CBC_PARAM_ACTION_BAB, + CBC_PARAM_ACTION_MIPLIB, + CLP_PARAM_ACTION_CLEARCUTS, + CLP_VERSION_NOTUSED_PRINTVERSION, + + CBC_PARAM_NOTUSED_OSLSTUFF = 401, + CBC_PARAM_NOTUSED_CBCSTUFF, + + CBC_PARAM_NOTUSED_INVALID = 1000 +}; + + +/// Very simple class for setting parameters + +class CbcParam { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructors + CbcParam ( ); + CbcParam (std::string name, std::string help, + double lower, double upper, CbcParameterType type, bool display = true); + CbcParam (std::string name, std::string help, + int lower, int upper, CbcParameterType type, bool display = true); + // Other strings will be added by insert + CbcParam (std::string name, std::string help, std::string firstValue, + CbcParameterType type, int defaultIndex = 0, bool display = true); + // Action + CbcParam (std::string name, std::string help, + CbcParameterType type, int indexNumber = -1, bool display = true); + /// Copy constructor. + CbcParam(const CbcParam &); + /// Assignment operator. This copies the data + CbcParam & operator=(const CbcParam & rhs); + /// Destructor + ~CbcParam ( ); + //@} + + /**@name stuff */ + //@{ + /// Insert string (only valid for keywords) + void append(std::string keyWord); + /// Adds one help line + void addHelp(std::string keyWord); + /// Returns name + inline std::string name( ) const { + return name_; + }; + /// Returns short help + inline std::string shortHelp( ) const { + return shortHelp_; + }; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(CbcModel & model, double value) const; + /// Gets a double parameter + double doubleParameter(CbcModel & model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(CbcModel & model, int value) const; + /// Gets a int parameter + int intParameter(CbcModel & model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(ClpSimplex * model, double value) const; + /// Gets a double parameter + double doubleParameter(ClpSimplex * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(ClpSimplex * model, int value) const; + /// Gets a int parameter + int intParameter(ClpSimplex * model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(OsiSolverInterface * model, double value) const; + /// Gets a double parameter + double doubleParameter(OsiSolverInterface * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(OsiSolverInterface * model, int value) const; + /// Gets a int parameter + int intParameter(OsiSolverInterface * model) const; + /// Checks a double parameter (nonzero code if error) + int checkDoubleParameter(double value) const; + /// Returns name which could match + std::string matchName ( ) const; + /// Returns parameter option which matches (-1 if none) + int parameterOption ( std::string check ) const; + /// Prints parameter options + void printOptions ( ) const; + /// Returns current parameter option + inline std::string currentOption ( ) const { + return definedKeyWords_[currentKeyWord_]; + } + /// Sets current parameter option + inline void setCurrentOption ( int value ) { + currentKeyWord_ = value; + } + /// Sets int value + inline void setIntValue ( int value ) { + intValue_ = value; + } + inline int intValue () const { + return intValue_; + } + /// Sets double value + inline void setDoubleValue ( double value ) { + doubleValue_ = value; + } + inline double doubleValue () const { + return doubleValue_; + } + /// Sets string value + inline void setStringValue ( std::string value ) { + stringValue_ = value; + } + inline std::string stringValue () const { + return stringValue_; + } + /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched + int matches (std::string input) const; + /// type + inline CbcParameterType type() const { + return type_; + } + /// whether to display + inline bool displayThis() const { + return display_; + } + /// Set Long help + inline void setLonghelp(const std::string help) { + longHelp_ = help; + } + /// Print Long help + void printLongHelp() const; + /// Print action and string + void printString() const; + /// type for classification + inline int indexNumber() const { + return indexNumber_; + } +private: + /// gutsOfConstructor + void gutsOfConstructor(); + //@} +////////////////// data ////////////////// +private: + + /**@name data + We might as well throw all type data in - could derive? + */ + //@{ + // Type see CbcParameterType + CbcParameterType type_; + /// If double == okay + double lowerDoubleValue_; + double upperDoubleValue_; + /// If int == okay + int lowerIntValue_; + int upperIntValue_; + // Length of name + unsigned int lengthName_; + // Minimum match + unsigned int lengthMatch_; + /// set of valid strings + std::vector<std::string> definedKeyWords_; + /// Name + std::string name_; + /// Short help + std::string shortHelp_; + /// Long help + std::string longHelp_; + /// Action + CbcParameterType action_; + /// Current keyWord (if a keyword parameter) + int currentKeyWord_; + /// Display on ? + bool display_; + /// Integer parameter - current value + int intValue_; + /// Double parameter - current value + double doubleValue_; + /// String parameter - current value + std::string stringValue_; + /// index number to use for display purposes + int indexNumber_; + //@} +}; +#endif /* CbcParam_H */ + diff --git a/thirdparty/linux/include/coin/CbcPartialNodeInfo.hpp b/thirdparty/linux/include/coin/CbcPartialNodeInfo.hpp new file mode 100644 index 0000000..446a3eb --- /dev/null +++ b/thirdparty/linux/include/coin/CbcPartialNodeInfo.hpp @@ -0,0 +1,110 @@ +// $Id: CbcPartialNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcPartialNodeInfo_H +#define CbcPartialNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; +/** \brief Holds information for recreating a subproblem by incremental change + from the parent. + + A CbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. +*/ + +class CbcPartialNodeInfo : public CbcNodeInfo { + +public: + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound and basis change + information at node and adds any cuts to the addCuts array. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const ; + + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ; + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis ) const ; + // Default Constructor + CbcPartialNodeInfo (); + + // Constructor from current state + CbcPartialNodeInfo (CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds, const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) ; + + // Copy constructor + CbcPartialNodeInfo ( const CbcPartialNodeInfo &); + + // Destructor + ~CbcPartialNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + /// Basis diff information + inline const CoinWarmStartDiff *basisDiff() const { + return basisDiff_ ; + } + /// Which variable (top bit if upper bound changing) + inline const int * variables() const { + return variables_; + } + // New bound + inline const double * newBounds() const { + return newBounds_; + } + /// Number of bound changes + inline int numberChangedBounds() const { + return numberChangedBounds_; + } +protected: + /* Data values */ + + /// Basis diff information + CoinWarmStartDiff *basisDiff_ ; + /// Which variable (top bit if upper bound changing) + int * variables_; + // New bound + double * newBounds_; + /// Number of bound changes + int numberChangedBounds_; +private: + + /// Illegal Assignment operator + CbcPartialNodeInfo & operator=(const CbcPartialNodeInfo& rhs); +}; + +#endif //CbcPartialNodeInfo_H + diff --git a/thirdparty/linux/include/coin/CbcSOS.hpp b/thirdparty/linux/include/coin/CbcSOS.hpp new file mode 100644 index 0000000..48ccece --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSOS.hpp @@ -0,0 +1,279 @@ +// $Id: CbcSOS.hpp 2070 2014-09-08 09:24:45Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcSOS_H +#define CbcSOS_H + +/** \brief Branching object for Special Ordered Sets of type 1 and 2. + + SOS1 are an ordered set of variables where at most one variable can be + non-zero. SOS1 are commonly defined with binary variables (interpreted as + selection between alternatives) but this is not necessary. An SOS1 with + all binary variables is a special case of a clique (setting any one + variable to 1 forces all others to 0). + + In theory, the implementation makes no assumptions about integrality in + Type 1 sets. In practice, there are places where the code seems to have been + written with a binary SOS mindset. Current development of SOS branching + objects is proceeding in OsiSOS. + + SOS2 are an ordered set of variables in which at most two consecutive + variables can be non-zero and must sum to 1 (interpreted as interpolation + between two discrete values). By definition the variables are non-integer. +*/ + +class CbcSOS : public CbcObject { + +public: + + // Default Constructor + CbcSOS (); + + /** \brief Constructor with SOS type and member information + + Type specifies SOS 1 or 2. Identifier is an arbitrary value. + + Which should be an array of variable indices with numberMembers entries. + Weights can be used to assign arbitrary weights to variables, in the order + they are specified in which. If no weights are provided, a default array of + 0, 1, 2, ... is generated. + */ + + CbcSOS (CbcModel * model, int numberMembers, + const int * which, const double * weights, int identifier, + int type = 1); + + // Copy constructor + CbcSOS ( const CbcSOS &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSOS & operator=( const CbcSOS& rhs); + + // Destructor + virtual ~CbcSOS (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & data) ; + using CbcObject::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + + /// Construct an OsiSOS object + OsiSOS * osiObject(const OsiSolverInterface * solver) const; + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const { + return members_; + } + + /// SOS type + inline int sosType() const { + return sosType_; + } + /// Down number times + inline int numberTimesDown() const { + return numberTimesDown_; + } + /// Up number times + inline int numberTimesUp() const { + return numberTimesUp_; + } + + /** Array of weights */ + inline const double * weights() const { + return weights_; + } + + /// Set number of members + inline void setNumberMembers(int n) { + numberMembers_ = n; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline int * mutableMembers() const { + return members_; + } + + /** Array of weights */ + inline double * mutableWeights() const { + return weights_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return (sosType_ == 1 && integerValued_); + } + /// Set whether set is integer valued or not + inline void setIntegerValued(bool yesNo) { + integerValued_ = yesNo; + } +private: + /// data + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /** \brief Weights for individual members + + Arbitrary weights for members. Can be used to attach meaning to variable + values independent of objective coefficients. For example, if the SOS set + comprises binary variables used to choose a facility of a given size, the + weight could be the corresponding facilty size. Fractional values of the + SOS variables can then be used to estimate ideal facility size. + + Weights cannot be completely arbitrary. From the code, they must be + differ by at least 1.0e-7 + */ + + double * weights_; + /// Current pseudo-shadow price estimate down + mutable double shadowEstimateDown_; + /// Current pseudo-shadow price estimate up + mutable double shadowEstimateUp_; + /// Down pseudo ratio + double downDynamicPseudoRatio_; + /// Up pseudo ratio + double upDynamicPseudoRatio_; + /// Number of times we have gone down + int numberTimesDown_; + /// Number of times we have gone up + int numberTimesUp_; + /// Number of members + int numberMembers_; + /// SOS type + int sosType_; + /// Whether integer valued + bool integerValued_; + /// Whether odd values e.g. negative + bool oddValues_; +}; + +/** Branching object for Special ordered sets + + Variable_ is the set id number (redundant, as the object also holds a + pointer to the set. + */ +class CbcSOSBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcSOSBranchingObject (); + + // Useful constructor + CbcSOSBranchingObject (CbcModel * model, const CbcSOS * clique, + int way, + double separator); + + // Copy constructor + CbcSOSBranchingObject ( const CbcSOSBranchingObject &); + + // Assignment operator + CbcSOSBranchingObject & operator=( const CbcSOSBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcSOSBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const ; + + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch() { + CbcBranchingObject::previousBranch(); + computeNonzeroRange(); + } + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SoSBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + + /** Fill out the \c firstNonzero_ and \c lastNonzero_ data members */ + void computeNonzeroRange(); + +private: + /// data + const CbcSOS * set_; + /// separator + double separator_; + /** The following two members describe the range in the members_ of the + original object that whose upper bound is not fixed to 0. This is not + necessary for Cbc to function correctly, this is there for heuristics so + that separate branching decisions on the same object can be pooled into + one branching object. */ + int firstNonzero_; + int lastNonzero_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcSimpleInteger.hpp b/thirdparty/linux/include/coin/CbcSimpleInteger.hpp new file mode 100644 index 0000000..cde7d8c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSimpleInteger.hpp @@ -0,0 +1,286 @@ +// $Id: CbcSimpleInteger.hpp 1943 2013-07-21 09:05:45Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcSimpleInteger_H +#define CbcSimpleInteger_H + +#include "CbcBranchingObject.hpp" + +/** Simple branching object for an integer variable + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcIntegerBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcIntegerBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcIntegerBranchingObject (CbcModel *model, int variable, + int way , double value) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcIntegerBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcIntegerBranchingObject ( const CbcIntegerBranchingObject &); + + /// Assignment operator + CbcIntegerBranchingObject & operator= (const CbcIntegerBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcIntegerBranchingObject (); + + /// Does part of constructor + void fillPart ( int variable, int way , double value) ; + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + Returns change in guessed objective on next branch + */ + virtual double branch(); + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const ; + /** Change (tighten) bounds in object to reflect bounds in solver. + Return true if now fixed */ + virtual bool tighten(OsiSolverInterface * ) ; + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /// Lower and upper bounds for down branch + inline const double * downBounds() const { + return down_; + } + /// Lower and upper bounds for up branch + inline const double * upBounds() const { + return up_; + } + /// Set lower and upper bounds for down branch + inline void setDownBounds(const double bounds[2]) { + memcpy(down_, bounds, 2*sizeof(double)); + } + /// Set lower and upper bounds for up branch + inline void setUpBounds(const double bounds[2]) { + memcpy(up_, bounds, 2*sizeof(double)); + } +#ifdef FUNNY_BRANCHING + /** Which variable (top bit if upper bound changing, + next bit if on down branch */ + inline const int * variables() const { + return variables_; + } + // New bound + inline const double * newBounds() const { + return newBounds_; + } + /// Number of bound changes + inline int numberExtraChangedBounds() const { + return numberExtraChangedBounds_; + } + /// Just apply extra bounds to one variable - COIN_DBL_MAX ignore + int applyExtraBounds(int iColumn, double lower, double upper, int way) ; + /// Deactivate bounds for branching + void deactivate(); + /// Are active bounds for branching + inline bool active() const { + return (down_[1] != -COIN_DBL_MAX); + } +#endif + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SimpleIntegerBranchObj; + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +#ifdef FUNNY_BRANCHING + /** Which variable (top bit if upper bound changing) + next bit if changing on down branch only */ + int * variables_; + // New bound + double * newBounds_; + /// Number of Extra bound changes + int numberExtraChangedBounds_; +#endif +}; + +/// Define a single integer class + + +class CbcSimpleInteger : public CbcObject { + +public: + + // Default Constructor + CbcSimpleInteger (); + + // Useful constructor - passed model and index + CbcSimpleInteger (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed model and Osi object + CbcSimpleInteger (CbcModel * model, const OsiSimpleInteger * object); + + // Copy constructor + CbcSimpleInteger ( const CbcSimpleInteger &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleInteger & operator=( const CbcSimpleInteger& rhs); + + // Destructor + virtual ~CbcSimpleInteger (); + /// Construct an OsiSimpleInteger object + OsiSimpleInteger * osiObject() const; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Fills in a created branching object + /*virtual*/ void fillCreateBranch(CbcIntegerBranchingObject * branching, const OsiBranchingInformation * info, int way) ; + + using CbcObject::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. The algorithm takes a bit of care in order to compensate for + minor numerical inaccuracy. + */ + virtual void feasibleRegion(); + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /// Set column number + inline void setColumnNumber(int value) { + columnNumber_ = value; + } + + /** Reset variable bounds to their original values. + + Bounds may be tightened, so it may be good to be able to set this info in object. + */ + virtual void resetBounds(const OsiSolverInterface * solver) ; + + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns) ; + /// Original bounds + inline double originalLowerBound() const { + return originalLower_; + } + inline void setOriginalLowerBound(double value) { + originalLower_ = value; + } + inline double originalUpperBound() const { + return originalUpper_; + } + inline void setOriginalUpperBound(double value) { + originalUpper_ = value; + } + /// Breakeven e.g 0.7 -> >= 0.7 go up first + inline double breakEven() const { + return breakEven_; + } + /// Set breakeven e.g 0.7 -> >= 0.7 go up first + inline void setBreakEven(double value) { + breakEven_ = value; + } + + +protected: + /// data + + /// Original lower bound + double originalLower_; + /// Original upper bound + double originalUpper_; + /// Breakeven i.e. >= this preferred is up + double breakEven_; + /// Column number in model + int columnNumber_; + /// If -1 down always chosen first, +1 up always, 0 normal + int preferredWay_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcSimpleIntegerDynamicPseudoCost.hpp b/thirdparty/linux/include/coin/CbcSimpleIntegerDynamicPseudoCost.hpp new file mode 100644 index 0000000..7952d57 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSimpleIntegerDynamicPseudoCost.hpp @@ -0,0 +1,564 @@ +// $Id: CbcSimpleIntegerDynamicPseudoCost.hpp 2094 2014-11-18 11:15:36Z forrest $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/17/2009 - carved out of CbcBranchDynamic + +#ifndef CbcSimpleIntegerDynamicPseudoCost_H +#define CbcSimpleIntegerDynamicPseudoCost_H + +#include "CbcSimpleInteger.hpp" + +#define TYPERATIO 0.9 +#define MINIMUM_MOVEMENT 0.1 +#define TYPE2 0 +// was 1 - but that looks flakey +#define INFEAS 1 +#define MOD_SHADOW 1 +// weight at 1.0 is max min +#define WEIGHT_AFTER 0.8 +#define WEIGHT_BEFORE 0.1 +//Stolen from Constraint Integer Programming book (with epsilon change) +#define WEIGHT_PRODUCT + + +/** Define a single integer class but with dynamic pseudo costs. + Based on work by Achterberg, Koch and Martin. + + It is wild overkill but to keep design all twiddly things are in each. + This could be used for fine tuning. + + */ + + +class CbcSimpleIntegerDynamicPseudoCost : public CbcSimpleInteger { + +public: + + // Default Constructor + CbcSimpleIntegerDynamicPseudoCost (); + + // Useful constructor - passed model index + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed model index and pseudo costs + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn, + double downDynamicPseudoCost, double upDynamicPseudoCost); + + // Useful constructor - passed model index and pseudo costs + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int dummy, int iColumn, + double downDynamicPseudoCost, double upDynamicPseudoCost); + + // Copy constructor + CbcSimpleIntegerDynamicPseudoCost ( const CbcSimpleIntegerDynamicPseudoCost &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleIntegerDynamicPseudoCost & operator=( const CbcSimpleIntegerDynamicPseudoCost& rhs); + + // Destructor + virtual ~CbcSimpleIntegerDynamicPseudoCost (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + + /// Fills in a created branching object + // void fillCreateBranch(CbcIntegerBranchingObject * branching, const OsiBranchingInformation * info, int way) ; + + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & data) ; + /// Copy some information i.e. just variable stuff + void copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject); + /// Updates stuff like pseudocosts before threads + virtual void updateBefore(const OsiObject * rhs) ; + /// Updates stuff like pseudocosts after threads finished + virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) ; + /// Updates stuff like pseudocosts after mini branch and bound + void updateAfterMini(int numberDown, int numberDownInfeasible, double sumDown, + int numberUp, int numberUpInfeasible, double sumUp); + + using CbcSimpleInteger::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + + /// Down pseudo cost + inline double downDynamicPseudoCost() const { + return downDynamicPseudoCost_; + } + /// Set down pseudo cost + void setDownDynamicPseudoCost(double value) ; + /// Modify down pseudo cost in a slightly different way + void updateDownDynamicPseudoCost(double value); + + /// Up pseudo cost + inline double upDynamicPseudoCost() const { + return upDynamicPseudoCost_; + } + /// Set up pseudo cost + void setUpDynamicPseudoCost(double value); + /// Modify up pseudo cost in a slightly different way + void updateUpDynamicPseudoCost(double value); + + /// Down pseudo shadow price cost + inline double downShadowPrice() const { + return downShadowPrice_; + } + /// Set down pseudo shadow price cost + inline void setDownShadowPrice(double value) { + downShadowPrice_ = value; + } + /// Up pseudo shadow price cost + inline double upShadowPrice() const { + return upShadowPrice_; + } + /// Set up pseudo shadow price cost + inline void setUpShadowPrice(double value) { + upShadowPrice_ = value; + } + + /// Up down separator + inline double upDownSeparator() const { + return upDownSeparator_; + } + /// Set up down separator + inline void setUpDownSeparator(double value) { + upDownSeparator_ = value; + } + + /// Down sum cost + inline double sumDownCost() const { + return sumDownCost_; + } + /// Set down sum cost + inline void setSumDownCost(double value) { + sumDownCost_ = value; + } + /// Add to down sum cost and set last and square + inline void addToSumDownCost(double value) { + sumDownCost_ += value; + lastDownCost_ = value; + } + + /// Up sum cost + inline double sumUpCost() const { + return sumUpCost_; + } + /// Set up sum cost + inline void setSumUpCost(double value) { + sumUpCost_ = value; + } + /// Add to up sum cost and set last and square + inline void addToSumUpCost(double value) { + sumUpCost_ += value; + lastUpCost_ = value; + } + + /// Down sum change + inline double sumDownChange() const { + return sumDownChange_; + } + /// Set down sum change + inline void setSumDownChange(double value) { + sumDownChange_ = value; + } + /// Add to down sum change + inline void addToSumDownChange(double value) { + sumDownChange_ += value; + } + + /// Up sum change + inline double sumUpChange() const { + return sumUpChange_; + } + /// Set up sum change + inline void setSumUpChange(double value) { + sumUpChange_ = value; + } + /// Add to up sum change and set last and square + inline void addToSumUpChange(double value) { + sumUpChange_ += value; + } + + /// Sum down decrease number infeasibilities from strong or actual + inline double sumDownDecrease() const { + return sumDownDecrease_; + } + /// Set sum down decrease number infeasibilities from strong or actual + inline void setSumDownDecrease(double value) { + sumDownDecrease_ = value; + } + /// Add to sum down decrease number infeasibilities from strong or actual + inline void addToSumDownDecrease(double value) { + sumDownDecrease_ += value;/*lastDownDecrease_ = (int) value;*/ + } + + /// Sum up decrease number infeasibilities from strong or actual + inline double sumUpDecrease() const { + return sumUpDecrease_; + } + /// Set sum up decrease number infeasibilities from strong or actual + inline void setSumUpDecrease(double value) { + sumUpDecrease_ = value; + } + /// Add to sum up decrease number infeasibilities from strong or actual + inline void addToSumUpDecrease(double value) { + sumUpDecrease_ += value;/*lastUpDecrease_ = (int) value;*/ + } + + /// Down number times + inline int numberTimesDown() const { + return numberTimesDown_; + } + /// Set down number times + inline void setNumberTimesDown(int value) { + numberTimesDown_ = value; + } + /// Increment down number times + inline void incrementNumberTimesDown() { + numberTimesDown_++; + } + + /// Up number times + inline int numberTimesUp() const { + return numberTimesUp_; + } + /// Set up number times + inline void setNumberTimesUp(int value) { + numberTimesUp_ = value; + } + /// Increment up number times + inline void incrementNumberTimesUp() { + numberTimesUp_++; + } + + /// Number times branched + inline int numberTimesBranched() const { + return numberTimesDown_ + numberTimesUp_; + } + /// Down number times infeasible + inline int numberTimesDownInfeasible() const { + return numberTimesDownInfeasible_; + } + /// Set down number times infeasible + inline void setNumberTimesDownInfeasible(int value) { + numberTimesDownInfeasible_ = value; + } + /// Increment down number times infeasible + inline void incrementNumberTimesDownInfeasible() { + numberTimesDownInfeasible_++; + } + + /// Up number times infeasible + inline int numberTimesUpInfeasible() const { + return numberTimesUpInfeasible_; + } + /// Set up number times infeasible + inline void setNumberTimesUpInfeasible(int value) { + numberTimesUpInfeasible_ = value; + } + /// Increment up number times infeasible + inline void incrementNumberTimesUpInfeasible() { + numberTimesUpInfeasible_++; + } + + /// Number of times before trusted + inline int numberBeforeTrust() const { + return numberBeforeTrust_; + } + /// Set number of times before trusted + inline void setNumberBeforeTrust(int value) { + numberBeforeTrust_ = value; + } + /// Increment number of times before trusted + inline void incrementNumberBeforeTrust() { + numberBeforeTrust_++; + } + + /// Return "up" estimate + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// method - see below for details + inline int method() const { + return method_; + } + /// Set method + inline void setMethod(int value) { + method_ = value; + } + + /// Pass in information on a down branch + void setDownInformation(double changeObjectiveDown, int changeInfeasibilityDown); + /// Pass in information on a up branch + void setUpInformation(double changeObjectiveUp, int changeInfeasibilityUp); + /// Pass in probing information + void setProbingInformation(int fixedDown, int fixedUp); + + /// Print - 0 -summary, 1 just before strong + void print(int type = 0, double value = 0.0) const; + /// Same - returns true if contents match(ish) + bool same(const CbcSimpleIntegerDynamicPseudoCost * obj) const; +protected: + /// data + + /// Down pseudo cost + double downDynamicPseudoCost_; + /// Up pseudo cost + double upDynamicPseudoCost_; + /** Up/down separator + If >0.0 then do first branch up if value-floor(value) + >= this value + */ + double upDownSeparator_; + /// Sum down cost from strong or actual + double sumDownCost_; + /// Sum up cost from strong or actual + double sumUpCost_; + /// Sum of all changes to x when going down + double sumDownChange_; + /// Sum of all changes to x when going up + double sumUpChange_; + /// Current pseudo-shadow price estimate down + mutable double downShadowPrice_; + /// Current pseudo-shadow price estimate up + mutable double upShadowPrice_; + /// Sum down decrease number infeasibilities from strong or actual + double sumDownDecrease_; + /// Sum up decrease number infeasibilities from strong or actual + double sumUpDecrease_; + /// Last down cost from strong (i.e. as computed by last strong) + double lastDownCost_; + /// Last up cost from strong (i.e. as computed by last strong) + double lastUpCost_; + /// Last down decrease number infeasibilities from strong (i.e. as computed by last strong) + mutable int lastDownDecrease_; + /// Last up decrease number infeasibilities from strong (i.e. as computed by last strong) + mutable int lastUpDecrease_; + /// Number of times we have gone down + int numberTimesDown_; + /// Number of times we have gone up + int numberTimesUp_; + /// Number of times we have been infeasible going down + int numberTimesDownInfeasible_; + /// Number of times we have been infeasible going up + int numberTimesUpInfeasible_; + /// Number of branches before we trust + int numberBeforeTrust_; + /// Number of local probing fixings going down + int numberTimesDownLocalFixed_; + /// Number of local probing fixings going up + int numberTimesUpLocalFixed_; + /// Number of total probing fixings going down + double numberTimesDownTotalFixed_; + /// Number of total probing fixings going up + double numberTimesUpTotalFixed_; + /// Number of times probing done + int numberTimesProbingTotal_; + /// Number of times infeasible when tested + /** Method - + 0 - pseudo costs + 1 - probing + */ + int method_; +}; +/** Simple branching object for an integer variable with pseudo costs + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcIntegerPseudoCostBranchingObject : public CbcIntegerBranchingObject { + +public: + + /// Default constructor + CbcIntegerPseudoCostBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcIntegerPseudoCostBranchingObject (CbcModel *model, int variable, + int way , double value) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcIntegerPseudoCostBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcIntegerPseudoCostBranchingObject ( const CbcIntegerPseudoCostBranchingObject &); + + /// Assignment operator + CbcIntegerPseudoCostBranchingObject & operator= (const CbcIntegerPseudoCostBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcIntegerPseudoCostBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + This version also changes guessed objective value + */ + virtual double branch(); + + /// Change in guessed + inline double changeInGuessed() const { + return changeInGuessed_; + } + /// Set change in guessed + inline void setChangeInGuessed(double value) { + changeInGuessed_ = value; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SimpleIntegerDynamicPseudoCostBranchObj; + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Change in guessed objective value for next branch + double changeInGuessed_; +}; +#ifdef SWITCH_VARIABLES +/** Define a single integer class but with associated switched variable + So Binary variable switches on/off a continuous variable + designed for badly scaled problems + */ + + +class CbcSwitchingBinary : public CbcSimpleIntegerDynamicPseudoCost { + +public: + + // Default Constructor + CbcSwitchingBinary (); + + // Useful constructor + CbcSwitchingBinary (CbcSimpleIntegerDynamicPseudoCost * oldObject, + int nOdd,const int * other, const int * otherRow); + + + // Copy constructor + CbcSwitchingBinary ( const CbcSwitchingBinary &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSwitchingBinary & operator=( const CbcSwitchingBinary& rhs); + + // Destructor + virtual ~CbcSwitchingBinary (); + + /// Add in zero switches + void addZeroSwitches(int nAdd,const int * columns); + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Same - returns true if contents match(ish) + bool same(const CbcSwitchingBinary * obj) const; + /// Set associated bounds + virtual int setAssociatedBounds(OsiSolverInterface * solver=NULL, + int cleanBasis=0) const; + /// Check associated bounds + int checkAssociatedBounds(const OsiSolverInterface * solver,const double * solution, + int printLevel, int state[3], int & nBadFixed) const; + /// Lower bound when binary zero + inline const double * zeroLowerBound() const + { return zeroLowerBound_; } + /// Lower bound when binary one + inline const double * oneLowerBound() const + { return oneLowerBound_; } + /// Upper bound when binary zero + inline const double * zeroUpperBound() const + { return zeroUpperBound_; } + /// Upper bound when binary one + inline const double * oneUpperBound() const + { return oneUpperBound_; } + /** Continuous variable - + */ + inline const int * otherVariable() const + { return otherVariable_;} + /// Number of other variables + inline int numberOther() const + { return numberOther_;} + /** Type + 1 - single switch + 2 - double switch + 3 - both + */ + inline int type() const + { return type_;} +protected: + /// data + + /// Lower bound when binary zero + double * zeroLowerBound_; + /// Lower bound when binary one + double * oneLowerBound_; + /// Upper bound when binary zero + double * zeroUpperBound_; + /// Upper bound when binary one + double * oneUpperBound_; + /** Continuous variable - + */ + int * otherVariable_; + /// Number of other variables + int numberOther_; + /** Type + 1 - single switch + 2 - double switch + 3 - both + */ + int type_; +}; +#endif +#endif + diff --git a/thirdparty/linux/include/coin/CbcSimpleIntegerPseudoCost.hpp b/thirdparty/linux/include/coin/CbcSimpleIntegerPseudoCost.hpp new file mode 100644 index 0000000..c760bd6 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSimpleIntegerPseudoCost.hpp @@ -0,0 +1,114 @@ +// $Id: CbcSimpleIntegerPseudoCost.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcSimpleIntegerPseudoCost_H +#define CbcSimpleIntegerPseudoCost_H + +#include "CbcSimpleInteger.hpp" +/// Define a single integer class but with pseudo costs + +class CbcSimpleIntegerPseudoCost : public CbcSimpleInteger { + +public: + + // Default Constructor + CbcSimpleIntegerPseudoCost (); + + // Useful constructor - passed model index + CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed and model index and pseudo costs + CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn, + double downPseudoCost, double upPseudoCost); + // Useful constructor - passed and model index and pseudo costs + CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy, int iColumn, + double downPseudoCost, double upPseudoCost); + + // Copy constructor + CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleIntegerPseudoCost & operator=( const CbcSimpleIntegerPseudoCost& rhs); + + // Destructor + virtual ~CbcSimpleIntegerPseudoCost (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Down pseudo cost + inline double downPseudoCost() const { + return downPseudoCost_; + } + /// Set down pseudo cost + inline void setDownPseudoCost(double value) { + downPseudoCost_ = value; + } + + /// Up pseudo cost + inline double upPseudoCost() const { + return upPseudoCost_; + } + /// Set up pseudo cost + inline void setUpPseudoCost(double value) { + upPseudoCost_ = value; + } + + /// Up down separator + inline double upDownSeparator() const { + return upDownSeparator_; + } + /// Set up down separator + inline void setUpDownSeparator(double value) { + upDownSeparator_ = value; + } + + /// Return "up" estimate + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// method - see below for details + inline int method() const { + return method_; + } + /// Set method + inline void setMethod(int value) { + method_ = value; + } + +protected: + /// data + + /// Down pseudo cost + double downPseudoCost_; + /// Up pseudo cost + double upPseudoCost_; + /** Up/down separator + If >0.0 then do first branch up if value-floor(value) + >= this value + */ + double upDownSeparator_; + /** Method - + 0 - normal - return min (up,down) + 1 - if before any solution return CoinMax(up,down) + 2 - if before branched solution return CoinMax(up,down) + 3 - always return CoinMax(up,down) + */ + int method_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcSolver.hpp b/thirdparty/linux/include/coin/CbcSolver.hpp new file mode 100644 index 0000000..34052e1 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSolver.hpp @@ -0,0 +1,447 @@ +/* $Id: CbcSolver.hpp 1998 2013-12-19 18:11:05Z forrest $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +/*! \file CbcSolver.hpp + \brief Defines CbcSolver, the proposed top-level class for the new-style + cbc solver. + + This class is currently an orphan. With the removal of all code flagged + with the NEW_STYLE_SOLVER, this class is never instantiated (and cannot + be instantiated). It is available to be coopted as a top-level object + wrapping the current CbcMain0 and CbcMain1, should that appear to be a + desireable path forward. -- lh, 091211 -- +*/ + +#ifndef CbcSolver_H +#define CbcSolver_H + +#include <string> +#include <vector> +#include "CoinMessageHandler.hpp" +#include "OsiClpSolverInterface.hpp" + +#if CBC_OTHER_SOLVER==1 +#include "OsiCpxSolverInterface.hpp" +#endif + +#include "CbcModel.hpp" +#include "CbcOrClpParam.hpp" + +class CbcUser; +class CbcStopNow; +class CglCutGenerator; + +//############################################################################# + +/*! \brief This allows the use of the standalone solver in a flexible manner. + + It has an original OsiClpSolverInterface and CbcModel which it can use + repeatedly, e.g., to get a heuristic solution and then start again. + + So I [jjf] will need a primitive scripting language which can then call + solve and manipulate solution value and solution arrays. + + Also provides for user callback functions. Currently two ideas in + gestation, CbcUser and CbcStopNow. The latter seems limited to deciding + whether or not to stop. The former seems completely general, with a notion + of importing and exporting, and a `solve', which should be interpreted as + `do whatever this user function does'. + + Parameter initialisation is at last centralised in fillParameters(). +*/ + +class CbcSolver { + +public: + ///@name Solve method + //@{ + /** This takes a list of commands, does "stuff" and returns + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + int solve(int argc, const char * argv[], int returnMode); + /** This takes a list of commands, does "stuff" and returns + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + int solve(const char * input, int returnMode); + //@} + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcSolver(); + + /// Constructor from solver + CbcSolver(const OsiClpSolverInterface &); + + /// Constructor from model + CbcSolver(const CbcModel &); + + /** Copy constructor . + */ + CbcSolver(const CbcSolver & rhs); + + /// Assignment operator + CbcSolver & operator=(const CbcSolver& rhs); + + /// Destructor + ~CbcSolver (); + /// Fill with standard parameters + void fillParameters(); + /*! \brief Set default values in solvers from parameters + + Misleading. The current code actually reads default values from + the underlying solvers and installs them as default values for a subset of + parameters in #parameters_. + */ + void fillValuesInSolver(); + /// Add user function + void addUserFunction(CbcUser * function); + /// Set user call back + void setUserCallBack(CbcStopNow * function); + /// Add cut generator + void addCutGenerator(CglCutGenerator * generator); + //@} + ///@name miscellaneous methods to line up with old + //@{ + // analyze model + int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment, + bool changeInt, CoinMessageHandler * generalMessageHandler); + /** 1 - add heuristics to model + 2 - do heuristics (and set cutoff and best solution) + 3 - for miplib test so skip some + (out model later) + */ + //int doHeuristics(CbcModel * model, int type); + /** Updates model_ from babModel_ according to returnMode + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + void updateModel(ClpSimplex * model2, int returnMode); + //@} + ///@name useful stuff + //@{ + /// Get int value + int intValue(CbcOrClpParameterType type) const; + /// Set int value + void setIntValue(CbcOrClpParameterType type, int value); + /// Get double value + double doubleValue(CbcOrClpParameterType type) const; + /// Set double value + void setDoubleValue(CbcOrClpParameterType type, double value); + /// User function (NULL if no match) + CbcUser * userFunction(const char * name) const; + /// Return original Cbc model + inline CbcModel * model() { + return &model_; + } + /// Return updated Cbc model + inline CbcModel * babModel() { + return babModel_; + } + /// Number of userFunctions + inline int numberUserFunctions() const { + return numberUserFunctions_; + } + /// User function array + inline CbcUser ** userFunctionArray() const { + return userFunction_; + } + /// Copy of model on initial load (will contain output solutions) + inline OsiClpSolverInterface * originalSolver() const { + return originalSolver_; + } + /// Copy of model on initial load + inline CoinModel * originalCoinModel() const { + return originalCoinModel_; + } + /// Copy of model on initial load (will contain output solutions) + void setOriginalSolver(OsiClpSolverInterface * originalSolver); + /// Copy of model on initial load + void setOriginalCoinModel(CoinModel * originalCoinModel); + /// Number of cutgenerators + inline int numberCutGenerators() const { + return numberCutGenerators_; + } + /// Cut generator array + inline CglCutGenerator ** cutGeneratorArray() const { + return cutGenerator_; + } + /// Start time + inline double startTime() const { + return startTime_; + } + /// Whether to print to std::cout + inline void setPrinting(bool onOff) { + noPrinting_ = !onOff; + } + /// Where to start reading commands + inline void setReadMode(int value) { + readMode_ = value; + } + //@} +private: + ///@name Private member data + //@{ + + /// Reference model + CbcModel model_; + + /// Updated model + CbcModel * babModel_; + + /// User functions + CbcUser ** userFunction_; + /** Status of user functions + 0 - not used + 1 - needs cbc_load + 2 - available - data in coinModel + 3 - data loaded - can do cbc_save + */ + int * statusUserFunction_; + /// Copy of model on initial load (will contain output solutions) + OsiClpSolverInterface * originalSolver_; + /// Copy of model on initial load + CoinModel * originalCoinModel_; + /// Cut generators + CglCutGenerator ** cutGenerator_; + /// Number of user functions + int numberUserFunctions_; + /// Number of cut generators + int numberCutGenerators_; + /// Stop now stuff + CbcStopNow * callBack_; + /// Cpu time at instantiation + double startTime_; + /// Parameters and values + CbcOrClpParam * parameters_; + /// Number of parameters + int numberParameters_ ; + /// Whether to do miplib test + bool doMiplib_; + /// Whether to print to std::cout + bool noPrinting_; + /// Where to start reading commands + int readMode_; + //@} +}; +//############################################################################# + +/// Structure to hold useful arrays +typedef struct { + // Priorities + int * priorities_; + // SOS priorities + int * sosPriority_; + // Direction to branch first + int * branchDirection_; + // Input solution + double * primalSolution_; + // Down pseudo costs + double * pseudoDown_; + // Up pseudo costs + double * pseudoUp_; +} CbcSolverUsefulData2; + +//############################################################################# + +/** + The CbcSolver class was taken out at a 9/12/09 meeting + This is a feeble replacement. + At present everything is public +*/ +class CbcSolverUsefulData { + +public: + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcSolverUsefulData(); + + /** Copy constructor . + */ + CbcSolverUsefulData(const CbcSolverUsefulData & rhs); + + /// Assignment operator + CbcSolverUsefulData & operator=(const CbcSolverUsefulData& rhs); + + /// Destructor + ~CbcSolverUsefulData (); + //@} + + ///@name Member data + //@{ + // For time + double totalTime_; + // Parameters + CbcOrClpParam parameters_[CBCMAXPARAMETERS]; + // Printing + bool noPrinting_; + // Whether to use signal handler + bool useSignalHandler_; + // Number of Parameters + int numberParameters_; + // Default pump tuning + int initialPumpTune_; + //@} +}; +/// And this uses it +// When we want to load up CbcModel with options first +void CbcMain0 (CbcModel & babSolver,CbcSolverUsefulData & solverData); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom),CbcSolverUsefulData & solverData); + +//############################################################################# + +/*! \brief A class to allow the use of unknown user functionality + + For example, access to a modelling language (CbcAmpl). +*/ +class CbcUser { + +public: + ///@name import/export methods + //@{ + /*! \brief Import - gets full command arguments + + \return + - -1 - no action + - 0 - data read in without error + - 1 - errors + */ + virtual int importData(CbcSolver * /*model*/, int & /*argc*/, char ** /*argv[]*/) { + return -1; + } + + /*! \brief Export + + Values for mode: + - 1 OsiClpSolver + - 2 CbcModel + - add 10 if infeasible from odd situation + */ + virtual void exportSolution(CbcSolver * /*model*/, + int /*mode*/, const char * /*message*/ = NULL) {} + + /// Export Data (i.e. at very end) + virtual void exportData(CbcSolver * /*model*/) {} + + /// Get useful stuff + virtual void fillInformation(CbcSolver * /*model*/, + CbcSolverUsefulData & /*info*/) {} + //@} + + ///@name usage methods + //@{ + /// CoinModel if valid + inline CoinModel *coinModel() const { + return coinModel_; + } + /// Other info - needs expanding + virtual void * stuff() { + return NULL; + } + /// Name + inline std::string name() const { + return userName_; + } + /// Solve (whatever that means) + virtual void solve(CbcSolver * model, const char * options) = 0; + /// Returns true if function knows about option + virtual bool canDo(const char * options) = 0; + //@} + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcUser(); + + /// Copy constructor + CbcUser(const CbcUser & rhs); + + /// Assignment operator + CbcUser & operator=(const CbcUser& rhs); + + /// Clone + virtual CbcUser * clone() const = 0; + + /// Destructor + virtual ~CbcUser (); + //@} + +protected: + ///@name Private member data + //@{ + + /// CoinModel + CoinModel * coinModel_; + + /// Name of user function + std::string userName_; + +//@} +}; +//############################################################################# + +/*! \brief Support the use of a call back class to decide whether to stop + + Definitely under construction. +*/ + +class CbcStopNow { + +public: + ///@name Decision methods + //@{ + /*! \brief Import + + Values for whereFrom: + - 1 after initial solve by dualsimplex etc + - 2 after preprocessing + - 3 just before branchAndBound (so user can override) + - 4 just after branchAndBound (before postprocessing) + - 5 after postprocessing + - 6 after a user called heuristic phase + + \return 0 if good + nonzero return code to stop + */ + virtual int callBack(CbcModel * /*currentSolver*/, int /*whereFrom*/) { + return 0; + } + //@} + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcStopNow(); + + /** Copy constructor . + */ + CbcStopNow(const CbcStopNow & rhs); + + /// Assignment operator + CbcStopNow & operator=(const CbcStopNow& rhs); + + /// Clone + virtual CbcStopNow * clone() const; + + /// Destructor + virtual ~CbcStopNow (); + //@} + +private: + ///@name Private member data + //@{ +//@} +}; +#endif + diff --git a/thirdparty/linux/include/coin/CbcStrategy.hpp b/thirdparty/linux/include/coin/CbcStrategy.hpp new file mode 100644 index 0000000..a9c8d24 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcStrategy.hpp @@ -0,0 +1,258 @@ +/* $Id: CbcStrategy.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcStrategy_H +#define CbcStrategy_H + +#include "CbcModel.hpp" +class CglPreProcess; +class CbcNodeInfo; +class CbcNode; +class CoinWarmStartDiff; + +//############################################################################# +/** Strategy base class */ + +class CbcStrategy { +public: + // Default Constructor + CbcStrategy (); + + virtual ~CbcStrategy(); + + /// Clone + virtual CbcStrategy * clone() const = 0; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model) = 0; + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model) = 0; + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) = 0; + /// Other stuff e.g. strong branching and preprocessing + virtual void setupOther(CbcModel & model) = 0; + /// Set model depth (i.e. how nested) + inline void setNested(int depth) { + depth_ = depth; + } + /// Get model depth (i.e. how nested) + inline int getNested() const { + return depth_; + } + /// Say preProcessing done + inline void setPreProcessState(int state) { + preProcessState_ = state; + } + /// See what sort of preprocessing was done + inline int preProcessState() const { + return preProcessState_; + } + /// Pre-processing object + inline CglPreProcess * process() const { + return process_; + } + /// Delete pre-processing object to save memory + void deletePreProcess(); + /// Return a new Full node information pointer (descendant of CbcFullNodeInfo) + virtual CbcNodeInfo * fullNodeInfo(CbcModel * model, int numberRowsAtContinuous) const; + /// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo) + virtual CbcNodeInfo * partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds, const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /** After a CbcModel::resolve this can return a status + -1 no effect + 0 treat as optimal + 1 as 0 but do not do any more resolves (i.e. no more cuts) + 2 treat as infeasible + */ + virtual int status(CbcModel * model, CbcNodeInfo * parent, int whereFrom); +private: + + /// Illegal Assignment operator + CbcStrategy & operator=(const CbcStrategy& rhs); +protected: + // Data + /// Model depth + int depth_; + /** PreProcessing state - + -1 infeasible + 0 off + 1 was done (so need post-processing) + */ + int preProcessState_; + /// If preprocessing then this is object + CglPreProcess * process_; +}; + +/** Null class + */ + +class CbcStrategyNull : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyNull () {} + + // Copy constructor + CbcStrategyNull ( const CbcStrategyNull & rhs) : CbcStrategy(rhs) {} + + // Destructor + ~CbcStrategyNull () {} + + /// Clone + virtual CbcStrategy * clone() const { + return new CbcStrategyNull(*this); + } + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & ) {} + /// Setup heuristics + virtual void setupHeuristics(CbcModel & ) {} + /// Do printing stuff + virtual void setupPrinting(CbcModel & , int ) {} + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & ) {} + +protected: + // Data +private: + /// Illegal Assignment operator + CbcStrategyNull & operator=(const CbcStrategyNull& rhs); +}; + +/** Default class + */ + +class CbcStrategyDefault : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyDefault (int cutsOnlyAtRoot = 1, + int numberStrong = 5, + int numberBeforeTrust = 0, + int printLevel = 0); + + // Copy constructor + CbcStrategyDefault ( const CbcStrategyDefault &); + + // Destructor + ~CbcStrategyDefault (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) ; + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & model); + /// Set up preProcessing - see below + inline void setupPreProcessing(int desired = 1, int passes = 10) { + desiredPreProcess_ = desired; + preProcessPasses_ = passes; + } + /// See what sort of preprocessing wanted + inline int desiredPreProcess() const { + return desiredPreProcess_; + } + /// See how many passes wanted + inline int preProcessPasses() const { + return preProcessPasses_; + } + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + +protected: + // Data + + // Whether to do cuts only at root (-1 -> switch off totally) + int cutsOnlyAtRoot_; + + // How much strong branching to do + int numberStrong_; + + // Number branches needed to trust with dynamic pseudo costs + int numberBeforeTrust_; + + // Print level 0 little, 1 medium + int printLevel_; + + /** Desired pre-processing + 0 - none + 1 - ordinary + 2 - find sos + 3 - find cliques + 4 - more aggressive sos + 5 - add integer slacks + */ + int desiredPreProcess_; + /// Number of pre-processing passes + int preProcessPasses_; + +private: + /// Illegal Assignment operator + CbcStrategyDefault & operator=(const CbcStrategyDefault& rhs); +}; + + +/** Default class for sub trees + */ + +class CbcStrategyDefaultSubTree : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyDefaultSubTree (CbcModel * parent = NULL, int cutsOnlyAtRoot = 1, + int numberStrong = 5, + int numberBeforeTrust = 0, + int printLevel = 0); + + // Copy constructor + CbcStrategyDefaultSubTree ( const CbcStrategyDefaultSubTree &); + + // Destructor + ~CbcStrategyDefaultSubTree (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) ; + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & model); +protected: + // Data + // Parent model + CbcModel * parentModel_; + // Whether to do cuts only at root (-1 -> switch off totally) + int cutsOnlyAtRoot_; + + // How much strong branching to do + int numberStrong_; + + // Number branches needed to trust with dynamic pseudo costs + int numberBeforeTrust_; + + // Print level 0 little, 1 medium + int printLevel_; + +private: + /// Illegal Assignment operator + CbcStrategyDefaultSubTree & operator=(const CbcStrategyDefaultSubTree& rhs); +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/CbcSubProblem.hpp b/thirdparty/linux/include/coin/CbcSubProblem.hpp new file mode 100644 index 0000000..4a7a580 --- /dev/null +++ b/thirdparty/linux/include/coin/CbcSubProblem.hpp @@ -0,0 +1,83 @@ +// $Id: CbcSubProblem.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcSubProblem_H +#define CbcSubProblem_H + +#ifdef COIN_HAS_CLP +#include "ClpSimplex.hpp" +#include "ClpNode.hpp" + +/** Defines a general subproblem + Basis will be made more compact later +*/ +class CoinWarmStartDiff; +class CbcSubProblem { + +public: + + /// Default constructor + CbcSubProblem (); + + /// Constructor from model + CbcSubProblem (const OsiSolverInterface * solver, + const double * lowerBefore, + const double * upperBefore, + const unsigned char * status, + int depth); + + /// Copy constructor + CbcSubProblem ( const CbcSubProblem &); + + /// Assignment operator + CbcSubProblem & operator= (const CbcSubProblem& rhs); + + /// Destructor + virtual ~CbcSubProblem (); + + /// Take over + void takeOver ( CbcSubProblem &, bool cleanup); + /// Apply subproblem (1=bounds, 2=basis, 3=both) + void apply(OsiSolverInterface * model, int what = 3) const; + +public: + /// Value of objective + double objectiveValue_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Branch value + double branchValue_; + /// Dj on branching variable at end + double djValue_; + /** Which variable (top bit if upper bound changing) + next bit if changing on down branch only */ + int * variables_; + /// New bound + double * newBounds_; + /// Status + mutable CoinWarmStartBasis * status_; + /// Depth + int depth_; + /// Number of Extra bound changes + int numberChangedBounds_; + /// Number of infeasibilities + int numberInfeasibilities_; + /** Status 1 bit going up on first, 2 bit set first branch infeasible on second, 4 bit redundant branch, + bits after 256 give reason for stopping (just last node) + 0 - solution + 1 - infeasible + 2 - maximum depth + >2 - error or max time or something + */ + int problemStatus_; + /// Variable branched on + int branchVariable_; +}; + +#endif //COIN_HAS_CLP +#endif + diff --git a/thirdparty/linux/include/coin/CbcTree.hpp b/thirdparty/linux/include/coin/CbcTree.hpp new file mode 100644 index 0000000..92ea2bf --- /dev/null +++ b/thirdparty/linux/include/coin/CbcTree.hpp @@ -0,0 +1,490 @@ +/* $Id: CbcTree.hpp 1943 2013-07-21 09:05:45Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcTree_H +#define CbcTree_H + +#include <vector> +#include <algorithm> +#include <cmath> + +#include "CoinHelperFunctions.hpp" +#include "CbcCompare.hpp" + +/*! \brief Using MS heap implementation + + It's unclear if this is needed any longer, or even if it should be allowed. + Cbc occasionally tries to do things to the tree (typically tweaking the + comparison predicate) that can cause a violation of the heap property (parent better + than either child). In a debug build, Microsoft's heap implementation does checks that + detect this and fail. This symbol switched to an alternate implementation of CbcTree, + and there are clearly differences, but no explanation as to why or what for. + + As of 100921, the code is cleaned up to make it through `cbc -unitTest' without + triggering `Invalid heap' in an MSVS debug build. The method validateHeap() can + be used for debugging if this turns up again. +*/ +//#define CBC_DUBIOUS_HEAP +#if defined(_MSC_VER) || defined(__MNO_CYGWIN) +//#define CBC_DUBIOUS_HEAP +#endif +#if 1 //ndef CBC_DUBIOUS_HEAP + +/*! \brief Controls search tree debugging + + In order to have validateHeap() available, set CBC_DEBUG_HEAP + to 1 or higher. + + - 1 calls validateHeap() after each change to the heap + - 2 will print a line for major operations (clean, set comparison, etc.) + - 3 will print information about each push and pop + +#define CBC_DEBUG_HEAP 1 +*/ + + +/*! \class CbcTree + \brief Implementation of the live set as a heap. + + This class is used to hold the set of live nodes in the search tree. +*/ +class CbcTree { + +public: + /*! \name Constructors and related */ +//@{ + /// Default Constructor + CbcTree (); + + /// Copy constructor + CbcTree (const CbcTree &rhs); + + /// = operator + CbcTree & operator=(const CbcTree &rhs); + + /// Destructor + virtual ~CbcTree(); + + /// Clone + virtual CbcTree * clone() const; + + /// Create C++ lines to get to current state + virtual void generateCpp(FILE *) {} +//@} + + /*! \name Heap access and maintenance methods */ +//@{ + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode *x); + + /// Remove the top node from the heap + virtual void pop() ; + + /*! \brief Gets best node and takes off heap + + Before returning the node from the top of the heap, the node + is offered an opportunity to reevaluate itself. Callers should + be prepared to check that the node returned is suitable for use. + */ + virtual CbcNode * bestNode(double cutoff); + + /*! \brief Rebuild the heap */ + virtual void rebuild() ; +//@} + + /*! \name Direct node access methods */ +//@{ + /// Test for an empty tree + virtual bool empty() ; + + /// Return size + virtual int size() const { return static_cast<int>(nodes_.size()); } + + /// Return a node pointer + inline CbcNode * operator [] (int i) const { return nodes_[i]; } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { return nodes_[i]; } + void realpop(); + /** After changing data in the top node, fix the heap */ + void fixTop(); + void realpush(CbcNode * node); +//@} + + /*! \name Search tree maintenance */ +//@{ + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worse than the + specified cutoff value. It also sets bestPossibleObjective to + the best objective over remaining nodes. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + /// Reset maximum node number + inline void resetNodeNumbers() { maximumNodeNumber_ = 0; } + + /// Get maximum node number + inline int maximumNodeNumber() const { return maximumNodeNumber_; } + + /// Set number of branches + inline void setNumberBranching(int value) { numberBranching_ = value; } + + /// Get number of branches + inline int getNumberBranching() const { return numberBranching_; } + + /// Set maximum branches + inline void setMaximumBranching(int value) { maximumBranching_ = value; } + + /// Get maximum branches + inline int getMaximumBranching() const { return maximumBranching_; } + + /// Get branched variables + inline unsigned int * branched() const { return branched_; } + + /// Get bounds + inline int * newBounds() const { return newBound_; } + + /// Last objective in branch-and-cut search tree + inline double lastObjective() const { + return lastObjective_; + } + /// Last depth in branch-and-cut search tree + inline int lastDepth() const { + return lastDepth_; + } + /// Last number of objects unsatisfied + inline int lastUnsatisfied() const { + return lastUnsatisfied_; + } + /// Adds branching information to complete state + void addBranchingInformation(const CbcModel * model, const CbcNodeInfo * nodeInfo, + const double * currentLower, + const double * currentUpper); + /// Increase space for data + void increaseSpace(); +//@} + +# if CBC_DEBUG_HEAP > 0 + /*! \name Debugging methods */ + //@{ + /*! \brief Check that the heap property is satisfied. */ + void validateHeap() ; + //@} +# endif + +protected: + /// Storage vector for the heap + std::vector <CbcNode *> nodes_; + /// Sort predicate for heap ordering. + CbcCompare comparison_; + /// Maximum "node" number so far to split ties + int maximumNodeNumber_; + /// Size of variable list + int numberBranching_; + /// Maximum size of variable list + int maximumBranching_; + /// Objective of last node pushed on tree + double lastObjective_; + /// Depth of last node pushed on tree + int lastDepth_; + /// Number unsatisfied of last node pushed on tree + int lastUnsatisfied_; + /** Integer variables branched or bounded + top bit set if new upper bound + next bit set if a branch + */ + unsigned int * branched_; + /// New bound + int * newBound_; +}; + +#ifdef JJF_ZERO // not used +/*! \brief Implementation of live set as a managed array. + + This class is used to hold the set of live nodes in the search tree. +*/ +class CbcTreeArray : public CbcTree { + +public: + + // Default Constructor + CbcTreeArray (); + + // Copy constructor + CbcTreeArray ( const CbcTreeArray & rhs); + // = operator + CbcTreeArray & operator=(const CbcTreeArray & rhs); + + virtual ~CbcTreeArray(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + virtual bool empty() ; + +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); +//@} +protected: + /// Returns + /// Last node + CbcNode * lastNode_; + /// Last node popped + CbcNode * lastNodePopped_; + /// Not used yet + int switches_; + +}; + +/// New style +#include "CoinSearchTree.hpp" +/*! \class tree + \brief Implementation of live set as a heap. + + This class is used to hold the set of live nodes in the search tree. +*/ + +class CbcNewTree : public CbcTree, public CoinSearchTreeManager { + +public: + + // Default Constructor + CbcNewTree (); + + // Copy constructor + CbcNewTree ( const CbcNewTree & rhs); + // = operator + CbcNewTree & operator=(const CbcNewTree & rhs); + + virtual ~CbcNewTree(); + + /// Clone + virtual CbcNewTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// Return size + inline int size() const { + return nodes_.size(); + } + + /// [] operator + inline CbcNode * operator [] (int i) const { + return nodes_[i]; + } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { + return nodes_[i]; + } + +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} +//@} +protected: + + +}; +#endif +#else +/* CBC_DUBIOUS_HEAP is defined + + See note at top of file. This code is highly suspect. + -- lh, 100921 -- +*/ +class CbcTree { + +public: + + // Default Constructor + CbcTree (); + + // Copy constructor + CbcTree ( const CbcTree & rhs); + // = operator + CbcTree & operator=(const CbcTree & rhs); + + virtual ~CbcTree(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + //virtual bool empty() ; + + /// Return size + inline int size() const { + return nodes_.size(); + } + + /// [] operator + inline CbcNode * operator [] (int i) const { + return nodes_[i]; + } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { + return nodes_[i]; + } + + virtual bool empty(); + //inline int size() const { return size_; } + void realpop(); + /** After changing data in the top node, fix the heap */ + void fixTop(); + void realpush(CbcNode * node); +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} + /// Reset maximum node number + inline void resetNodeNumbers() { + maximumNodeNumber_ = 0; + } + + /// Get maximum node number + inline int maximumNodeNumber() const { return maximumNodeNumber_; } +//@} +protected: + std::vector <CbcNode *> nodes_; + CbcCompare comparison_; ///> Sort function for heap ordering. + /// Maximum "node" number so far to split ties + int maximumNodeNumber_; + + +}; +#endif +#endif + diff --git a/thirdparty/linux/include/coin/CbcTreeLocal.hpp b/thirdparty/linux/include/coin/CbcTreeLocal.hpp new file mode 100644 index 0000000..efff91c --- /dev/null +++ b/thirdparty/linux/include/coin/CbcTreeLocal.hpp @@ -0,0 +1,372 @@ +/* $Id: CbcTreeLocal.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcTreeLocal_H +#define CbcTreeLocal_H + +//############################################################################# +/* This implements (approximately) local branching as in the 2002 paper by + Matteo Fischetti and Andrea Lodi. + + The very simple version of the algorithm for problems with + 0-1 variables and continuous is as follows: + + Obtain a feasible solution (one can be passed in). + + Add a cut which limits search to a k neighborhood of this solution. + (At most k 0-1 variables may change value) + Do branch and bound on this problem. + + If finished search and proven optimal then we can reverse cut so + any solutions must be at least k+1 away from solution and we can + add a new cut limiting search to a k neighborhood of new solution + repeat. + + If finished search and no new solution then the simplest version + would reverse last cut and complete search. The version implemented + here can use time and node limits and can widen search (increase effective k) + .... and more + +*/ + +#include "CbcTree.hpp" +#include "CbcNode.hpp" +#include "OsiRowCut.hpp" +class CbcModel; + + +class CbcTreeLocal : public CbcTree { + +public: + + // Default Constructor + CbcTreeLocal (); + + /* Constructor with solution. + If solution NULL no solution, otherwise must be integer + range is initial upper bound (k) on difference from given solution. + typeCuts - + 0 means just 0-1 cuts and will need to refine 0-1 solution + 1 uses weaker cuts on all integer variables + maxDiversification is maximum number of range widenings to try + timeLimit is seconds in subTree + nodeLimit is nodes in subTree + refine is whether to see if we can prove current solution is optimal + when we fix all 0-1 (in case typeCuts==0 and there are general integer variables) + if false then no refinement but reverse cuts weaker + */ + CbcTreeLocal (CbcModel * model, const double * solution , int range = 10, + int typeCuts = 0, int maxDiversification = 0, + int timeLimit = 1000000, int nodeLimit = 1000000, bool refine = true); + // Copy constructor + CbcTreeLocal ( const CbcTreeLocal & rhs); + + // = operator + CbcTreeLocal & operator=(const CbcTreeLocal & rhs); + + virtual ~CbcTreeLocal(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + +//@} + /*! \name Other stuff */ +//@{ + + /// Create cut - return -1 if bad, 0 if okay and 1 if cut is everything + int createCut(const double * solution, OsiRowCut & cut); + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() ; + /// Other side of last cut branch (if bias==rhs_ will be weakest possible) + void reverseCut(int state, double bias = 0.0); + /// Delete last cut branch + void deleteCut(OsiRowCut & cut); + /// Pass in solution (so can be used after heuristic) + void passInSolution(const double * solution, double solutionValue); + // range i.e. k + inline int range() const { + return range_; + } + // setrange i.e. k + inline void setRange(int value) { + range_ = value; + } + // Type of cuts - 0=just 0-1, 1=all + inline int typeCuts() const { + return typeCuts_; + } + // Type of cuts - 0=just 0-1, 1=all + inline void setTypeCuts(int value) { + typeCuts_ = value; + } + // maximum number of diversifications + inline int maxDiversification() const { + return maxDiversification_; + } + // maximum number of diversifications + inline void setMaxDiversification(int value) { + maxDiversification_ = value; + } + // time limit per subtree + inline int timeLimit() const { + return timeLimit_; + } + // time limit per subtree + inline void setTimeLimit(int value) { + timeLimit_ = value; + } + // node limit for subtree + inline int nodeLimit() const { + return nodeLimit_; + } + // node limit for subtree + inline void setNodeLimit(int value) { + nodeLimit_ = value; + } + // Whether to do refinement step + inline bool refine() const { + return refine_; + } + // Whether to do refinement step + inline void setRefine(bool yesNo) { + refine_ = yesNo; + } + +//@} +private: + // Node for local cuts + CbcNode * localNode_; + // best solution + double * bestSolution_; + // saved solution + double * savedSolution_; + // solution number at start of pass + int saveNumberSolutions_; + /* Cut. If zero size then no solution yet. Otherwise is left hand branch */ + OsiRowCut cut_; + // This cut fixes all 0-1 variables + OsiRowCut fixedCut_; + // Model + CbcModel * model_; + // Original lower bounds + double * originalLower_; + // Original upper bounds + double * originalUpper_; + // range i.e. k + int range_; + // Type of cuts - 0=just 0-1, 1=all + int typeCuts_; + // maximum number of diversifications + int maxDiversification_; + // current diversification + int diversification_; + // Whether next will be strong diversification + bool nextStrong_; + // Current rhs + double rhs_; + // Save allowable gap + double savedGap_; + // Best solution + double bestCutoff_; + // time limit per subtree + int timeLimit_; + // time when subtree started + int startTime_; + // node limit for subtree + int nodeLimit_; + // node count when subtree started + int startNode_; + // -1 not started, 0 == stop on first solution, 1 don't stop on first, 2 refinement step + int searchType_; + // Whether to do refinement step + bool refine_; + +}; + +class CbcTreeVariable : public CbcTree { + +public: + + // Default Constructor + CbcTreeVariable (); + + /* Constructor with solution. + If solution NULL no solution, otherwise must be integer + range is initial upper bound (k) on difference from given solution. + typeCuts - + 0 means just 0-1 cuts and will need to refine 0-1 solution + 1 uses weaker cuts on all integer variables + maxDiversification is maximum number of range widenings to try + timeLimit is seconds in subTree + nodeLimit is nodes in subTree + refine is whether to see if we can prove current solution is optimal + when we fix all 0-1 (in case typeCuts==0 and there are general integer variables) + if false then no refinement but reverse cuts weaker + */ + CbcTreeVariable (CbcModel * model, const double * solution , int range = 10, + int typeCuts = 0, int maxDiversification = 0, + int timeLimit = 1000000, int nodeLimit = 1000000, bool refine = true); + // Copy constructor + CbcTreeVariable ( const CbcTreeVariable & rhs); + + // = operator + CbcTreeVariable & operator=(const CbcTreeVariable & rhs); + + virtual ~CbcTreeVariable(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + +//@} + /*! \name Other stuff */ +//@{ + + /// Create cut - return -1 if bad, 0 if okay and 1 if cut is everything + int createCut(const double * solution, OsiRowCut & cut); + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() ; + /// Other side of last cut branch (if bias==rhs_ will be weakest possible) + void reverseCut(int state, double bias = 0.0); + /// Delete last cut branch + void deleteCut(OsiRowCut & cut); + /// Pass in solution (so can be used after heuristic) + void passInSolution(const double * solution, double solutionValue); + // range i.e. k + inline int range() const { + return range_; + } + // setrange i.e. k + inline void setRange(int value) { + range_ = value; + } + // Type of cuts - 0=just 0-1, 1=all + inline int typeCuts() const { + return typeCuts_; + } + // Type of cuts - 0=just 0-1, 1=all + inline void setTypeCuts(int value) { + typeCuts_ = value; + } + // maximum number of diversifications + inline int maxDiversification() const { + return maxDiversification_; + } + // maximum number of diversifications + inline void setMaxDiversification(int value) { + maxDiversification_ = value; + } + // time limit per subtree + inline int timeLimit() const { + return timeLimit_; + } + // time limit per subtree + inline void setTimeLimit(int value) { + timeLimit_ = value; + } + // node limit for subtree + inline int nodeLimit() const { + return nodeLimit_; + } + // node limit for subtree + inline void setNodeLimit(int value) { + nodeLimit_ = value; + } + // Whether to do refinement step + inline bool refine() const { + return refine_; + } + // Whether to do refinement step + inline void setRefine(bool yesNo) { + refine_ = yesNo; + } + +//@} +private: + // Node for local cuts + CbcNode * localNode_; + // best solution + double * bestSolution_; + // saved solution + double * savedSolution_; + // solution number at start of pass + int saveNumberSolutions_; + /* Cut. If zero size then no solution yet. Otherwise is left hand branch */ + OsiRowCut cut_; + // This cut fixes all 0-1 variables + OsiRowCut fixedCut_; + // Model + CbcModel * model_; + // Original lower bounds + double * originalLower_; + // Original upper bounds + double * originalUpper_; + // range i.e. k + int range_; + // Type of cuts - 0=just 0-1, 1=all + int typeCuts_; + // maximum number of diversifications + int maxDiversification_; + // current diversification + int diversification_; + // Whether next will be strong diversification + bool nextStrong_; + // Current rhs + double rhs_; + // Save allowable gap + double savedGap_; + // Best solution + double bestCutoff_; + // time limit per subtree + int timeLimit_; + // time when subtree started + int startTime_; + // node limit for subtree + int nodeLimit_; + // node count when subtree started + int startNode_; + // -1 not started, 0 == stop on first solution, 1 don't stop on first, 2 refinement step + int searchType_; + // Whether to do refinement step + bool refine_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/Cbc_C_Interface.h b/thirdparty/linux/include/coin/Cbc_C_Interface.h new file mode 100644 index 0000000..fc15774 --- /dev/null +++ b/thirdparty/linux/include/coin/Cbc_C_Interface.h @@ -0,0 +1,381 @@ +/* $Id: Cbc_C_Interface.h 2091 2014-10-03 00:46:49Z mlubin $ */ +/* + Copyright (C) 2004 International Business Machines Corporation and others. + All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef CbcModelC_H +#define CbcModelC_H + +/* include all defines and ugly stuff */ +#include "Coin_C_defines.h" +#include <stddef.h> + +/* + * Original verison contributed by Bob Entriken, + * significantly updated by Miles Lubin. +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + /**@name Constructors and destructor + This is a "C" interface to Cbc. + The user does not need to know structure of Cbc_Model. + */ + /*@{*/ + + /** Default Cbc_Model constructor */ + COINLIBAPI Cbc_Model * COINLINKAGE + Cbc_newModel(void) + ; + /** Cbc_Model Destructor */ + COINLIBAPI void COINLINKAGE + Cbc_deleteModel(Cbc_Model * model) + ; + /** Current version of Cbc */ + COINLIBAPI const char* COINLINKAGE Cbc_getVersion(void) + ; + /*@}*/ + + /**@name Getting and setting model data + Note that problem access and modification methods, + such as getColLower and setColLower, + are *not valid* after calling Cbc_solve(). + Therefore it is not recommended to reuse a Cbc_Model + object for multiple solves. A workaround is to call Cbc_clone() + before solving. + * */ + /*@{*/ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + The constraint matrix is + given in standard compressed sparse column (without gaps). + <ul> + <li> <code>start[i]</code> stores the starting index of the ith column + <li> <code>index[k]</code> stores the row index of the kth nonzero element + <li> <code>value[k]</code> stores the coefficient of the kth nonzero element + </ul> + */ + COINLIBAPI void COINLINKAGE + Cbc_loadProblem (Cbc_Model * model, const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + ; + /** Read an mps file from the given filename */ + COINLIBAPI int COINLINKAGE + Cbc_readMps(Cbc_Model * model, const char *filename) + ; + /** Write an mps file from the given filename */ + COINLIBAPI void COINLINKAGE + Cbc_writeMps(Cbc_Model * model, const char *filename) + ; + /** Provide an initial feasible solution to accelerate branch-and-bound + Note that feasibility of the solution is *not* verified. + */ + COINLIBAPI void COINLINKAGE + Cbc_setInitialSolution(Cbc_Model *model, const double * sol) + ; + /** Fills in array with problem name */ + COINLIBAPI void COINLINKAGE + Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array) + ; + /** Sets problem name. + + \p array must be a null-terminated string. + */ + COINLIBAPI int COINLINKAGE + Cbc_setProblemName(Cbc_Model * model, const char * array) + ; + + /** Number of nonzero elements in constraint matrix */ + COINLIBAPI int COINLINKAGE + Cbc_getNumElements(Cbc_Model * model) + ; + /** "Column start" vector of constraint matrix. Same format as Cbc_loadProblem() */ + COINLIBAPI const CoinBigIndex * COINLINKAGE + Cbc_getVectorStarts(Cbc_Model * model) + ; + /** "Row index" vector of constraint matrix */ + COINLIBAPI const int * COINLINKAGE + Cbc_getIndices(Cbc_Model * model) + ; + /** Coefficient vector of constraint matrix */ + COINLIBAPI const double * COINLINKAGE + Cbc_getElements(Cbc_Model * model) + ; + + /** Maximum lenght of a row or column name */ + COINLIBAPI size_t COINLINKAGE + Cbc_maxNameLength(Cbc_Model * model) + ; + /** Fill in first maxLength bytes of name array with a row name */ + COINLIBAPI void COINLINKAGE + Cbc_getRowName(Cbc_Model * model, int iRow, char * name, size_t maxLength) + ; + /** Fill in first maxLength bytes of name array with a column name */ + COINLIBAPI void COINLINKAGE + Cbc_getColName(Cbc_Model * model, int iColumn, char * name, size_t maxLength) + ; + /** Set the name of a column */ + COINLIBAPI void COINLINKAGE + Cbc_setColName(Cbc_Model * model, int iColumn, const char * name) + ; + /** Set the name of a row */ + COINLIBAPI void COINLINKAGE + Cbc_setRowName(Cbc_Model * model, int iRow, const char * name) + ; + /** Number of constraints in the model */ + COINLIBAPI int COINLINKAGE + Cbc_getNumRows(Cbc_Model * model) + ; + /** Number of variables in the model */ + COINLIBAPI int COINLINKAGE + Cbc_getNumCols(Cbc_Model * model) + ; + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore) */ + COINLIBAPI void COINLINKAGE + Cbc_setObjSense(Cbc_Model * model, double sense) + ; + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore) */ + COINLIBAPI double COINLINKAGE + Cbc_getObjSense(Cbc_Model * model) + ; + /** Constraint lower bounds */ + COINLIBAPI const double* COINLINKAGE + Cbc_getRowLower(Cbc_Model * model) + ; + /** Set the lower bound of a single constraint */ + COINLIBAPI void COINLINKAGE + Cbc_setRowLower(Cbc_Model * model, int index, double value) + ; + /** Constraint upper bounds */ + COINLIBAPI const double* COINLINKAGE + Cbc_getRowUpper(Cbc_Model * model) + ; + /** Set the upper bound of a single constraint */ + COINLIBAPI void COINLINKAGE + Cbc_setRowUpper(Cbc_Model * model, int index, double value) + ; + /** Objective vector */ + COINLIBAPI const double * COINLINKAGE + Cbc_getObjCoefficients(Cbc_Model * model) + ; + /** Set the objective coefficient of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setObjCoeff(Cbc_Model * model, int index, double value) + ; + /** Variable lower bounds */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColLower(Cbc_Model * model) + ; + /** Set the lower bound of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setColLower(Cbc_Model * model, int index, double value) + ; + /** Variable upper bounds */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColUpper(Cbc_Model * model) + ; + /** Set the upper bound of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setColUpper(Cbc_Model * model, int index, double value) + ; + /** Determine whether the ith variable is integer restricted */ + COINLIBAPI int COINLINKAGE + Cbc_isInteger(Cbc_Model * model, int i) + ; + /** Set this variable to be continuous */ + COINLIBAPI void COINLINKAGE + Cbc_setContinuous(Cbc_Model * model, int iColumn) + ; + /** Set this variable to be integer */ + COINLIBAPI void COINLINKAGE + Cbc_setInteger(Cbc_Model * model, int iColumn) + ; + /** Add SOS constraints to the model using row-order matrix */ + COINLIBAPI void COINLINKAGE + Cbc_addSOS(Cbc_Model * model, int numRows, const int * rowStarts, + const int * colIndices, const double * weights, const int type) + ; + /** Print the model */ + COINLIBAPI void COINLINKAGE + Cbc_printModel(Cbc_Model * model, const char * argPrefix) + ; + /** Return a copy of this model */ + COINLIBAPI Cbc_Model * COINLINKAGE + Cbc_clone(Cbc_Model * model) + ; + /*@}*/ + /**@name Solver parameters */ + /*@{*/ + /** Set parameter "name" to value "value". Note that this + * translates directly to using "-name value" as a + * command-line argument to Cbc.*/ + COINLIBAPI void COINLINKAGE + Cbc_setParameter(Cbc_Model * model, const char * name, const char * value) + ; + + + /*@}*/ + /**@name Message handling. Call backs are handled by ONE function */ + /*@{*/ + /** Pass in Callback function. + Message numbers up to 1000000 are Clp, Coin ones have 1000000 added */ + COINLIBAPI void COINLINKAGE + Cbc_registerCallBack(Cbc_Model * model, + cbc_callback userCallBack) + ; + /** Unset Callback function */ + COINLIBAPI void COINLINKAGE + Cbc_clearCallBack(Cbc_Model * model) + ; + + /*@}*/ + + + /**@name Solving the model */ + /*@{*/ + /* Solve the model with Cbc (using CbcMain1). + */ + COINLIBAPI int COINLINKAGE + Cbc_solve(Cbc_Model * model) + ; + /*@}*/ + + + /**@name Accessing the solution and solution status */ + /*@{*/ + + /** Sum of primal infeasibilities */ + COINLIBAPI double COINLINKAGE + Cbc_sumPrimalInfeasibilities(Cbc_Model * model) + ; + /** Number of primal infeasibilities */ + COINLIBAPI int COINLINKAGE + Cbc_numberPrimalInfeasibilities(Cbc_Model * model) + ; + + /** Just check solution (for external use) - sets sum of + infeasibilities etc */ + COINLIBAPI void COINLINKAGE + Cbc_checkSolution(Cbc_Model * model) + ; + + /** Number of iterations */ + COINLIBAPI int COINLINKAGE + Cbc_getIterationCount(Cbc_Model * model) + ; + /** Are there a numerical difficulties? */ + COINLIBAPI int COINLINKAGE + Cbc_isAbandoned(Cbc_Model * model) + ; + /** Is optimality proven? */ + COINLIBAPI int COINLINKAGE + Cbc_isProvenOptimal(Cbc_Model * model) + ; + /** Is infeasiblity proven (or none better than cutoff)? */ + COINLIBAPI int COINLINKAGE + Cbc_isProvenInfeasible(Cbc_Model * model) + ; + /** Was continuous solution unbounded? */ + COINLIBAPI int COINLINKAGE + Cbc_isContinuousUnbounded(Cbc_Model * model) + ; + /** Node limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isNodeLimitReached(Cbc_Model * model) + ; + /** Time limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isSecondsLimitReached(Cbc_Model * model) + ; + /** Solution limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isSolutionLimitReached(Cbc_Model * model) + ; + /** Are there numerical difficulties (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveAbandoned(Cbc_Model * model) + ; + /** Is optimality proven (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveProvenOptimal(Cbc_Model * model) + ; + /** Is primal infeasiblity proven (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveProvenPrimalInfeasible(Cbc_Model * model) + ; + /** "row" solution + * This is the vector A*x, where A is the constraint matrix + * and x is the current solution. */ + COINLIBAPI const double * COINLINKAGE + Cbc_getRowActivity(Cbc_Model * model) + ; + /** Best feasible solution vector */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColSolution(Cbc_Model * model) + ; + /** Objective value of best feasible solution */ + COINLIBAPI double COINLINKAGE + Cbc_getObjValue(Cbc_Model * model) + ; + /** Best known bound on the optimal objective value */ + COINLIBAPI double COINLINKAGE + Cbc_getBestPossibleObjValue(Cbc_Model * model) + ; + /** Number of nodes explored in B&B tree */ + COINLIBAPI int COINLINKAGE + Cbc_getNodeCount(Cbc_Model * model) + ; + /** Print the solution */ + COINLIBAPI void COINLINKAGE + Cbc_printSolution(Cbc_Model * model) + ; + /** Final status of problem + Some of these can be found out by is...... functions + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + */ + COINLIBAPI int COINLINKAGE + Cbc_status(Cbc_Model * model) + ; + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + 8 stopped on iteration limit + */ + COINLIBAPI int COINLINKAGE + Cbc_secondaryStatus(Cbc_Model * model) + ; + /*@}*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin/CglClique.hpp b/thirdparty/linux/include/coin/CglClique.hpp index 5b47b40..288052d 100644 --- a/thirdparty/linux/include/coin/CglClique.hpp +++ b/thirdparty/linux/include/coin/CglClique.hpp @@ -1,4 +1,4 @@ -// $Id: CglClique.hpp 1119 2013-04-06 20:24:18Z stefan $ +// $Id: CglClique.hpp 1330 2016-01-26 19:35:16Z forrest $ // Copyright (C) 2000, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -86,6 +86,8 @@ public: void setMinViolation(double minviol) { petol = minviol; } double getMinViolation() const { return petol; } + /// Maximum number of binaries for looking at all + inline void setMaxNumber(int value) { maxNumber_ = value; } private: @@ -157,6 +159,8 @@ protected: /** The primal tolerance in the solverinterface. */ double petol; + /// Maximum number of binaries for looking at all + int maxNumber_; /** data for the star clique algorithm */ diff --git a/thirdparty/linux/include/coin/CglConfig.h b/thirdparty/linux/include/coin/CglConfig.h index bca5553..a4de202 100644 --- a/thirdparty/linux/include/coin/CglConfig.h +++ b/thirdparty/linux/include/coin/CglConfig.h @@ -5,7 +5,7 @@ #define __CONFIG_CGL_H__ /* Version number of project */ -#define CGL_VERSION "0.59.4" +#define CGL_VERSION "0.59.9" /* Major Version number of project */ #define CGL_VERSION_MAJOR 0 @@ -14,6 +14,6 @@ #define CGL_VERSION_MINOR 59 /* Release Version number of project */ -#define CGL_VERSION_RELEASE 4 +#define CGL_VERSION_RELEASE 9 #endif diff --git a/thirdparty/linux/include/coin/CglLandPValidator.hpp b/thirdparty/linux/include/coin/CglLandPValidator.hpp index 8b05597..b9e363d 100644 --- a/thirdparty/linux/include/coin/CglLandPValidator.hpp +++ b/thirdparty/linux/include/coin/CglLandPValidator.hpp @@ -4,7 +4,7 @@ // Carnegie Mellon University, Pittsburgh, PA 15213 // Date: 11/22/05 // -// $Id: CglLandPValidator.hpp 1122 2013-04-06 20:39:53Z stefan $ +// $Id: CglLandPValidator.hpp 1302 2015-08-14 15:48:32Z stefan $ // // This code is licensed under the terms of the Eclipse Public License (EPL). //--------------------------------------------------------------------------- @@ -93,11 +93,11 @@ public: } /** @} */ - const std::string& failureString(RejectionsReasons code) const + const char* failureString(RejectionsReasons code) const { return rejections_[static_cast<int> (code)]; } - const std::string& failureString(int code) const + const char* failureString(int code) const { return rejections_[ code]; } @@ -110,7 +110,6 @@ public: return numRejected_[ code]; } private: - static void fillRejectionReasons(); /** max percentage of given formulation fillIn should be accepted for cut fillin.*/ double maxFillIn_; /** max ratio between smallest and biggest coefficient */ @@ -122,7 +121,7 @@ private: /** Scale of right-hand-side.*/ double rhsScale_; /** Strings explaining reason for rejections */ - static std::vector<std::string> rejections_; + static const char* rejections_[DummyEnd]; /** Number of cut rejected for each of the reasons.*/ std::vector<int> numRejected_; }; diff --git a/thirdparty/linux/include/coin/ClpAmplObjective.hpp b/thirdparty/linux/include/coin/ClpAmplObjective.hpp new file mode 100644 index 0000000..32b04e4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpAmplObjective.hpp @@ -0,0 +1,113 @@ +/* $Id: ClpAmplObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpAmplObjective_H +#define ClpAmplObjective_H + +#include "ClpObjective.hpp" +#include "CoinPackedMatrix.hpp" + +//############################################################################# + +/** Ampl Objective Class + +*/ + +class ClpAmplObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Ampl then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /// Resize objective + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() ; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpAmplObjective(); + + /// Constructor from ampl info + ClpAmplObjective(void * amplInfo); + + /** Copy constructor . + */ + ClpAmplObjective(const ClpAmplObjective & rhs); + + /// Assignment operator + ClpAmplObjective & operator=(const ClpAmplObjective& rhs); + + /// Destructor + virtual ~ClpAmplObjective (); + + /// Clone + virtual ClpObjective * clone() const; + + //@} + ///@name Gets and sets + //@{ + /// Linear objective + double * linearObjective() const; + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Saved offset + double offset_; + /// Ampl info + void * amplObjective_; + /// Objective + double * objective_; + /// Gradient + double * gradient_; + //@} +}; + +#endif + diff --git a/thirdparty/linux/include/coin/ClpCholeskyMumps.hpp b/thirdparty/linux/include/coin/ClpCholeskyMumps.hpp new file mode 100644 index 0000000..48261d7 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpCholeskyMumps.hpp @@ -0,0 +1,63 @@ +/* $Id: ClpCholeskyMumps.hpp 1692 2011-03-05 18:05:01Z stefan $ */ +// Copyright (C) 2009, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpCholeskyMumps_H +#define ClpCholeskyMumps_H +#include "ClpCholeskyBase.hpp" +class ClpMatrixBase; +class ClpCholeskyDense; + +// unfortunately, DMUMPS_STRUC_C is an anonymous struct in MUMPS, so we define it to void for everyone outside ClpCholeskyMumps +// if this file is included by ClpCholeskyMumps.cpp, then after dmumps_c.h has been included, which defines MUMPS_VERSION +#ifndef MUMPS_VERSION +typedef void DMUMPS_STRUC_C; +#endif + +/** Mumps class for Clp Cholesky factorization + +*/ +class ClpCholeskyMumps : public ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes provides */ + //@{ + /** Orders rows and saves pointer to matrix.and model. + Returns non-zero if not enough memory */ + virtual int order(ClpInterior * model) ; + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const double * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (double * region) ; + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Constructor which has dense columns activated. + Default is off. */ + ClpCholeskyMumps(int denseThreshold = -1); + /** Destructor */ + virtual ~ClpCholeskyMumps(); + /// Clone + virtual ClpCholeskyBase * clone() const ; + //@} + +private: + // Mumps structure + DMUMPS_STRUC_C* mumps_; + + // Copy + ClpCholeskyMumps(const ClpCholeskyMumps&); + // Assignment + ClpCholeskyMumps& operator=(const ClpCholeskyMumps&); +}; + +#endif diff --git a/thirdparty/linux/include/coin/ClpConfig.h b/thirdparty/linux/include/coin/ClpConfig.h index d10a206..2e3620f 100644 --- a/thirdparty/linux/include/coin/ClpConfig.h +++ b/thirdparty/linux/include/coin/ClpConfig.h @@ -5,7 +5,7 @@ /* #undef CLP_HAS_ABC */ /* Version number of project */ -#define CLP_VERSION "1.16.6" +#define CLP_VERSION "1.16.10" /* Major Version number of project */ #define CLP_VERSION_MAJOR 1 @@ -14,4 +14,4 @@ #define CLP_VERSION_MINOR 16 /* Release Version number of project */ -#define CLP_VERSION_RELEASE 6 +#define CLP_VERSION_RELEASE 10 diff --git a/thirdparty/linux/include/coin/ClpConstraintAmpl.hpp b/thirdparty/linux/include/coin/ClpConstraintAmpl.hpp new file mode 100644 index 0000000..1ca0ab4 --- /dev/null +++ b/thirdparty/linux/include/coin/ClpConstraintAmpl.hpp @@ -0,0 +1,108 @@ +/* $Id: ClpConstraintAmpl.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintAmpl_H +#define ClpConstraintAmpl_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Ampl Constraint Class + +*/ + +class ClpConstraintAmpl : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Ampl then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonampl columns to 1. + Returns number of nonampl columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() ; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintAmpl(); + + /// Constructor from ampl + ClpConstraintAmpl(int row, void * amplInfo); + + /** Copy constructor . + */ + ClpConstraintAmpl(const ClpConstraintAmpl & rhs); + + /// Assignment operator + ClpConstraintAmpl & operator=(const ClpConstraintAmpl& rhs); + + /// Destructor + virtual ~ClpConstraintAmpl (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Ampl info + void * amplInfo_; + /// Column + int * column_; + /// Coefficients + double * coefficient_; + /// Number of coefficients in gradient + int numberCoefficients_; + //@} +}; + +#endif + diff --git a/thirdparty/linux/include/coin/ClpEventHandler.hpp b/thirdparty/linux/include/coin/ClpEventHandler.hpp index 0a49c83..aeed324 100644 --- a/thirdparty/linux/include/coin/ClpEventHandler.hpp +++ b/thirdparty/linux/include/coin/ClpEventHandler.hpp @@ -1,4 +1,4 @@ -/* $Id: ClpEventHandler.hpp 1825 2011-11-20 16:02:57Z forrest $ */ +/* $Id: ClpEventHandler.hpp 2156 2015-08-07 14:51:42Z forrest $ */ // Copyright (C) 2004, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -67,6 +67,7 @@ public: modifyMatrixInMiniPresolve, moreMiniPresolve, modifyMatrixInMiniPostsolve, + startOfCrossover, // in Idiot noTheta // At end (because no pivot) }; /**@name Virtual method that the derived classes should provide. diff --git a/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp b/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp index 16d3c91..8610adb 100644 --- a/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp +++ b/thirdparty/linux/include/coin/CoinPresolveDupcol.hpp @@ -1,4 +1,4 @@ -/* $Id: CoinPresolveDupcol.hpp 1817 2015-03-22 16:43:28Z forrest $ */ +/* $Id: CoinPresolveDupcol.hpp 1854 2015-12-18 14:18:54Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -152,15 +152,19 @@ class duprow3_action : public CoinPresolveAction { class gubrow_action : public CoinPresolveAction { struct action { - int row; - double lbound; - double ubound; + double rhs; + // last is row itself + int * deletedRow; + double * rowels; + int * indices; // indices in gub row + int nDrop; + int ninrow; }; const int nactions_; const action *const actions_; - gubrow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + //gubrow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} gubrow_action(int nactions, const action *actions, const CoinPresolveAction *next) : @@ -175,7 +179,7 @@ class gubrow_action : public CoinPresolveAction { void postsolve(CoinPostsolveMatrix *prob) const; - //~gubrow_action() { delete[]actions_; } + virtual ~gubrow_action(); }; /*! \class twoxtwo_action diff --git a/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp b/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp index d72479a..445278e 100644 --- a/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp +++ b/thirdparty/linux/include/coin/CoinPresolvePsdebug.hpp @@ -1,4 +1,4 @@ -/* $Id: CoinPresolvePsdebug.hpp 1560 2012-11-24 00:29:01Z lou $ */ +/* $Id: CoinPresolvePsdebug.hpp 1854 2015-12-18 14:18:54Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -161,6 +161,9 @@ void presolve_check_nbasic(const CoinPresolveMatrix *preObj) ; */ void presolve_check_nbasic(const CoinPostsolveMatrix *postObj) ; +/// get a row copy in postsolve +void postsolve_get_rowcopy(const CoinPostsolveMatrix *postObj, + int * & rowStarts, int * & columns, double * & elements ) ; //@} #endif diff --git a/thirdparty/linux/include/coin/CoinSearchTree.hpp b/thirdparty/linux/include/coin/CoinSearchTree.hpp index a0ce8e3..f7c101d 100644 --- a/thirdparty/linux/include/coin/CoinSearchTree.hpp +++ b/thirdparty/linux/include/coin/CoinSearchTree.hpp @@ -1,4 +1,4 @@ -/* $Id: CoinSearchTree.hpp 1685 2014-01-27 03:05:07Z tkr $ */ +/* $Id: CoinSearchTree.hpp 1824 2015-04-04 16:27:28Z tkr $ */ // Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -243,7 +243,7 @@ public: inline int size() const { return size_; } inline int numInserted() const { return numInserted_; } inline CoinTreeNode* top() const { - if (size_ == 0) + if (size_ == 0 || candidateList_.size() == 0) return NULL; #ifdef DEBUG_PRINT char output[44]; diff --git a/thirdparty/linux/include/coin/CoinUtilsConfig.h b/thirdparty/linux/include/coin/CoinUtilsConfig.h index 8d656d5..d7e8eaa 100644 --- a/thirdparty/linux/include/coin/CoinUtilsConfig.h +++ b/thirdparty/linux/include/coin/CoinUtilsConfig.h @@ -11,7 +11,7 @@ /* #undef COINUTILS_HAS_CSTDINT */ /* Version number of project */ -#define COINUTILS_VERSION "2.10.6" +#define COINUTILS_VERSION "2.10.13" /* Major Version number of project */ #define COINUTILS_VERSION_MAJOR 2 @@ -20,7 +20,7 @@ #define COINUTILS_VERSION_MINOR 10 /* Release Version number of project */ -#define COINUTILS_VERSION_RELEASE 6 +#define COINUTILS_VERSION_RELEASE 13 /* Define to 64bit integer type */ #define COIN_INT64_T int64_t diff --git a/thirdparty/linux/include/coin/Idiot.hpp b/thirdparty/linux/include/coin/Idiot.hpp index a3d7891..b675c4f 100644 --- a/thirdparty/linux/include/coin/Idiot.hpp +++ b/thirdparty/linux/include/coin/Idiot.hpp @@ -1,4 +1,4 @@ -/* $Id: Idiot.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +/* $Id: Idiot.hpp 2143 2015-05-20 15:49:17Z forrest $ */ // Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). @@ -290,7 +290,8 @@ private: 32768 - experimental 1 65536 - experimental 2 131072 - experimental 3 - 262144 - just values pass etc */ + 262144 - just values pass etc + 524288 - don't treat structural slacks as slacks */ int lightWeight_; // 0 - normal, 1 lightweight }; diff --git a/thirdparty/linux/include/coin/IpoptConfig.h b/thirdparty/linux/include/coin/IpoptConfig.h index 78dadd3..68d1494 100644 --- a/thirdparty/linux/include/coin/IpoptConfig.h +++ b/thirdparty/linux/include/coin/IpoptConfig.h @@ -5,7 +5,7 @@ #define __CONFIG_IPOPT_H__ /* Version number of project */ -#define IPOPT_VERSION "3.12.7" +#define IPOPT_VERSION "3.12" /* Major Version number of project */ #define IPOPT_VERSION_MAJOR 3 @@ -14,7 +14,7 @@ #define IPOPT_VERSION_MINOR 12 /* Release Version number of project */ -#define IPOPT_VERSION_RELEASE 7 +#define IPOPT_VERSION_RELEASE 9999 /* Define to the C type corresponding to Fortran INTEGER */ #define FORTRAN_INTEGER_TYPE int diff --git a/thirdparty/linux/include/coin/OsiCbcSolverInterface.hpp b/thirdparty/linux/include/coin/OsiCbcSolverInterface.hpp new file mode 100644 index 0000000..3250a00 --- /dev/null +++ b/thirdparty/linux/include/coin/OsiCbcSolverInterface.hpp @@ -0,0 +1,764 @@ +// $Id: OsiCbcSolverInterface.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCbcSolverInterface_H +#define OsiCbcSolverInterface_H + +#include <string> +#include <cfloat> +#include <map> +#include "CbcModel.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiSolverInterface.hpp" +#include "CbcStrategy.hpp" +#include "CoinWarmStartBasis.hpp" + +class OsiRowCut; +class OsiClpSolverInterface; +static const double OsiCbcInfinity = COIN_DBL_MAX; + +//############################################################################# + +/** Cbc Solver Interface + +Instantiation of OsiCbcSolverInterface for the Model Algorithm. + +*/ + +class OsiCbcSolverInterface : + virtual public OsiSolverInterface { + friend void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the cbc algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + // Set a hint parameter - overrides OsiSolverInterface + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * otherInformation=NULL); + /// Get a hint parameter + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength, + void *& otherInformation) const; + + using OsiSolverInterface::getHintParam ; + /// Get a hint parameter + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength) const; + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + //@} + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods */ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const; + + /// Get warmstarting information + virtual CoinWarmStart* getWarmStart() const; + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + //@} + + //--------------------------------------------------------------------------- + /**@name Hotstart related methods (primarily used in strong branching). <br> + The user can create a hotstart (a snapshot) of the optimization process + then reoptimize over and over again always starting from there.<br> + <strong>NOTE</strong>: between hotstarted optimizations only + bound changes are allowed. */ + //@{ + /// Create a hotstart point of the optimization process + virtual void markHotStart(); + /// Optimize starting from the hotstart + virtual void solveFromHotStart(); + /// Delete the snapshot + virtual void unmarkHotStart(); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /**@name Methods related to querying the input data */ + //@{ + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + /// Get number of nonzero elements + virtual int getNumElements() const ; + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L' <= constraint + <li>'E' = constraint + <li>'G' >= constraint + <li>'R' ranged constraint + <li>'N' free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const ; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is undefined + </ul> + */ + virtual const double * getRowRange() const ; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const ; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const ; + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const; + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const ; + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. */ + virtual int getIterationCount() const ; + + /** Get as many dual rays as the solver can provide. (In case of proven + primal infeasibility there should be at least one.) + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const; + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const; + + //@} + + /*! \name Methods for row and column names. + + Because OsiCbc is a pass-through class, it's necessary to override any + virtual method in order to be sure we catch an override by the underlying + solver. See the OsiSolverInterface class documentation for detailed + descriptions. + */ + //@{ + + /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn */ + + virtual std::string dfltRowColName(char rc, + int ndx, unsigned digits = 7) const ; + + /*! \brief Return the name of the objective function */ + + virtual std::string getObjName (unsigned maxLen = std::string::npos) const ; + + /*! \brief Set the name of the objective function */ + + virtual void setObjName (std::string name) ; + + /*! \brief Return the name of the row. */ + + virtual std::string getRowName(int rowIndex, + unsigned maxLen = std::string::npos) const ; + + /*! \brief Return a pointer to a vector of row names */ + + virtual const OsiNameVec &getRowNames() ; + + /*! \brief Set a row name */ + + virtual void setRowName(int ndx, std::string name) ; + + /*! \brief Set multiple row names */ + + virtual void setRowNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len row names starting at index tgtStart */ + + virtual void deleteRowNames(int tgtStart, int len) ; + + /*! \brief Return the name of the column */ + + virtual std::string getColName(int colIndex, + unsigned maxLen = std::string::npos) const ; + + /*! \brief Return a pointer to a vector of column names */ + + virtual const OsiNameVec &getColNames() ; + + /*! \brief Set a column name */ + + virtual void setColName(int ndx, std::string name) ; + + /*! \brief Set multiple column names */ + + virtual void setColNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len column names starting at index tgtStart */ + virtual void deleteColNames(int tgtStart, int len) ; + + //@} + + //@} + + //--------------------------------------------------------------------------- + + /**@name Problem modifying methods */ + //@{ + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColLower ; + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColUpper ; + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + virtual void setColBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the type of a single row<br> */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /** Set the bounds on a number of rows simultaneously<br> + The default implementation just invokes setRowLower() and + setRowUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set the type of a number of rows simultaneously<br> + The default implementation just invokes setRowType() + over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>any</em> characteristics changes + @param senseList the new senses + @param rhsList the new right hand sides + @param rangeList the new ranges + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + //@} + + //------------------------------------------------------------------------- + /**@name Integrality related changing methods */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + //@} + + //------------------------------------------------------------------------- + /// Set objective function sense (1 for min (default), -1 for max,) + virtual void setObjSense(double s ); + + /** Set the primal solution column values + + colsol[numcols()] is an array of values of the problem column + variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of colsol() until changed by another call to + setColsol() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setColSolution(const double * colsol); + + /** Set dual solution vector + + rowprice[numrows()] is an array of values of the problem row + dual variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of rowprice() until changed by another call to + setRowprice() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setRowPrice(const double * rowprice); + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem.<br> + Note that if a column is added then by default it will correspond to a + continuous variable. */ + //@{ + using OsiSolverInterface::addCol ; + /** */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, const int * rows, const double * elements, + const double collb, const double colub, + const double obj) ; + + using OsiSolverInterface::addCols ; + /** */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void deleteCols(const int num, const int * colIndices); + + using OsiSolverInterface::addRow ; + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + + using OsiSolverInterface::addRows ; + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + /** */ + virtual void deleteRows(const int num, const int * rowIndices); + + //----------------------------------------------------------------------- + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + This uses array of pointers + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + //@} + //@} + + //--------------------------------------------------------------------------- + +public: + + /**@name Methods to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + using OsiSolverInterface::readMps ; + /** Read an mps file from the given filename (defaults to Osi reader) - returns + number of errors (see OsiMpsReader class) */ + virtual int readMps(const char *filename, + const char *extension = "mps") ; + + /** Write the problem into an mps file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + /** Write the problem into an mps file of the given filename, + names may be null. formatType is + 0 - normal + 1 - extra accuracy + 2 - IEEE hex (later) + + Returns non-zero on I/O error + */ + virtual int writeMpsNative(const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0) const ; + //@} + + /**@name Message handling (extra for Cbc messages). + Normally I presume you would want the same language. + If not then you could use underlying model pointer */ + //@{ + /// Set language + void newLanguage(CoinMessages::Language language); + void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + //@} + //--------------------------------------------------------------------------- + + /**@name Cbc specific public interfaces */ + //@{ + /// Get pointer to Cbc model + inline CbcModel * getModelPtr() const + { return modelPtr_;} + /// Get pointer to underlying solver + inline OsiSolverInterface * getRealSolverPtr() const + { return modelPtr_->solver();} + /// Set cutoff bound on the objective function. + inline void setCutoff(double value) + { modelPtr_->setCutoff(value);} + /// Get the cutoff bound on the objective function - always as minimize + inline double getCutoff() const + { return modelPtr_->getCutoff();} + /// Set the CbcModel::CbcMaxNumNode maximum node limit + inline void setMaximumNodes( int value) + { modelPtr_->setMaximumNodes(value);} + /// Get the CbcModel::CbcMaxNumNode maximum node limit + inline int getMaximumNodes() const + { return modelPtr_->getMaximumNodes();} + /// Set the CbcModel::CbcMaxNumSol maximum number of solutions + inline void setMaximumSolutions( int value) + { modelPtr_->setMaximumSolutions(value);} + /// Get the CbcModel::CbcMaxNumSol maximum number of solutions + inline int getMaximumSolutions() const + { return modelPtr_->getMaximumSolutions();} + /// Set the CbcModel::CbcMaximumSeconds maximum number of seconds + inline void setMaximumSeconds( double value) + { modelPtr_->setMaximumSeconds(value);} + /// Get the CbcModel::CbcMaximumSeconds maximum number of seconds + inline double getMaximumSeconds() const + { return modelPtr_->getMaximumSeconds();} + /// Node limit reached? + inline bool isNodeLimitReached() const + { return modelPtr_->isNodeLimitReached();} + /// Solution limit reached? + inline bool isSolutionLimitReached() const + { return modelPtr_->isSolutionLimitReached();} + /// Get how many Nodes it took to solve the problem. + inline int getNodeCount() const + { return modelPtr_->getNodeCount();} + /// Final status of problem - 0 finished, 1 stopped, 2 difficulties + inline int status() const + { return modelPtr_->status();} + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + //@} + + //--------------------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiCbcSolverInterface (OsiSolverInterface * solver=NULL, + CbcStrategy * strategy=NULL); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiCbcSolverInterface (const OsiCbcSolverInterface &); +#if 0 + /// Borrow constructor - only delete one copy + OsiCbcSolverInterface (CbcModel * rhs, bool reallyOwn=false); + + /// Releases so won't error + void releaseCbc(); +#endif + /// Assignment operator + OsiCbcSolverInterface & operator=(const OsiCbcSolverInterface& rhs); + + /// Destructor + virtual ~OsiCbcSolverInterface (); + + //@} + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to constraint matrix). */ + virtual void applyRowCut(const OsiRowCut& rc); + + /** Apply a column cut (adjust one or more bounds). */ + virtual void applyColCut(const OsiColCut& cc); + //@} + /**@name Protected member data */ + //@{ + /// Cbc model represented by this class instance + mutable CbcModel * modelPtr_; + //@} +}; +// So unit test can find out if NDEBUG set +bool OsiCbcHasNDEBUG(); + +//############################################################################# +/** A function that tests the methods in the OsiCbcSolverInterface class. */ +void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +#endif diff --git a/thirdparty/linux/include/coin/OsiConfig.h b/thirdparty/linux/include/coin/OsiConfig.h index 2e42bb9..ee9424f 100644 --- a/thirdparty/linux/include/coin/OsiConfig.h +++ b/thirdparty/linux/include/coin/OsiConfig.h @@ -5,7 +5,7 @@ #define __CONFIG_OSI_H__ /* Version number of project */ -#define OSI_VERSION "0.107.4" +#define OSI_VERSION "0.107.8" /* Major Version number of project */ #define OSI_VERSION_MAJOR 0 @@ -14,6 +14,6 @@ #define OSI_VERSION_MINOR 107 /* Release Version number of project */ -#define OSI_VERSION_RELEASE 4 +#define OSI_VERSION_RELEASE 8 #endif diff --git a/thirdparty/linux/include/coin/OsiCuts.hpp b/thirdparty/linux/include/coin/OsiCuts.hpp index d454402..5eea264 100644 --- a/thirdparty/linux/include/coin/OsiCuts.hpp +++ b/thirdparty/linux/include/coin/OsiCuts.hpp @@ -74,7 +74,7 @@ public: class const_iterator { friend class OsiCuts; public: - typedef std::bidirectional_iterator_tag iterator_category; + typedef std::forward_iterator_tag iterator_category; typedef OsiCut* value_type; typedef size_t difference_type; typedef OsiCut ** pointer; diff --git a/thirdparty/linux/include/coin/SuiteSparse_config.h b/thirdparty/linux/include/coin/SuiteSparse_config.h new file mode 100644 index 0000000..5d705ea --- /dev/null +++ b/thirdparty/linux/include/coin/SuiteSparse_config.h @@ -0,0 +1,179 @@ +/* ========================================================================== */ +/* === SuiteSparse_config =================================================== */ +/* ========================================================================== */ + +/* Configuration file for SuiteSparse: a Suite of Sparse matrix packages + * (AMD, COLAMD, CCOLAMD, CAMD, CHOLMOD, UMFPACK, CXSparse, and others). + * + * SuiteSparse_config.h provides the definition of the long integer. On most + * systems, a C program can be compiled in LP64 mode, in which long's and + * pointers are both 64-bits, and int's are 32-bits. Windows 64, however, uses + * the LLP64 model, in which int's and long's are 32-bits, and long long's and + * pointers are 64-bits. + * + * SuiteSparse packages that include long integer versions are + * intended for the LP64 mode. However, as a workaround for Windows 64 + * (and perhaps other systems), the long integer can be redefined. + * + * If _WIN64 is defined, then the __int64 type is used instead of long. + * + * The long integer can also be defined at compile time. For example, this + * could be added to SuiteSparse_config.mk: + * + * CFLAGS = -O -D'SuiteSparse_long=long long' \ + * -D'SuiteSparse_long_max=9223372036854775801' -D'SuiteSparse_long_idd="lld"' + * + * This file defines SuiteSparse_long as either long (on all but _WIN64) or + * __int64 on Windows 64. The intent is that a SuiteSparse_long is always a + * 64-bit integer in a 64-bit code. ptrdiff_t might be a better choice than + * long; it is always the same size as a pointer. + * + * This file also defines the SUITESPARSE_VERSION and related definitions. + * + * Copyright (c) 2012, Timothy A. Davis. No licensing restrictions apply + * to this file or to the SuiteSparse_config directory. + * Author: Timothy A. Davis. + */ + +#ifndef _SUITESPARSECONFIG_H +#define _SUITESPARSECONFIG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <limits.h> +#include <stdlib.h> + +/* ========================================================================== */ +/* === SuiteSparse_long ===================================================== */ +/* ========================================================================== */ + +#ifndef SuiteSparse_long + +#if _WIN64 && !(defined PYTHON) && (defined _MSC_VER) + +#define SuiteSparse_long __int64 +#define SuiteSparse_long_max _I64_MAX +#define SuiteSparse_long_idd "I64d" + +#else + +#define SuiteSparse_long long +#define SuiteSparse_long_max LONG_MAX +#define SuiteSparse_long_idd "ld" + +#endif +#define SuiteSparse_long_id "%" SuiteSparse_long_idd +#endif + +/* For backward compatibility with prior versions of SuiteSparse. The UF_* + * macros are deprecated and will be removed in a future version. */ +#ifndef UF_long +#define UF_long SuiteSparse_long +#define UF_long_max SuiteSparse_long_max +#define UF_long_idd SuiteSparse_long_idd +#define UF_long_id SuiteSparse_long_id +#endif + +/* ========================================================================== */ +/* === SuiteSparse_config parameters and functions ========================== */ +/* ========================================================================== */ + +/* SuiteSparse-wide parameters will be placed in this struct. */ + +typedef struct SuiteSparse_config_struct +{ + void *(*malloc_memory) (size_t) ; /* pointer to malloc */ + void *(*realloc_memory) (void *, size_t) ; /* pointer to realloc */ + void (*free_memory) (void *) ; /* pointer to free */ + void *(*calloc_memory) (size_t, size_t) ; /* pointer to calloc */ + +} SuiteSparse_config ; + +void *SuiteSparse_malloc /* pointer to allocated block of memory */ +( + size_t nitems, /* number of items to malloc (>=1 is enforced) */ + size_t size_of_item, /* sizeof each item */ + int *ok, /* TRUE if successful, FALSE otherwise */ + SuiteSparse_config *config /* SuiteSparse-wide configuration */ +) ; + +void *SuiteSparse_free /* always returns NULL */ +( + void *p, /* block to free */ + SuiteSparse_config *config /* SuiteSparse-wide configuration */ +) ; + +void SuiteSparse_tic /* start the timer */ +( + double tic [2] /* output, contents undefined on input */ +) ; + +double SuiteSparse_toc /* return time in seconds since last tic */ +( + double tic [2] /* input: from last call to SuiteSparse_tic */ +) ; + +double SuiteSparse_time /* returns current wall clock time in seconds */ +( + void +) ; + +/* determine which timer to use, if any */ +#ifndef NTIMER +#ifdef _POSIX_C_SOURCE +#if _POSIX_C_SOURCE >= 199309L +#define SUITESPARSE_TIMER_ENABLED +#endif +#endif +#endif + +/* ========================================================================== */ +/* === SuiteSparse version ================================================== */ +/* ========================================================================== */ + +/* SuiteSparse is not a package itself, but a collection of packages, some of + * which must be used together (UMFPACK requires AMD, CHOLMOD requires AMD, + * COLAMD, CAMD, and CCOLAMD, etc). A version number is provided here for the + * collection itself. The versions of packages within each version of + * SuiteSparse are meant to work together. Combining one packge from one + * version of SuiteSparse, with another package from another version of + * SuiteSparse, may or may not work. + * + * SuiteSparse contains the following packages: + * + * SuiteSparse_config version 4.0.2 (version always the same as SuiteSparse) + * AMD version 2.3.1 + * BTF version 1.2.0 + * CAMD version 2.3.1 + * CCOLAMD version 2.8.0 + * CHOLMOD version 2.0.1 + * COLAMD version 2.8.0 + * CSparse version 3.1.1 + * CXSparse version 3.1.1 + * KLU version 1.2.1 + * LDL version 2.1.0 + * RBio version 2.1.1 + * SPQR version 1.3.1 (full name is SuiteSparseQR) + * UMFPACK version 5.6.1 + * MATLAB_Tools various packages & M-files + * + * Other package dependencies: + * BLAS required by CHOLMOD and UMFPACK + * LAPACK required by CHOLMOD + * METIS 4.0.1 required by CHOLMOD (optional) and KLU (optional) + */ + +#define SUITESPARSE_DATE "July 17, 2012" +#define SUITESPARSE_VER_CODE(main,sub) ((main) * 1000 + (sub)) +#define SUITESPARSE_MAIN_VERSION 4 +#define SUITESPARSE_SUB_VERSION 0 +#define SUITESPARSE_SUBSUB_VERSION 2 +#define SUITESPARSE_VERSION \ + SUITESPARSE_VER_CODE(SUITESPARSE_MAIN_VERSION,SUITESPARSE_SUB_VERSION) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin/SymConfig.h b/thirdparty/linux/include/coin/SymConfig.h index d3c548e..08cb201 100644 --- a/thirdparty/linux/include/coin/SymConfig.h +++ b/thirdparty/linux/include/coin/SymConfig.h @@ -5,7 +5,7 @@ #define __CONFIG_SYM_H__ /* Version number of project */ -#define SYMPHONY_VERSION "5.6.10" +#define SYMPHONY_VERSION "5.6.16" /* Major Version number of project */ #define SYMPHONY_VERSION_MAJOR 5 @@ -14,6 +14,6 @@ #define SYMPHONY_VERSION_MINOR 6 /* Release Version number of project */ -#define SYMPHONY_VERSION_RELEASE 10 +#define SYMPHONY_VERSION_RELEASE 16 #endif diff --git a/thirdparty/linux/include/coin/ThirdParty/arith.h b/thirdparty/linux/include/coin/ThirdParty/arith.h new file mode 100644 index 0000000..356d34f --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/arith.h @@ -0,0 +1,8 @@ +#define IEEE_8087 +#define Arith_Kind_ASL 1 +#define Long int +#define Intcast (int)(long) +#define Double_Align +#define X64_bit_pointers +#define QNaN0 0x0 +#define QNaN1 0xfff80000 diff --git a/thirdparty/linux/include/coin/ThirdParty/asl.h b/thirdparty/linux/include/coin/ThirdParty/asl.h new file mode 100644 index 0000000..ec8a379 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/asl.h @@ -0,0 +1,1199 @@ +/**************************************************************** +Copyright (C) 1997-2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#ifndef ASL_included +#define ASL_included + +#include "arith.h" /* for Long and Double_Align */ +#include "math.h" +#include "stdio1.h" +#include "string.h" + +#ifdef KR_headers +#define Const /* */ +#define VOID /*void*/ +extern char *malloc(), *realloc(); +extern double strtod(); +#else +#define Const const +#define VOID void +#include "stdlib.h" +#endif +#include "errno.h" + +#ifdef __cplusplus +#define Cextern extern "C" +extern "C" { +#else +#define Cextern extern +#endif + +#ifndef Stderr +extern FILE *Stderr; +#endif + +#ifndef real +#define real double +#endif + +#ifndef Long +#define Long long +#endif +#ifndef F2C_INCLUDE +typedef Long fint; +typedef Long ftnlen; +#endif +#ifndef Intcast +#define Intcast (size_t) +#endif + +#ifndef Not_Used +#define Not_Used(x) x = x /* silence non-use warnings */ +#endif + +#define Malloc(x) mymalloc((size_t)(x)) +#define Realloc(x,y) myralloc(x,(size_t)(y)) +#define Sizeof(x) sizeof(x) +/* prior to 20110912, Sizeof(x) was (fint)sizeof(x) */ + + /* Place qsortv declaration ahead of funcadd.h in case Permit_AE_redefs is #defined. */ + extern void qsortv(void*, size_t, size_t, int(*)(const void*,const void*,void*), void*); + +#ifndef FUNCADD_H_INCLUDED +#ifndef Permit_AE_redefs +#define No_AE_redefs +#endif +#include "funcadd.h" +#endif +#include "setjmp.h" + + typedef size_t (*Fwrite)(const void*, size_t, size_t, FILE*); + typedef int (*Add_Indicator)(void*, int, int, int, int, int*, real*, real); + typedef struct {jmp_buf jb;} Jmp_buf; + typedef struct ASL ASL; + typedef struct MPEC_Adjust MPEC_Adjust; + typedef struct Objrep Objrep; + typedef struct Option_Info Option_Info; + typedef struct cgrad cgrad; + typedef struct cplist cplist; + typedef struct derp derp; + typedef struct expr_n expr_n; + typedef struct func_info func_info; + typedef struct linpart linpart; + typedef struct ograd ograd; + typedef struct plterm plterm; + typedef struct relo relo; + + typedef struct +SputInfo { + fint *hcolstarts; + fint *hrownos; + size_t *hcs[2]; + fint *hrn[2]; + ssize_t *ulinc; + ssize_t *ulcopy; + ssize_t *ulinc0; + ssize_t *ulcopy0; + ssize_t *ulcend; + ssize_t nod; + int nobj; /* from sphsetup() */ + int ow; /* from sphsetup() */ + int y; /* from sphsetup() */ + int khinfo; /* mblk size in sphes_setup */ + int khinfob; + int uptri; /* from sphsetup() */ + int *uptolow; + size_t *hcolstartsZ; + } SputInfo; + + typedef union +uirp { + int i; + real *rp; + void *vp; + } uirp; + +#ifdef ASL_big_goff /*{{ for jacval() with nzc >= 2^31 */ + struct +cgrad { + real coef; + cgrad *next; + ssize_t varno; + size_t goff; + }; + + struct +ograd { + real coef; + ograd *next; + ssize_t varno; + }; +typedef ssize_t varno_t; +#else /*}{ less memory */ + struct +cgrad { + real coef; + cgrad *next; + int varno; + int goff; + }; + + struct +ograd { + real coef; + ograd *next; + int varno; + }; +typedef int varno_t; +#endif /*}}*/ + + struct +cplist { + cplist *next; + uirp ca; + real *cfa; + }; + + struct +derp { + derp *next; + uirp a, b, c; + }; + +typedef real efunc_n(expr_n*); + + struct +expr_n { + efunc_n *op; + real v; + }; + + struct +func_info { + func_info *next, *fnext; + Const char *name; + ufunc *funcp; + int ftype; + int nargs; + void *funcinfo; + int findex; /* for fg_write */ + }; + + struct +linpart { + uirp v; + real fac; + }; + + struct +plterm { + int n; /* number of slopes */ + int z; /* bs[z] == slope at 0 */ + real bs[1]; /* slope 1, bkpt 1, slope 2, bkpt 2, ..., slope n */ + }; + + struct +relo { + relo *next, *next2; + derp *D, *Dnext, *Dcond; + }; + + typedef struct +EdRead_ASL { + ASL *asl; + FILE *nl; + void *S; /* Static */ + Long Line; + int lineinc; + int can_end; + char rl_buf[80]; + void (*iadjfcn)(void*, size_t); + void (*dadjfcn)(void*, size_t); + } EdRead_ASL; +#define EdRead EdRead_ASL + + typedef struct ASLhead ASLhead; struct +ASLhead { ASLhead *next, *prev; }; + +#define NFHASH 23 + + typedef struct +Edagpars { + ASLhead h; + /* stuff initialized to nonzero values */ + real hffactor; + int FUNNEL_MIN_; + int maxfwd_; + int need_funcadd_; + int vrefGulp_; + int want_derivs_; + int ihd_limit_; + int solve_code_; + real (*Objval) (ASL*, int nobj, real *X, fint *nerror); + real (*Objval_nomap) (ASL*, int nobj, real *X, fint *nerror); + void (*Objgrd) (ASL*, int nobj, real *X, real *G, fint *nerror); + void (*Objgrd_nomap) (ASL*, int nobj, real *X, real *G, fint *nerror); + void (*Conval) (ASL*, real *X, real *R, fint *nerror); + void (*Jacval) (ASL*, real *X, real *J, fint *nerror); + real (*Conival) (ASL*, int ncon, real *X, fint *nerror); + real (*Conival_nomap) (ASL*, int ncon, real *X, fint *nerror); + void (*Congrd) (ASL*, int nc, real *X, real *G, fint *nerror); + void (*Congrd_nomap) (ASL*, int nc, real *X, real *G, fint *nerror); + void (*Hvcomp) (ASL*, real *hv, real *p, int no, real *ow, real *y); + void (*Hvcomp_nomap) (ASL*, real *hv, real *p, int no, real *ow, real *y); + void (*Hvcompd) (ASL*, real *hv, real *p, int co); + varno_t (*Hvcomps) (ASL*, real *hv, real *p, int co, varno_t nz, varno_t *z); + void (*Hvinit) (ASL*, int hid_limit, int nobj, real *ow, real *y); + void (*Hvinit_nomap) (ASL*, int hid_limit, int nobj, real *ow, real *y); + void (*Hesset) (ASL*, int flags, int no, int nno, int nc, int nnc); + int (*Lconval) (ASL*, int ncon, real *X, fint *nerror); + void (*Xknown) (ASL*, real*, fint*); + void (*Duthes) (ASL*, real *H, int nobj, real *ow, real *y); + void (*Duthes_nomap) (ASL*, real *H, int nobj, real *ow, real *y); + void (*Fulhes) (ASL*, real *H, fint LH, int no, real *ow, real *y); + void (*Fulhes_nomap) (ASL*, real *H, fint LH, int no, real *ow, real *y); + void (*Sphes) (ASL*, SputInfo**, real *H, int nobj, real *ow, real *y); + void (*Sphes_nomap) (ASL*, SputInfo**, real *H, int nobj, real *ow, real *y); + fint (*Sphset) (ASL*, SputInfo**, int nobj, int ow, int y, int uptri); + fint (*Sphset_nomap) (ASL*, SputInfo**, int nobj, int ow, int y, int uptri); + } Edagpars; + + extern Edagpars edagpars_ASL; + +#define objval(np,x,ne) (*((ASL*)asl)->p.Objval)((ASL*)asl,np,x,ne) +#define objgrd(np,x,g,ne) (*((ASL*)asl)->p.Objgrd)((ASL*)asl,np,x,g,ne) +#define conval(x,r,ne) (*((ASL*)asl)->p.Conval)((ASL*)asl,x,r,ne) +#define jacval(x,j,ne) (*((ASL*)asl)->p.Jacval)((ASL*)asl,x,j,ne) +#define conival(i,x,ne) (*((ASL*)asl)->p.Conival)((ASL*)asl,i,x,ne) +#define congrd(i,x,g,ne) (*((ASL*)asl)->p.Congrd)((ASL*)asl,i,x,g,ne) +#define hvcomp(hv,P,no,ow,y) (*((ASL*)asl)->p.Hvcomp)((ASL*)asl,hv,P,no,ow,y) +#define hvcompd(hv,P,co) (*((ASL*)asl)->p.Hvcompd)((ASL*)asl,hv,P,co) +#define hvcomps(hv,P,co,nz,z) (*((ASL*)asl)->p.Hvcomps)((ASL*)asl,hv,P,co,nz,z) +#define hvinit(no,ow,y) (*((ASL*)asl)->p.Hvinit)((ASL*)asl,ihd_limit,no,ow,y) +#define hesset(f,o,n,c,nc) (*((ASL*)asl)->p.Hesset)((ASL*)asl,f,o,n,c,nc) +#define duthes(h,n,ow,y) (*((ASL*)asl)->p.Duthes)((ASL*)asl,h,n,ow,y) +#define fullhes(h,lh,n,ow,y) (*((ASL*)asl)->p.Fulhes)((ASL*)asl,h,lh,n,ow,y) +#define lconval(i,x,ne) (*((ASL*)asl)->p.Lconval)((ASL*)asl,i,x,ne) +#define sphes(h,no,ow,y) (*((ASL*)asl)->p.Sphes)( (ASL*)asl,0,h,no,ow,y) +#define sphsetup(no,ow,y,b) (*((ASL*)asl)->p.Sphset)((ASL*)asl,0,no,ow,y,b) +#define xknown(x) (*((ASL*)asl)->p.Xknown)((ASL*)asl,x,0) +#define xknowne(x,ne) (*((ASL*)asl)->p.Xknown)((ASL*)asl,x,ne) +#define xunknown() (asl->i.x_known = 0) + +#define FUNNEL_MIN asl->p.FUNNEL_MIN_ +#define ihd_limit asl->p.ihd_limit_ +#define maxfwd asl->p.maxfwd_ +#define need_funcadd asl->p.need_funcadd_ +#define solve_code asl->p.solve_code_ +#define solve_result_num asl->p.solve_code_ +#define vrefGulp asl->p.vrefGulp_ +#define want_derivs asl->p.want_derivs_ + + typedef struct +SufDesc { /* suffix description */ + char *sufname; /* suffix name */ + char *table; /* for return to AMPL, suffix_table value */ + int kind; + int nextra; /* extra entries to allocate in u.i or u.r */ + struct { /* was union, but this made debugging harder */ + int *i; + real *r; + } u; + struct SufDesc *next; + /* The number of entries in u.i or u.r is */ + /* (&asl->i.n_var_)[kind & ASL_Sufkind_mask] . */ + } SufDesc; + + enum { /* kind bits for SufDesc */ + ASL_Sufkind_var = 0, + ASL_Sufkind_con = 1, + ASL_Sufkind_obj = 2, + ASL_Sufkind_prob = 3, + ASL_Sufkind_mask = 3, /* mask for getting one of the above */ + /* values from SufDesc.kind */ + ASL_Sufkind_real = 4, /* use SufDesc.u.r rather than .i */ + ASL_Sufkind_iodcl = 8, /* tell AMPL to make this an INOUT suffix */ + ASL_Sufkind_output = 16,/* return this suffix to AMPL */ + ASL_Sufkind_input = 32, /* input values were received from AMPL */ + ASL_Sufkind_outonly = 64/* reject as an input value */ + }; + + typedef struct +SufDecl { /* Pass array of SufDecl's to suf_declare(). */ + char *name; + char *table; + int kind; + int nextra; + } SufDecl; + + typedef struct Exitcall Exitcall; struct +Exitcall { + Exitcall *prev; + Exitfunc *ef; + void *v; + }; + + typedef struct DerivErrInfo DerivErrInfo; + + typedef struct +Edaginfo { + int ASLtype; + /* stuff initialized to zero values */ + int amplflag_; + int need_nl_; + int nlmode; + func_info **funcs_, *funcsfirst_, *funcslast_; + int (*xscanf_)(EdRead*, const char*, ...); + + func_info *fhash_[NFHASH]; + + real *adjoints_; /* partials of result w.r.t. current oper. */ + real *adjoints_nv1_; /* internal use: start of portion to zero */ + real *LUrhs_, /* constraint lower (and, if Urhsx == 0, */ + /* upper) bounds */ + *Urhsx_, /* constraint upper bounds (if nonzero) */ + *X0_, /* initial guess (if nonzero) */ + *LUv_, /* variable lower (and, if Uvx == 0, upper) */ + /* bounds */ + *Uvx_, /* variable upper bounds (if nonzero) */ + *Lastx_, /* internal use: copy of X */ + *pi0_; /* dual initial guess */ + + char *objtype_; /* object type array: 0 == min, 1 == max */ + char *havex0_; /* if nonzero, havex0_[i] != 0 ==> */ + /* X0_[i] was specified: this lets you */ + /* tell explicit 0's from default 0's */ + char *havepi0_; /* analogous to havex0_, but for dual values */ + real *A_vals_; /* If nonzero, store constant Jacobian values */ + /* (possibly 0 when nonlinearities are involved) */ + /* in A_vals, A_rownos, and A_colstarts, */ + /* rather than in Cgrad_. */ + int *A_rownos_, /* row numbers corresponding to A_vals_ */ + *A_colstarts_; /* offsets of columns in A_vals_ */ + size_t *A_colstartsZ_; /* for huge problems -- 2^31 or more nonzeros */ + + cgrad **Cgrad_; /* constraint gradient info. (linear part) */ + ograd **Ograd_; /* objective gradient info. (linear part) */ + cgrad **Cgrad0; /* unmapped */ + + int Fortran_; /* adjustment to A_rownos, A_colstarts, */ + /* ccind1, and ccind2 */ + int amax_; /* number of adjoint cells */ + + /* stuff for common expressions (from "defined" vars) */ + int c_vars_; + int comb_; + int combc_; + int comc1_; + int comc_; + int como1_; + int como_; + + int lnc_; /* no. of linear network constraints */ + int nbv_; /* no. of linear binary variables */ + int niv_; /* no. of linear non-binary integer variables */ + int nlc_; /* total no. of nonlinear constraints */ + int n_eqn_; /* number of equality constraints or -1 */ + /* if unknown (ampl prior to 19970627) */ + int n_cc_; /* total complementarity conditions */ + int nlcc_; /* nonlinear complementarity conditions */ + int ndcc_; /* number of complementarities involving */ + /* double inequalities (for ASL_cc_simplify) */ + int nzlb_; /* number of complemented variables with a */ + /* nonzero lower bound (for ASL_cc_simplify) */ + int nlnc_; /* no. of nonlinear network constraints */ + int nlo_; /* no. of nonlinear objectives */ + int nlvb_; /* no. of nonlinear variables in both */ + /* constraints and objectives */ + int nlvc_; /* no. of nonlinear variables in constraints */ + int nlvo_; /* no. of nonlinear variables in objectives */ + /* nlvc_ and nlvo_ include nlvb_ */ + int nlvbi_; /* integer nonlinear variables in both */ + /* constraints and objectives */ + int nlvci_; /* integer nonlinear vars just in constraints */ + int nlvoi_; /* integer nonlinear vars just in objectives */ + int nwv_; /* no. of (linear) network variables (arcs) */ + int nzc_; /* no. of nonzeros in constraints' Jacobian */ + int nzo_; /* no. of nonzeros in all objective gradients */ + int n_var_; /* total no. of variables */ + int n_con_; /* total no. of constraints */ + int n_obj_; /* total no. of objectives */ + int n_prob; /* 1 (for use with SufDesc): SufDesc.u has */ + /* (&asl->i.n_var_)[SufDesc.kind & ASL_Sufkind_mask] entries */ + int n_lcon_; /* no. of logical constraints */ + int flags; /* 1 = want output suffixes */ + int n_conjac_[2]; /* Conval and Jacval operate on constraint i */ + /* for n_conjac_[0] <= i < n_conjac_[1]. */ + /* Initialized by jac0dim to 0 and n_con. */ + /* The .nl reader may adjust these values when */ + /* processing ASL_cc_simplify or ASL_obj_replace. */ + + + /* internal stuff */ + + int nclcon_; /* n_con + n_lcon */ + int ncom0_; + int ncom1_; + int nderps_; + int nfunc_; + int o_vars_; + int want_deriv_; + int x0kind_; + int rflags; /* flags given to the .nl reader */ + size_t nzjac_; + size_t x0len_; + size_t nZc_; /* no. of nonzeros in constraints' Jacobian */ + size_t nZo_; /* no. of nonzeros in all objective gradients */ + + char *filename_; /* stub + current extension */ + char *stub_end_; /* copy new extension (starting with ".") */ + /* here to adjust filename */ + void *archan_; /* channel for reading from AMPL */ + void *awchan_; /* channel from writing to AMPL */ + int binary_nl_; /* 0 = ASCII format, 1 = binary */ + int return_nofile_; /* 0 ==> jacdim0 should exit if stub.nl */ + /* does not exist; 1 ==> return 0 */ + int plterms_; /* no. of piecewise-linear terms */ + int maxrownamelen_; /* length of longest constraint name */ + /* (if stub.row exists) */ + int maxcolnamelen_; /* length of longest constraint name */ + /* (if stub.col exists) */ + int co_index_; /* set this to (constraint number - 1) or */ + /* -(objective number) to identify the */ + /* constraint or objective being evaluated */ + /* (used in report_where()) */ + int cv_index_; /* used internally */ + Jmp_buf *err_jmp_; /* If nonzero when an error is detected, */ + /* longjmp here (without printing an error */ + /* message). */ + Jmp_buf *err_jmp1_; /* If nonzero when an error is detected */ + /* (and err_jmp_ == 0), longjmp here after */ + /* printing an error message. */ + fint ampl_options_[10]; + fint obj_no_; /* objective number (for write_sol and */ + /* read_sol) */ + int nranges_; /* no. of ranges (constraints with */ + /* negInfinity < lhs < rhs < Infinity) */ + int want_xpi0_; /* & 1 ==> allocate X0_ if an */ + /* initial guess is available */ + /* & 2 ==> allocate pi0_ if a dual */ + /* initial guess is available */ + + /* starting subscripts for cexp1's: request by */ + /* assigning these pointers before invoking edagread */ + + int *c_cexp1st_; /* cexp1 starts for constraints */ + int *o_cexp1st_; /* cexp1 starts for objectives */ + + /* for complementarity constraints */ + + int *cvar_; /* cvar[i] > 0 means constraint i complements */ + /* variable cvar[i] - 1 */ + + int *ccind1, *ccind2; /* populated when ASL_cc_simplify is */ + /* "on" in the flags argument to the .nl reader */ + + unsigned size_expr_n_; /* size for struct expr_n, for nlc */ + + /* extra info for write_sol */ + real ampl_vbtol_; + + /* relocated adjoints for common expressions */ + /* (used by nlc; request by allocating) */ + + int **zaC_; /* for common expressions */ + int **zac_; /* for constraints */ + int **zao_; /* for objectives */ + + /* for nlc */ + + int skip_int_derivs_; + + /* for suffixes */ + + int nsuffixes; + int nsufext[4]; + int nsuff[4]; + SufDesc *suffixes[4]; + + /* for sparse gradients */ + + int **zerograds_; + int congrd_mode; /* How to treat arg G to Congrd: */ + /* 0 == expand to n_var vector (default) */ + /* 1 == compact storage in G */ + /* 2 == use goff fields of struct cgrad */ + int x_known; /* used by xknown(), xunknown() */ + Long xknown_ignore; /* for debugging: ignore xknown */ + size_t zap_J; /* used by dense_j */ + int nxval; /* used by conival and objval */ + int nlvog; /* objgrd(np,x,g,ne) sets g[i] = 0 */ + /* if the objective does not depend on x[i] */ + /* and i < nlvog (or i < max(c_vars, o_vars) */ + /* if nlvog is left at 0); nlvog must be set */ + /* before the .nl reader is called. */ + int *ncxval; /* for conival */ + int *noxval; /* for objval */ + SputInfo *sputinfo_; /* used by sputhes() */ + + /* for ASL_free */ + void **Mbnext, **Mblast, *Mb; + /* for mem */ + char *memNext, *memLast; + + /* for user-defined functions */ + AmplExports *ae; + + /* for con_name(), obj_name(), var_name() */ + + char **connames; + char **lconnames; + char **objnames; + char **varnames; + int vcochecked; + + /* for possible user-specific use */ + void *uinfo; + + /* for reading alternate binary formats */ + void (*iadjfcn)(void*, size_t); + void (*dadjfcn)(void*, size_t); + const char *opfmt; /* format of opcodes */ + + /* for scaling */ + real *cscale; /* constraints */ + real *vscale; /* variables */ + real *lscale; /* Lagrange-multiplier scale */ + + /* for at_reset() */ + + Exitcall *arlast; + Exitcall *arnext; + Exitcall *arprev; + + /* for suf_sos() */ + + SufDesc *csd; + SufDesc *rsd; + int n_var0; /* number of variables before suf_sos() */ + int n_con0; /* number of constraints before suf_sos() */ + int n_var1; /* index of next variable to be added */ + int n_con1; /* index of next constraint to be added */ + int *vmap; /* for mapping variables, length n_var */ + int *cmap; /* for mapping constraints, length n_con */ + int *vzap; /* for zeroing primal variables in eliminated suf_sos */ + /* constraints: vzmap[i] for 1 <= i <= vzmap[0] */ + int *czap; /* for zeroing dual variables of eliminated suf_sos */ + /* constraints: czap[i] for 1 <= i <= czmap[0] */ + int *vminv; /* inverse of vmap; allocated on demand */ + + /* for modifying objectives */ + Objrep **Or; + real *orscratch; /* scratch (if needed) */ + + /* for simplifying complementarities */ + MPEC_Adjust *mpa; + + /* for derivative errors */ + DerivErrInfo *Derrs, *Derrs0; + + /* bounds and solution filenames */ + char *boundsfile; + char *solfile; + } Edaginfo; + + struct +ASL { + Edagpars p; + Edaginfo i; + }; + + typedef struct +NewVCO { + int nnv; /* number of new variables */ + int nnc; /* number of new constraints */ + int nno; /* number of new objectives */ + ograd **newc; /* new constraint nonzeros */ + ograd **newo; /* new objective nonzeros */ + real *LUnv; /* nnv variable lower bounds or, if Unv is null, */ + /* nnv (lower,upper) bound pairs */ + real *Unv; /* null or nnv variable upper bounds */ + real *LUnc; /* nnc constraint lower bounds or, if Unc is null, */ + /* nnc (lower,upper) bound pairs */ + real *Unc; /* null or nnc constraint upper bounds */ + real *oc; /* null or nno objective constants */ + char *ot; /* objective types (1 = max, 0 = min) */ + /* taken to be all zeros (min) if null */ + real *x0; /* null or nnv primal initial guesses */ + real *d0; /* null or nnc dual initial guesses */ + } NewVCO; + + struct +TMInfo { + union { + TMInfo *prev; + double align; + } u; + }; + +#define A_colstarts asl->i.A_colstarts_ +#define A_colstartsZ asl->i.A_colstartsZ_ +#define A_rownos asl->i.A_rownos_ +#define A_vals asl->i.A_vals_ +#define Cgrad asl->i.Cgrad_ +#define CgradZ asl->i.CgradZ_ +#define Fortran asl->i.Fortran_ +#define LUrhs asl->i.LUrhs_ +#define LUv asl->i.LUv_ +#define Lastx asl->i.Lastx_ +#define Ograd asl->i.Ograd_ +#define Urhsx asl->i.Urhsx_ +#define Uvx asl->i.Uvx_ +#define X0 asl->i.X0_ +#define adjoints asl->i.adjoints_ +#define adjoints_nv1 asl->i.adjoints_nv1_ +#define amax asl->i.amax_ +#define ampl_options asl->i.ampl_options_ +#define ampl_vbtol asl->i.ampl_vbtol_ +#define amplflag asl->i.amplflag_ +#define archan asl->i.archan_ +#define awchan asl->i.awchan_ +#define binary_nl asl->i.binary_nl_ +#define c_cexp1st asl->i.c_cexp1st_ +#define c_vars asl->i.c_vars_ +#define co_index asl->i.co_index_ +#define comb asl->i.comb_ +#define combc asl->i.combc_ +#define comc asl->i.comc_ +#define comc1 asl->i.comc1_ +#define como asl->i.como_ +#define como1 asl->i.como1_ +#define cv_index asl->i.cv_index_ +#define cvar asl->i.cvar_ +#define err_jmp asl->i.err_jmp_ +#define err_jmp1 asl->i.err_jmp1_ +#define fhash asl->i.fhash_ +#define filename asl->i.filename_ +#define funcs asl->i.funcs_ +#define funcsfirst asl->i.funcsfirst_ +#define funcslast asl->i.funcslast_ +#define havepi0 asl->i.havepi0_ +#define havex0 asl->i.havex0_ +#define lnc asl->i.lnc_ +#define maxcolnamelen asl->i.maxcolnamelen_ +#define maxrownamelen asl->i.maxrownamelen_ +#define nZc asl->i.nZc_ +#define nZo asl->i.nZo_ +#define n_cc asl->i.n_cc_ +#define n_con asl->i.n_con_ +#define n_conjac asl->i.n_conjac_ +#define n_eqn asl->i.n_eqn_ +#define n_lcon asl->i.n_lcon_ +#define n_obj asl->i.n_obj_ +#define n_var asl->i.n_var_ +#define nbv asl->i.nbv_ +#define nclcon asl->i.nclcon_ +#define ncom0 asl->i.ncom0_ +#define ncom1 asl->i.ncom1_ +#define nderps asl->i.nderps_ +#define need_nl asl->i.need_nl_ +#define nfunc asl->i.nfunc_ +#define niv asl->i.niv_ +#define nlc asl->i.nlc_ +#define nlcc asl->i.nlcc_ +#define nlnc asl->i.nlnc_ +#define nlo asl->i.nlo_ +#define nlogv asl->i.nbv_ /* nbv used to be called nlogv */ +#define nlvb asl->i.nlvb_ +#define nlvbi asl->i.nlvbi_ +#define nlvc asl->i.nlvc_ +#define nlvci asl->i.nlvci_ +#define nlvo asl->i.nlvo_ +#define nlvoi asl->i.nlvoi_ +#define nranges asl->i.nranges_ +#define nwv asl->i.nwv_ +#define nzc asl->i.nzc_ +#define nzjac asl->i.nzjac_ +#define nzo asl->i.nzo_ +#define o_cexp1st asl->i.o_cexp1st_ +#define o_vars asl->i.o_vars_ +#define obj_no asl->i.obj_no_ +#define objtype asl->i.objtype_ +#define pi0 asl->i.pi0_ +#define plterms asl->i.plterms_ +#define return_nofile asl->i.return_nofile_ +#define size_expr_n asl->i.size_expr_n_ +#define skip_int_derivs asl->i.skip_int_derivs_ +#define sputinfo asl->i.sputinfo_ +#define stub_end asl->i.stub_end_ +#define want_deriv asl->i.want_deriv_ +#define want_xpi0 asl->i.want_xpi0_ +#define x0kind asl->i.x0kind_ +#define x0len asl->i.x0len_ +#define xscanf asl->i.xscanf_ +#define zaC asl->i.zaC_ +#define zac asl->i.zac_ +#define zao asl->i.zao_ +#define zerograds asl->i.zerograds_ + +#define M1alloc(n) M1alloc_ASL(&asl->i,n) +#define M1free M1free_ASL +#define M1record(n) M1record_ASL(&asl->i,n) +#define M1zapalloc(n) M1zapalloc_ASL(&asl->i,n) +#define Mach Mach_ASL +#define ascanf ascanf_ASL +#define badline badline_ASL +#define badread badread_ASL +#define bscanf bscanf_ASL +#define derprop derprop_ASL +#define dynlink dynlink_ASL +#define edag_peek edag_peek_ASL +#define edagread_one edag_one_ASL +#define fpecatch fpecatch_ASL +#define fpe_jmpbuf fpe_jmpbuf_ASL +#define func_add func_add_ASL +#define func_lookup func_lookup_ASL +#define g_fmt g_fmt_ASL +#define g_fmtp g_fmtp_ASL +#define g_fmtop g_fmtop_ASL +#define g_fmt_E gfmt_E_ASL +#define g_fmt_decpt gfmt_decpt_ASL +#define hscanf hscanf_ASL +#define htcl htcl_ASL +#define mem(n) mem_ASL((ASL*)asl,n) +#define mymalloc mymalloc_ASL +#define mypow mypow_ASL +#define myralloc myralloc_ASL +#define obj_prec obj_prec_ASL +#define optype op_type_ASL +#define optypeb op_typeb_ASL +#define pr_unknown pr_unknown_ASL +#define read_line read_line_ASL +#define report_where report_where_ASL +#define scream scream_ASL +#define what_prog what_prog_ASL + + extern real Infinity, edagread_one, negInfinity; + extern char g_fmt_E, *progname; + extern int g_fmt_decpt; + extern ASL *cur_ASL; + +enum { /* mode bits for ASLtype */ + ASL_read_f = 1, + ASL_read_fg = 2, + ASL_read_fgh = 3, + ASL_read_pfg = 4, + ASL_read_pfgh = 5 + }; + +enum { /* bits for x0kind */ + ASL_have_conval = 1, + ASL_have_objcom = 2, + ASL_first_x = 4, + ASL_have_funnel = 8, /* in con[12]ival */ + ASL_need_funnel = 16, /* in pshvprod */ + ASL_have_concom = 32 + }; + +enum ASL_reader_flag_bits { /* bits in flags arg */ + /* values just relevant to pfg_read and pfgh_read: */ + /* If you do not need the sparsity pattern, */ + /* you can omit linear coefficients of zero. */ + ASL_J_zerodrop = 1, /* Omit 0 linear terms in constraint derivs. */ + ASL_G_zerodrop = 2, /* Omit 0 linear terms in objective derivs. */ + ASL_GJ_zerodrop = 3, /* Omit both kinds of zero linear terms. */ + ASL_findOgroups = 4, /* Find objective group structure. */ + ASL_findCgroups = 8, /* Find constraint group structure. */ + ASL_findgroups = 12, /* Find both group structures; you want this */ + /* unless you're a solver like LANCELOT that */ + /* deals explicitly with group structure. */ + ASL_find_c_class = 32, /* Find c_class and c_class_max: see nlp.h */ + ASL_find_o_class = 64, /* Find o_class and o_class_max: or nlp2.h */ + ASL_find_co_class = 96, /* Find all four */ + + /* applicable to all .nl file readers: */ + ASL_return_read_err = 16, + ASL_keep_all_suffixes = 0x80, + ASL_allow_CLP = 0x1000, /* permit CLP extensions */ + ASL_find_default_no_groups = 0x2000, /* Assume ASL_findgroups */ + /* when this bit is off. */ + /* When ASL_find_default_no_groups is on, pfg_read and pfgh_read */ + /* only honor explicit specification of the ASL_findgroups bits. */ + + /* Stuff for fg_wread: */ + + ASL_omit_all_suffixes = 0x100, + ASL_keep_derivs = 0x200, + ASL_allow_missing_funcs = 0x400, + ASL_forbid_missing_funcs = 0x800, + + /* problem adjustments */ + + ASL_no_linear_cc_rhs_adjust = 0x4000, /* Omit constant term adjustment */ + /* of linear complementarities. */ + + ASL_cc_simplify = 0x8000, /* Provide arrays ccind1 and ccind2 and */ + /* modify complementarities (possibly */ + /* increasing n_cc) so the complementarity */ + /* constraints have the form */ + /* _svar[i] >= 0 complements _svar[j] >= 0 */ + /* for i = ccind1[k] - Fortran */ + /* and j = ccind2[k] - Fortran, */ + /* 0 <= k < n_cc. */ + + ASL_obj_replace_ineq = 0x10000, /* Whether to replace an objective of the */ + /* form minimize or maximize const*var and */ + /* a corresponding constraint of the form */ + /* var relop expr with const*expr, where */ + /* relop is either >= or <=, depending */ + /* on the sense of optimization, and var */ + /* does not appear elsewhere. */ + + ASL_obj_replace_eq = 0x20000, /* Similar to ASL_obj_replace, but where */ + /* relop is == . */ + + ASL_rowwise_jac = 0x40000, /* Whether Jacobian nonzeros should be stored */ + /* row-wise rather than column-wise, in which */ + /* case the A_colstarts array provides offsets */ + /* of rows rather than columns. */ + + ASL_want_A_vals = 0x80000, /* Allocate and use A_vals (if NULL), allowing */ + /* space needed for ASL_cc_simplify. */ + + ASL_sep_U_arrays = 0x100000, /* Allocate and use Uvx and Urhsx */ + + ASL_allow_Z = 0x200000, /* Accept problems with nZc >= 2^31, populating */ + /* A_colstarsZ rather than A_colstarts. */ + ASL_use_Z = 0x400000, /* Use A_colstartsZ rather than A_colstarts, */ + /* regardless of problem size. */ + ASL_opified = 0x800000 /* internal use: qp_opify called */ + }; + +enum ASL_reader_error_codes { + /* return codes from .nl readers with flag ASL_ret_read_err */ + ASL_readerr_none = 0, /* all went well */ + ASL_readerr_nofile = 1, /* cannot open .nl file */ + ASL_readerr_nonlin = 2, /* model involves nonlinearities (ed0read) */ + ASL_readerr_argerr = 3, /* user-defined function with bad args */ + ASL_readerr_unavail= 4, /* user-defined function not available */ + ASL_readerr_corrupt= 5, /* corrupt .nl file */ + ASL_readerr_bug = 6, /* bug in .nl reader */ + ASL_readerr_CLP = 7 /* solver cannot handle CLP extensions */ + }; + +enum ASL_suf_sos_flags { /* bits in flags parameter of suf_sos() */ + ASL_suf_sos_explict_free = 1, /* caller will explicitly free */ + /* returned arrays */ + ASL_suf_sos_ignore_sosno = 2, /* ignore .sosno */ + ASL_suf_sos_ignore_amplsos = 4 /* ignore SOS information from */ + /* transformations of piecewise- */ + /* linear terms (etc.) by AMPL */ + }; + +enum ASL_write_flags { + ASL_write_ASCII = 1, + ASL_write_CR = 2 + }; + +enum ASL_writer_error_codes { + ASL_writeerr_openfail = 1, + ASL_writeerr_badrops = 2, + ASL_writeerr_badcexp1st = 3, + ASL_writeerr_badNewVCO = 4 + }; + +#define f_OPNUM f_OPNUM_ASL +#undef basename +#define basename basename_ASL +#ifndef Sig_ret_type +#define Sig_ret_type void +#endif + + typedef struct +QPinfo { + int nc; /* number of nonempty columns */ + int nz; /* number of nonzeros */ + int *colno; /* column numbers of nonempty columns */ + size_t *colbeg; /* nonzeros for column colno[i]: (rowno[j], delsq[j]) */ + int *rowno; /* for colbeg[i] <= j < colbeg[i+1], except that values */ + real *delsq; /* in colno, colbeg, and rowno are incremented by Fortran */ + } QPinfo; + + extern ASL *ASL_alloc(int); + extern void ASL_free(ASL**); + extern long ASLdate_ASL; + extern void Del_mblk_ASL(ASL*, int, void*); + extern EdRead *EdReadInit_ASL(EdRead*, ASL*, FILE*, void*); + extern void LUcopy_ASL(int, real*, real*, real*); + extern void *M1alloc_ASL(Edaginfo*, size_t); + extern void M1free(Edaginfo*, void**, void**); + extern void **M1record_ASL(Edaginfo*, void*); + extern void *M1zapalloc_ASL(Edaginfo*, size_t); + extern void MAIN__(VOID); + extern void Mach_ASL(VOID); + extern void No_derivs_ASL(const char*); + extern int Sprintf(char*, const char*, ...); + extern void Stderr_init_ASL(void); + extern void Suf_read_ASL(EdRead*, int); + extern void adjust_zerograds_ASL(ASL*, int); + extern int already_ASL(const char*); + extern int ascanf(EdRead*, const char*, ...); + extern void auxinfo_ASL(AmplExports*); + extern void *b_search_ASL(void *ow, int owsize, int n, char **sp, char **peq); + extern void badasl_ASL(ASL*,int,const char*); + extern void badline(EdRead*); + extern void badread(EdRead*); + extern char *basename(const char*); + extern int bscanf(EdRead*, const char*, ...); + extern char *con_name_ASL(ASL*,int); + extern char *con_name_nomap_ASL(ASL*,int,int*); + extern int conadj_ASL(ASL*,int*,int); + extern void congrd_(fint *N, fint *I, real *X, real *G, fint *nerror); + extern real cnival_(fint *N, fint *I, real *X, fint *nerror); + extern void colstart_inc_ASL(ASL*); + extern void conscale_ASL(ASL*, int, real, fint*); + extern void conval_(fint *M, fint *N, real *X, real *F, fint *nerror); + extern void delprb_(VOID); + extern void dense_j_ASL(ASL*); + extern void densej_(VOID); + extern void deriv_errchk_ASL(ASL*, fint*, int coi, int n); + extern void deriv_errclear_ASL(Edaginfo*); + extern void derprop(derp *); + extern char *dtoa(double, int, int, int*, int*, char **); + extern ufunc *dynlink_ASL(const char*); + extern int edag_peek(EdRead*); + extern void equ_adjust_ASL(ASL*, int*, int*); + extern void exit_ASL(EdRead*,int); + extern real f_OPNUM(expr_n*); + extern int f_read_ASL(ASL*, FILE*, int); + extern int fg_read_ASL(ASL*, FILE*, int); + extern int fg_wread_ASL(ASL*, FILE*, int); + extern int fgh_read_ASL(ASL*, FILE*, int); + extern int fg_write_ASL(ASL*, const char*, NewVCO*, int); + extern void fintrouble_ASL(ASL*, func_info*, const char*, TMInfo*); + extern void flagsave_ASL(ASL*, int); + extern void freedtoa(char*); + extern func_info *func_lookup(ASL*, const char*, int add); + extern void func_add(ASL*); + extern int g_fmt(char*, double); + extern int g_fmtop(char*, double); + extern int g_fmtp(char*, double, int); + extern void gen_rownos_ASL(ASL*); + extern ASL *get_cur_ASL(VOID); + extern int *get_vcmap_ASL(ASL*, int); + extern int *get_vminv_ASL(ASL*); + extern char *getenv_ASL(const char*); + extern void goff_comp_ASL(ASL*); + extern int hscanf(EdRead*, const char*, ...); + extern int htcl_ASL(unsigned int); + extern void hvcomp_(real *hv, real *p, fint *nobj, real *ow, real *y); + extern void hvinit_(fint *nobj, real *ow, real *y); + extern int indicator_constrs_ASL(ASL*, void*, Add_Indicator, int errinfo[2]); + extern void intcatch_ASL(ASL*, void (*)(int,void*), void*); + extern void introuble_ASL(ASL*, const char *who, real a, int jv); + extern void introuble2_ASL(ASL*, const char *who, real a, real b, int jv); + extern FILE *jac0dim_ASL(ASL*, const char *stub, ftnlen stub_len); + extern int jac1dim_ASL(ASL*, const char *stub, fint *M, fint *N, fint *NO, + fint *NZ, fint *MXROW, fint *MXCOL, ftnlen stub_len); + extern int jac2dim_ASL (ASL*, const char *stub, fint *M, fint *N, fint *NO, + fint *NZ, fint *MXROW, fint *MXCOL, ftnlen stub_len); + extern FILE *jac_dim_ASL(ASL*, const char *stub, fint *M, fint *N, fint *NO, + fint *NZ, fint *MXROW, fint *MXCOL, ftnlen stub_len); + extern int jacdim_(const char *stub, fint *M, fint *N, fint *NO, fint *NZ, + fint *MXROW, fint *MXCOL, ftnlen stub_len); + extern void jacinc_(fint *M, fint *N, fint *NZ, + fint *JP, short *JI, real *X, real *L, real *U, + real *Lrhs, real *Urhs, real *Inf); + extern int jacpdim_ASL(ASL*, const char *stub, fint *M, fint *N, fint *NO, + fint *NZ, fint *MXROW, fint *MXCOL, ftnlen stub_len); + extern void jacval_(fint *M, fint *N, fint *NZ, real *X, + real *JAC, fint *nerror); + extern Sig_ret_type fpecatch(int); + extern jmp_buf fpe_jmpbuf_ASL; + extern int ka_read_ASL(ASL *, EdRead *, int, int**, size_t**); + extern void lagscale_ASL(ASL*, real, fint*); + extern char *lcon_name_ASL(ASL*,int); + extern void mainexit_ASL(int); + extern void *mem_ASL(ASL*, unsigned int); + extern int mip_pri_ASL(ASL*,int**startp,int**nump,int**prip,fint pmax); + extern void mnnzchk_ASL(ASL*asl,fint*M,fint*N,size_t NZ,const char*who); + extern void mpec_adjust_ASL(ASL*); + extern void mpec_auxvars_ASL(ASL*, real *c, real *x); + extern fint mqpcheck_ASL(ASL*, int co, fint **rowqp, fint **colqp, real **delsqp); + extern ssize_t mqpcheckZ_ASL(ASL*, int co, fint **rowqp, size_t **colqp, real **delsqp); + extern ssize_t mqpcheckv_ASL(ASL*, int co, QPinfo **QPIp, void **vp); + extern void mqpcheckv_free_ASL(ASL*, void **vp); + extern void *mymalloc(size_t); + extern real mypow(real,real); + extern void *myralloc(void *, size_t); + extern void *new_mblk_ASL(ASL*, int k); + extern int nl_obj_ASL(ASL*,int); + extern fint nqpcheck_ASL(ASL*, int co, fint **rowqp, fint **colqp, real **delsqp); + extern ssize_t nqpcheckZ_ASL(ASL*, int co, fint **rowqp, size_t **colqp, real **delsqp); + extern char *obj_name_ASL(ASL*,int); + extern int obj_prec(VOID); + extern void obj_adj_ASL(ASL*); + extern void obj_adj_xy_ASL(ASL *asl, real *x, real *x0, real *y); + extern real objconst_ASL(ASL*,int); + extern void objgrd_(fint *N, real *X, fint *NOBJ, real *G, fint *nerror); + extern real objval_(fint *N, real *X, fint *NOBJ, fint *nerror); + extern char optype[], optypeb[]; + extern int pfg_read_ASL(ASL*, FILE*, int flags); + extern int pfgh_read_ASL(ASL*, FILE*, int flags); + extern char *pr_unknown(FILE*, char*); + extern int prob_adj_ASL(ASL*); + extern void qp_opify_ASL(ASL*); + extern int qp_read_ASL(ASL*, FILE*, int); + extern fint qpcheck_ASL(ASL*, fint **rowqp, fint **colqp, real **delsqp); + extern ssize_t qpcheckZ_ASL(ASL*, fint **rowqp, size_t **colqp, real **delsqp); + extern char *read_line(EdRead*); + extern char *read_sol_ASL(ASL*, real**xp, real **yp); + extern void report_where(ASL*); + extern void scream(EdRead*, int rc, const char *fmt, ...); + extern ASL *set_cur_ASL(ASL*); /* returns previous value */ + extern real set_randseed_ASL(real nseed); /* returns new seed, usually nseed, but */ + /* automaticaally chosen if nseed == 0. */ + extern void show_funcs_ASL(ASL*); + extern void sigcatch_ASL(VOID); + extern void* sos_add_ASL(ASL*, FILE*, int); + extern int sos_finish_ASL(ASL*,void**,int,int*,int**,int*,int**,int**,real**); + extern void student_check_ASL(ASL*); + extern void suf_declare_ASL(ASL*, SufDecl*, int); + extern SufDesc *suf_get_ASL(ASL*, const char*, int); + extern SufDesc *suf_iput_ASL(ASL*, const char*, int, int*); + extern SufDesc *suf_rput_ASL(ASL*, const char*, int, real*); + extern int suf_sos_ASL(ASL*,int,int*,char**,int**,int*,int**,int**,real**); + extern char *var_name_ASL(ASL*,int); + extern char *var_name_nomap_ASL(ASL*,int,int*); + extern void varscale_ASL(ASL*, int, real, fint*); + extern void what_prog(VOID); + extern void write_sol_ASL(ASL*, const char *msg, double *x, double *y, Option_Info*); + extern int write_solf_ASL(ASL*, const char *msg, double *x, double *y, Option_Info *, + const char*); + extern int write_solfx_ASL(ASL*, const char *msg, double *x, double *y, Option_Info *, + Fwrite, Fwrite, Fwrite, const char*); + extern void wrsolw_(char *msg, fint *nmsg, real *x, real *y, fint *wantsol, + ftnlen msg_len); + extern void wrtsol_(char *msg, fint *nmsg, real *x, real *y, + ftnlen msg_len); + extern real xectim_(VOID); + extern void xknowe_(real *x, fint *nerror); + extern void xknown_(real *x); + extern void xunkno_(VOID); + extern void zero_div_ASL(ASL*, real, const char*); + +#ifndef No_dtoa + extern double strtod_ASL(Const char*, char**); +#ifndef strtod /* if not set by previous funcadd.h */ +#define strtod strtod_ASL +#endif +#endif + +#ifdef __cplusplus + } +#endif + +#define con_name(n) con_name_ASL((ASL*)asl,n) +#define conadj(cv) conadj_ASL((ASL*)asl,cv,1) +#define conscale(i,s,ie) conscale_ASL((ASL*)asl,i,s,ie) +#define dense_j() dense_j_ASL((ASL*)asl) +#define edagread(f) fg_read_ASL((ASL*)asl,f,0) /* dreg */ +#define equ_adjust(x,y) equ_adjust_ASL((ASL*)asl,x,y) +#define f_read(a,b) f_read_ASL((ASL*)asl,a,b) +#define fg_read(a,b) fg_read_ASL((ASL*)asl,a,b) +#define fg_wread(a,b) fg_wread_ASL((ASL*)asl,a,b) +#define fg_write(a,b,c) fg_write_ASL((ASL*)asl,a,b,c) +#define fgh_read(a,b) fgh_read_ASL((ASL*)asl,a,b) +#define gen_rownos() gen_rownos_ASL((ASL*)asl) +#undef getenv +#define getenv getenv_ASL +#define int_catch(f,v) intcatch_ASL((ASL*)asl,f,v) +#define jac0dim(stub,len) jac0dim_ASL((ASL*)asl,stub,len) +#define jac1dim(s,m,n,no,nz,mxr,mxc,L) jac1dim_ASL((ASL*)asl,s,m,n,no,nz,mxr,mxc,L) +#define jac2dim(s,m,n,no,nz,mxr,mxc,L) jac2dim_ASL((ASL*)asl,s,m,n,no,nz,mxr,mxc,L) +#define jacdim(stub,M,N,NO,NZ,MXR,MXC,len) jac_dim_ASL((ASL*)asl,stub,M,N,NO,NZ,MXR,MXC,len) +#define jacdim0(stub,len) jac0dim_ASL((ASL*)asl,stub,len) +#define jacpdim(s,m,n,no,nz,mxr,mxc,L) jacpdim_ASL((ASL*)asl,s,m,n,no,nz,mxr,mxc,L) +#define lagscale(s,ie) lagscale_ASL((ASL*)asl,s,ie) +#define lcon_name(n) lcon_name_ASL((ASL*)asl,n) +#define mip_pri(a,b,c,d) mip_pri_ASL((ASL*)asl,a,b,c,d) +#define mqpcheck(a,b,c,d) mqpcheck_ASL((ASL*)asl,a,b,c,d) +#define mqpcheckv(a,b,c) mqpcheckv_ASL((ASL*)asl,a,b,c) +#define mqpcheckv_free(a) mqpcheckv_free_ASL((ASL*)asl,a) +#define nl_obj(n) nl_obj_ASL((ASL*)asl,n) +#define nqpcheck(a,b,c,d) nqpcheck_ASL((ASL*)asl,a,b,c,d) +#define obj_name(n) obj_name_ASL((ASL*)asl,n) +#define objconst(n) objconst_ASL((ASL*)asl,n) +#define pfg_read(a,b) pfg_read_ASL((ASL*)asl,a,b) +#define pfgh_read(a,b) pfgh_read_ASL((ASL*)asl,a,b) +#define qp_opify() qp_opify_ASL((ASL*)asl) +#define qp_read(a,b) qp_read_ASL((ASL*)asl,a,b) +#define qpcheck(a,b,c) qpcheck_ASL((ASL*)asl,a,b,c) +#define read_soln(x,y) read_sol_ASL((ASL*)asl,x,y) +#define show_funcs() show_funcs_ASL((ASL*)asl) +#define sos_add(a,b) sos_add_ASL((ASL*)asl,a,b) +#define sos_finish(a,b,c,d,e,f,g,h) sos_finish_ASL((ASL*)asl,a,b,c,d,e,f,g,h) +#define suf_declare(x,n) suf_declare_ASL((ASL*)asl,x,(int)(n)) +#define suf_get(s,i) suf_get_ASL((ASL*)asl,s,i) +#define suf_iput(n,i,x) suf_iput_ASL((ASL*)asl,n,i,x) +#define suf_rput(n,i,x) suf_rput_ASL((ASL*)asl,n,i,x) +#define suf_sos(a,b,c,d,e,f,g,h) suf_sos_ASL((ASL*)asl,a,b,c,d,e,f,g,h) +#define var_name(n) var_name_ASL((ASL*)asl,n) +#define varscale(i,s,ie) varscale_ASL((ASL*)asl,i,s,ie) +#define write_sol(m,x,y,oi) write_sol_ASL((ASL*)asl,m,x,y,oi) +#define write_soln(m,x,y) write_sol_ASL((ASL*)asl,m,x,y,0) +#ifdef KR_headers +#define del_mblk(a,b) Del_mblk_ASL((ASL*)asl, a, (void*)(b)) +#else +#define del_mblk(a,b) Del_mblk_ASL((ASL*)asl,a,b) +#endif +#define new_mblk(n) new_mblk_ASL((ASL*)asl,n) + +#define exit mainexit_ASL + +#ifdef MULTIPLE_THREADS +#define A_ASL , ASL *asl +#define C_ASL , (ASL*)asl +#define D_ASL ASL *asl; +#define K_ASL , asl +#ifndef MEM_LOCK +#define MEM_LOCK 3 +#endif +#ifndef MBLK_LOCK +#define MBLK_LOCK 4 +#endif +#ifndef HESOPROD_LOCK +#define HESOPROD_LOCK 5 +#endif +#else /* MULTIPLE_THREADS */ +#define A_ASL /*nothing*/ +#define C_ASL /*nothing*/ +#define D_ASL /*nothing*/ +#define K_ASL /*nothing*/ +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ +#endif /* MULTIPLE_THREADS */ + +#define ASL_CHECK(a,n,w) if(!a||a->i.ASLtype!=n)badasl_ASL(a,n,w);cur_ASL=a; +#endif /* ASL_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/asl_pfg.h b/thirdparty/linux/include/coin/ThirdParty/asl_pfg.h new file mode 100644 index 0000000..e3d26be --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/asl_pfg.h @@ -0,0 +1,29 @@ +/**************************************************************** +Copyright (C) 1997 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#undef PSHVREAD +#ifndef ASL_PFG_included +#define ASL_PFG_included +#include "psinfo.h" +#endif /* ASL_PFG_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/asl_pfgh.h b/thirdparty/linux/include/coin/ThirdParty/asl_pfgh.h new file mode 100644 index 0000000..fc3e71c --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/asl_pfgh.h @@ -0,0 +1,30 @@ +/**************************************************************** +Copyright (C) 1997 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#undef PSHVREAD +#define PSHVREAD +#ifndef ASL_PFGH_included +#define ASL_PFGH_included +#include "psinfo.h" +#endif /* ASL_PFGH_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/funcadd.h b/thirdparty/linux/include/coin/ThirdParty/funcadd.h new file mode 100644 index 0000000..ec30d97 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/funcadd.h @@ -0,0 +1,487 @@ +/**************************************************************** +Copyright (C) 1997-2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#ifndef FUNCADD_H_INCLUDED +#define FUNCADD_H_INCLUDED +#include "stdio1.h" /* for ANSI and any printing */ + +#ifndef VA_LIST +#define VA_LIST va_list +#endif + +#ifdef _WIN32 +#define Stdio_redefs +#endif + + typedef struct cryptblock cryptblock; + +#ifdef __cplusplus +#undef KR_headers +extern "C" { +#endif + +#ifndef real +typedef double real; +#endif +typedef struct arglist arglist; +typedef struct function function; +typedef struct TVA TVA; +typedef struct AmplExports AmplExports; +typedef struct AuxInfo AuxInfo; +typedef struct TableInfo TableInfo; +typedef struct TMInfo TMInfo; + +#ifndef No_arglist_def + +#undef Const +#ifdef KR_headers +#define Const /* nothing */ +#else +#define Const const +#endif + + struct +arglist { /* Information sent to user-defined functions */ + int n; /* number of args */ + int nr; /* number of real input args */ + int *at; /* argument types -- see DISCUSSION below */ + real *ra; /* pure real args (IN, OUT, and INOUT) */ + Const char **sa; /* symbolic IN args */ + real *derivs; /* for partial derivatives (if nonzero) */ + real *hes; /* for second partials (if nonzero) */ + char *dig; /* if (dig && dig[i]) { partials w.r.t. */ + /* ra[i] will not be used } */ + Char *funcinfo; /* for use by the function (if desired) */ + AmplExports *AE; /* functions made visible (via #defines below) */ + function *f; /* for internal use by AMPL */ + TVA *tva; /* for internal use by AMPL */ + char *Errmsg; /* To indicate an error, set this to a */ + /* description of the error. When derivs */ + /* is nonzero and the error is that first */ + /* derivatives cannot or are not computed, */ + /* a single quote character (') should be */ + /* the first character in the text assigned */ + /* to Errmsg, followed by the actual error */ + /* message. Similarly, if hes is nonzero */ + /* and the error is that second derivatives */ + /* are not or cannot be computed, a double */ + /* quote character (") should be the first */ + /* character in Errmsg, followed by the */ + /* actual error message text. */ + TMInfo *TMI; /* used in Tempmem calls */ + Char *Private; + /* The following fields are relevant */ + /* only when imported functions are called */ + /* by AMPL commands (not declarations). */ + + int nin; /* number of input (IN and INOUT) args */ + int nout; /* number of output (OUT and INOUT) args */ + int nsin; /* number of symbolic input arguments */ + int nsout; /* number of symbolic OUT and INOUT args */ + }; + +typedef real (*rfunc) ANSI((arglist *)); +typedef real (ufunc) ANSI((arglist *)); + +#endif /* No_arglist_def */ + + enum AMPLFUNC_AT_BITS { /* Intrepretation of at[i] when the type */ + /* arg to addfunc has the */ + /* FUNCADD_OUTPUT_ARGS bit on.*/ + AMPLFUNC_INARG = 1, /* IN or INOUT */ + AMPLFUNC_OUTARG = 2, /* OUT or INOUT */ + AMPLFUNC_STRING = 4, /* Input value is a string (sa[i]) */ + AMPLFUNC_STROUT = 8 /* String output value allowed */ + }; + + enum FUNCADD_TYPE { /* bits in "type" arg to addfunc */ + + /* The type arg to addfunc should consist of one of the */ + /* following values ... */ + + FUNCADD_REAL_VALUED = 0, /* real (double) valued function */ + FUNCADD_STRING_VALUED = 2, /* char* valued function (AMPL only) */ + FUNCADD_RANDOM_VALUED = 4, /* real random valued */ + FUNCADD_012ARGS = 6, /* Special case: real random valued */ + /* with 0 <= nargs <= 2 arguments */ + /* passed directly, rather than in */ + /* an arglist structure (AMPL only). */ + + /* possibly or-ed with the following... */ + + FUNCADD_STRING_ARGS = 1, /* allow string args */ + FUNCADD_OUTPUT_ARGS = 16, /* allow output args (AMPL only) */ + FUNCADD_TUPLE_VALUED = 32, /* not yet allowed */ + + /* internal use */ + FUNCADD_NO_ARGLIST = 8, + FUNCADD_NO_DUPWARN = 64, /* no complaint if already defined */ + FUNCADD_NONRAND_BUILTIN = 128 /* mean, variance, moment, etc. */ + }; + +/* If a constraint involves an imported function and presolve fixes all + * the arguments of the function, AMPL may later need to ask the + * function for its partial derivatives -- even though the solver had + * no reason to call the function. If so, it will pass an arglist *al + * with al->derivs nonzero, and it will expect the function to set + * al->derivs[i] to the partial derivative of the function with respect + * to al->ra[i]. Solvers that need to evaluate an imported function + * work the same way -- they set al->derivs to a nonzero value if they + * require both the function value and its first derivatives. Solvers + * that expect Hessians to be supplied to them also set al->hes to a + * nonzero value if they require second derivatives at the current + * argument. In this case, the function should set + * al->hes[i + j*(j+1)/2] to the partial derivative of the function with + * respect to al->ra[i] and al->ra[j] for all 0 <= i <= j < al->nr. + */ + +typedef void AddFunc ANSI(( + const char *name, + rfunc f, /* cast f to (rfunc) if it returns char* */ + int type, /* see FUNCADD_TYPE above */ + int nargs, /* >= 0 ==> exactly that many args + * <= -1 ==> at least -(nargs+1) args + */ + void *funcinfo, /* for use by the function (if desired) */ + AmplExports *ae + )); + +typedef void AddRand ANSI(( + const char *name, + rfunc f, /* assumed to be a random function */ + rfunc icdf, /* inverse CDF */ + int type, /* FUNCADD_STRING_ARGS or 0 */ + int nargs, /* >= 0 ==> exactly that many args + * <= -1 ==> at least -(nargs+1) args + */ + void *funcinfo, /* for use by the function (if desired) */ + AmplExports *ae + )); + +typedef void (*RandSeedSetter) ANSI((void*, unsigned long)); +typedef void AddRandInit ANSI((AmplExports *ae, RandSeedSetter, void*)); +typedef void Exitfunc ANSI((void*)); + + struct +AuxInfo { + AuxInfo *next; + char *auxname; + void *v; + void (*f) ANSI((AmplExports*, void*, ...)); + }; + + struct +AmplExports { + FILE *StdErr; + AddFunc *Addfunc; + long ASLdate; + int (*FprintF) ANSI((FILE*, const char*, ...)); + int (*PrintF) ANSI((const char*, ...)); + int (*SprintF) ANSI((char*, const char*, ...)); + int (*VfprintF) ANSI((FILE*, const char*, VA_LIST)); + int (*VsprintF) ANSI((char*, const char*, VA_LIST)); + double (*Strtod) ANSI((const char*, char**)); + cryptblock *(*Crypto) ANSI((char *key, size_t scrbytes)); + Char *asl; + void (*AtExit) ANSI((AmplExports *ae, Exitfunc*, void*)); + void (*AtReset) ANSI((AmplExports *ae, Exitfunc*, void*)); + Char *(*Tempmem) ANSI((TMInfo*, size_t)); + void (*Add_table_handler) ANSI(( + int (*DbRead) (AmplExports *ae, TableInfo *TI), + int (*DbWrite)(AmplExports *ae, TableInfo *TI), + char *handler_info, + int flags, + void *Vinfo + )); + Char *Private; + void (*Qsortv) ANSI((void*, size_t, size_t, int(*)(const void*,const void*,void*), void*)); + + /* More stuff for stdio in DLLs... */ + + FILE *StdIn; + FILE *StdOut; + void (*Clearerr) ANSI((FILE*)); + int (*Fclose) ANSI((FILE*)); + FILE* (*Fdopen) ANSI((int, const char*)); + int (*Feof) ANSI((FILE*)); + int (*Ferror) ANSI((FILE*)); + int (*Fflush) ANSI((FILE*)); + int (*Fgetc) ANSI((FILE*)); + char* (*Fgets) ANSI((char*, int, FILE*)); + int (*Fileno) ANSI((FILE*)); + FILE* (*Fopen) ANSI((const char*, const char*)); + int (*Fputc) ANSI((int, FILE*)); + int (*Fputs) ANSI((const char*, FILE*)); + size_t (*Fread) ANSI((void*, size_t, size_t, FILE*)); + FILE* (*Freopen) ANSI((const char*, const char*, FILE*)); + int (*Fscanf) ANSI((FILE*, const char*, ...)); + int (*Fseek) ANSI((FILE*, long, int)); + long (*Ftell) ANSI((FILE*)); + size_t (*Fwrite) ANSI((const void*, size_t, size_t, FILE*)); + int (*Pclose) ANSI((FILE*)); + void (*Perror) ANSI((const char*)); + FILE* (*Popen) ANSI((const char*, const char*)); + int (*Puts) ANSI((const char*)); + void (*Rewind) ANSI((FILE*)); + int (*Scanf) ANSI((const char*, ...)); + void (*Setbuf) ANSI((FILE*, char*)); + int (*Setvbuf) ANSI((FILE*, char*, int, size_t)); + int (*Sscanf) ANSI((const char*, const char*, ...)); + char* (*Tempnam) ANSI((const char*, const char*)); + FILE* (*Tmpfile) ANSI((void)); + char* (*Tmpnam) ANSI((char*)); + int (*Ungetc) ANSI((int, FILE*)); + AuxInfo *AI; + char* (*Getenv) ANSI((const char*)); + void (*Breakfunc) ANSI((int,void*)); + Char *Breakarg; + /* Items available with ASLdate >= 20020501 start here. */ + int (*SnprintF) ANSI((char*, size_t, const char*, ...)); + int (*VsnprintF) ANSI((char*, size_t, const char*, VA_LIST)); + + AddRand *Addrand; /* for random function/inverse CDF pairs */ + AddRandInit *Addrandinit; /* for adding a function to receive a new random seed */ + }; + +extern const char *i_option_ASL, *ix_details_ASL[]; + +#define funcadd funcadd_ASL + +#if defined(_WIN32) && !defined(__MINGW32__) +__declspec(dllexport) +#endif +extern void funcadd ANSI((AmplExports*)); /* dynamically linked */ +extern void af_libnamesave_ASL ANSI((AmplExports*, const char *fullname, const char *name, int nlen)); +extern void note_libuse_ASL ANSI((void)); /* If funcadd() does not provide any imported */ + /* functions, it can call note_libuse_ASL() to */ + /* keep the library loaded; note_libuse_ASL() is */ + /* called, e.g., by the tableproxy table handler. */ + +#ifdef __cplusplus + } +#endif + + typedef struct +DbCol { + real *dval; + char **sval; + } DbCol; + + struct +TableInfo { + int (*AddRows) ANSI((TableInfo *TI, DbCol *cols, long nrows)); + char *tname; /* name of this table */ + char **strings; + char **colnames; + DbCol *cols; + char *Missing; + char *Errmsg; + void *Vinfo; + TMInfo *TMI; + int nstrings; + int arity; + int ncols; + int flags; + long nrows; + void *Private; + int (*Lookup) ANSI((real*, char**, TableInfo*)); + long (*AdjustMaxrows) ANSI((TableInfo*, long new_maxrows)); + void *(*ColAlloc) ANSI((TableInfo*, int ncol, int sval)); + long maxrows; + }; + +enum { /* return values from (*DbRead)(...) and (*DbWrite)(...) */ + DB_Done = 0, /* Table read or written. */ + DB_Refuse = 1, /* Refuse to handle this table. */ + DB_Error = 2 /* Error reading or writing table. */ + }; + +enum { /* bits in flags field of TableInfo */ + DBTI_flags_IN = 1, /* table has IN or INOUT entities */ + DBTI_flags_OUT = 2, /* table has OUT or INOUT entities */ + DBTI_flags_INSET = 4 /* table has "in set" phrase: */ + /* DbRead could omit rows for */ + /* which Lookup(...) == -1; AMPL */ + /* will ignore such rows if DbRead */ + /* offers them. */ + }; + +#endif /* FUNCADD_H_INCLUDED */ + +#ifndef No_AE_redefs +/* Assume "{extern|static} AmplExports *ae;" is given elsewhere. */ +#undef Stderr +#undef addfunc +#undef fprintf +#undef getenv +#undef printf +#undef sprintf +#undef snprintf +#undef strtod +#undef vfprintf +#undef vsprintf +#undef vsnprintf +#define Stderr (ae->StdErr) +#define addfunc(a,b,c,d,e) (*ae->Addfunc)(a,b,c,d,e,ae) +#define addrand(a,b,c,d,e,f) (*ae->Addrand)(a,b,c,d,e,f,ae) +#define addrandinit(a,b) (*ae->Addrandinit)(ae,a,b) +#define printf (*ae->PrintF) +#define fprintf (*ae->FprintF) +#define snprintf (*ae->SnprintF) +#define sprintf (*ae->SprintF) +#define strtod (*ae->Strtod) +#define vfprintf (*ae->VfprintF) +#define vsprintf (*ae->VsprintF) +#define vsnprintf (*ae->VsnprintF) +#define TempMem(x,y) (*ae->Tempmem)(x,y) +#define at_exit(x,y) (*ae->AtExit)(ae,x,y) +#define at_reset(x,y) (*ae->AtReset)(ae,x,y) +#define add_table_handler(a,b,c,d,e) (*ae->Add_table_handler)(a,b,c,d,e) +#define qsortv(a,b,c,d,e) (*ae->Qsortv)(a,b,c,d,e) +#define getenv(x) (*ae->Getenv)(x) +#ifdef Stdio_redefs +#undef clearerr +#undef fclose +#undef fdopen +#undef feof +#undef ferror +#undef fflush +#undef fgetc +#undef fgets +#undef fileno +#undef fopen +#undef fputc +#undef fputs +#undef fread +#undef freopen +#undef fscanf +#undef fseek +#undef ftell +#undef fwrite +#undef getc +#undef getchar +#undef gets +#undef pclose +#undef perror +#undef popen +#undef putc +#undef putchar +#undef puts +#undef rewind +#undef scanf +#undef setbuf +#undef setvbuf +#undef sscanf +#undef tempnam +#undef tmpfile +#undef tmpnam +#undef ungetc +#undef vprintf +#define clearerr (*ae->Clearerr) +#define fclose (*ae->Fclose) +#define fdopen (*ae->Fdopen) +#define feof (*ae->Feof) +#define ferror (*ae->Ferror) +#define fflush (*ae->Fflush) +#define fgetc (*ae->Fgetc) +#define fgets (*ae->Fgets) +#define fileno (*ae->Fileno) +#define fopen (*ae->Fopen) +#define fputc (*ae->Fputc) +#define fputs (*ae->Fputs) +#define fread (*ae->Fread) +#define freopen (*ae->Freopen) +#define fscanf (*ae->Fscanf) +#define fseek (*ae->Fseek) +#define ftell (*ae->Ftell) +#define fwrite (*ae->Fwrite) +#define getc (*ae->Fgetc) +#define getchar() (*ae->Getc)(ae->StdIn) +#define gets Error - use "fgets" rather than "gets" +#define pclose (*ae->Pclose) +#define perror (*ae->Perror) +#define popen (*ae->Popen) +#define putc (*ae->Fputc) +#define putchar(x) (*ae->Fputc)(ae->StdOut,(x)) +#define puts (*ae->Puts) +#define rewind (*ae->Rewind) +#define scanf (*ae->Scanf) +#define setbuf (*ae->Setbuf) +#define setvbuf (*ae->Setvbuf) +#define sscanf (*ae->Sscanf) +#define tempnam (*ae->Tempnam) +#define tmpfile (*ae->Tmpfile) +#define tmpnam (*ae->Tmpnam) +#define ungetc (*ae->Ungetc) +#define vprintf(x,y) (*ae->VfprintF)(ae->StdOut,(x),(y)) +#define Stdin (ae->StdIn) +#define Stdout (ae->StdOut) +#ifndef No_std_FILE_redefs /* may elicit compiler warnings */ +#undef stdin +#undef stdout +#undef stderr +#define stdin (ae->StdIn) +#define stdout (ae->StdOut) +#define stderr (ae->StdErr) +#endif /* No_std_FILE_redefs */ +#endif /* Stdio_redefs */ +#endif /* ifndef No_AE_redefs */ + +/* DISCUSSION: the "at" field of an arglist... + * + * OUT and INOUT arguments are only permitted in AMPL commands, + * such as "let" and "call" commands (and not in declarations, e.g., + * of constraints and variables). + * + * When addfunc was called with type <= 6 (so there can be no OUT or + * INOUT arguments), for 0 <= i < n, + * at[i] >= 0 ==> arg i is ra[at[i]] + * at[i] < 0 ==> arg i is sa[-(at[i]+1)]. + * + * When addfunc was called with type & FUNCADD_OUTPUT_ARGS on (permitting + * OUT and INOUT arguments), arg i is in ra[i] or sa[i] (as explained + * below), derivs and hes are both null, and at[i] is the union of bits + * that describe arg i: + * AMPLFUNC_INARG = 1 ==> input arg; + * AMPLFUNC_OUTARG = 2 ==> output arg; + * AMPLFUNC_STROUT = 4 ==> can be assigned a string value. + * + * INOUT args have both the AMPLFUNC_INARG and the AMPLFUNC_OUTARG bits + * are on, i.e., (at[i] & 3) == 3. + * + * Symbolic OUT and INOUT arguments are a bit complicated. They can only + * correspond to symbolic parameters in AMPL, which may have either a + * string or a numeric value. Thus there is provision for specifying + * output values to be either numbers or strings. For simplicity, when + * the function accepts output arguments, ra[i] and sa[i] together describe + * argument i. In general (whentype & FUNCADD_OUTPUT_ARGS is nonzero in + * the addfunc call), the incoming value of argument i is ra[i] + * (a numeric value) if sa[i] is null and is otherwise sa[i]. + * To assign a value to argument i, either assign a numeric value to + * ra[i] and set sa[i] = 0, or assign a non-null value to sa[i] + * (in which case ra[i] will be ignored). A value assigned to argument + * i is ignored unless at[i] & AMPLFUNC_OUTARG is nonzero; if so + * and if (at[i] & AMPLFUNC_STROUT) == 0, string values cause an error + * message. + */ diff --git a/thirdparty/linux/include/coin/ThirdParty/getstub.h b/thirdparty/linux/include/coin/ThirdParty/getstub.h new file mode 100644 index 0000000..a5d7631 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/getstub.h @@ -0,0 +1,206 @@ +/**************************************************************** +Copyright (C) 1997-1998, 2000-2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#ifndef GETSTUB_H_included +#define GETSTUB_H_included +#ifndef ASL_included +#include "asl.h" +#endif + + typedef struct keyword keyword; + + typedef char * +Kwfunc(Option_Info *oi, keyword *kw, char *value); + + struct +keyword { + char *name; + Kwfunc *kf; + void *info; + char *desc; + }; + +#define KW(a,b,c,d) {a,b,(void*)(c),d} +#define nkeywds (int)(sizeof(keywds)/sizeof(keyword)) + + typedef fint Solver_KW_func(char*, fint); + typedef fint Fileeq_func(fint*, char*, fint); + + struct +Option_Info { + char *sname; /* invocation name of solver */ + char *bsname; /* solver name in startup "banner" */ + char *opname; /* name of solver_options environment var */ + keyword *keywds; /* key words */ + int n_keywds; /* number of key words */ + int flags; /* whether funcadd will be called, etc.: */ + /* see the first enum below */ + char *version; /* for -v and Ver_key_ASL() */ + char **usage; /* solver-specific usage message */ + Solver_KW_func *kwf; /* solver-specific keyword function */ + Fileeq_func *feq; /* for nnn=filename */ + keyword *options; /* command-line options (with -) before stub */ + int n_options; /* number of options */ + long driver_date; /* YYYYMMDD for driver */ + + /* For write_sol: */ + + int wantsol; /* write .sol file without -AMPL */ + int nS; /* transmit S[i], 0 <= i < nS */ + SufDesc *S; + + /* For possible use by "nonstandard" Kwfunc's: */ + + char *uinfo; + + /* Stuff provided/used by getopts (and getstops): */ + + ASL *asl; + char *eqsign; + int n_badopts; /* number of bad options: bail out if != 0*/ + int option_echo;/* whether to echo: see the second enum below. */ + /* Kwfunc's may set option_echo &= ~ASL_OI_echo to turn off all */ + /* keyword echoing or option_echo &= ~ASL_OI_echothis to turn */ + /* off echoing of the present keyword. If they detect but do */ + /* not themselves report a bad value, they should set */ + /* option_echo |= ASL_OI_badvalue. During command-line option */ + /* processing (for -... args), (option_echo & ASL_OI_clopt) is */ + /* nonzero. */ + + int nnl; /* internal use: copied to asl->i.need_nl_ */ + }; + + enum { /* bits for Option_Info.flags */ + ASL_OI_want_funcadd = 1, + ASL_OI_keep_underscores = 2, + ASL_OI_show_version = 4 + } ; + + enum { /* bits for Option_Info.option_echo */ + ASL_OI_echo = 1, + ASL_OI_echothis = 2, + ASL_OI_clopt = 4, + ASL_OI_badvalue = 8, + ASL_OI_never_echo = 16, + ASL_OI_tabexpand = 32, /* have shownames() expand tabs */ + ASL_OI_addnewline = 64, /* have shownames() add a newline */ + /* after each keyword description */ + ASL_OI_showname_bits = 96, + ASL_OI_defer_bsname = 128 /* print "bsname: " only if there */ + /* are options to echo */ + } ; + +#ifdef __cplusplus + extern "C" { +#endif + +/* Kwfuncs should invoke badopt_ASL() if they complain. */ +extern void badopt_ASL (Option_Info*); +extern char *badval_ASL (Option_Info*, keyword*, char *value, char *badc); +extern char* get_opt_ASL (Option_Info*, char*); +extern int getopts_ASL (ASL*, char **argv, Option_Info*); +extern char* getstops_ASL (ASL*, char **argv, Option_Info*); +extern char* getstub_ASL (ASL*, char ***pargv, Option_Info*); +extern void show_version_ASL(Option_Info*); +extern char sysdetails_ASL[]; +extern void usage_ASL(Option_Info*, int exit_code); +extern void usage_noexit_ASL(Option_Info*, int exit_code); + +#define getstub(a,b) getstub_ASL((ASL*)asl,a,b) +#define getstops(a,b) getstops_ASL((ASL*)asl,a,b) +#define getopts(a,b) getopts_ASL((ASL*)asl,a,b) + +#define CK_val CK_val_ASL /* known character value in known place */ +#define C_val C_val_ASL /* character value in known place */ +#define DA_val DA_val_ASL /* real (double) value in asl */ +#define DK_val DK_val_ASL /* known real (double) value in known place */ +#define DU_val DU_val_ASL /* real (double) value: offset from uinfo */ +#define D_val D_val_ASL /* real (double) value in known place */ +#define FI_val FI_val_ASL /* fint value in known place */ +#define IA_val IA_val_ASL /* int value in asl */ +#define IK0_val IK0_val_ASL /* int value 0 in known place */ +#define IK1_val IK1_val_ASL /* int value 1 in known place */ +#define IK_val IK_val_ASL /* known int value in known place */ +#define IU_val IU_val_ASL /* int value: offset from uinfo */ +#define I_val I_val_ASL /* int value in known place */ +#define LK_val LK_val_ASL /* known Long value in known place */ +#define LU_val LU_val_ASL /* Long value: offset from uinfo */ +#define L_val L_val_ASL /* Long value in known place */ +#define SU_val SU_val_ASL /* short value: offset from uinfo */ +#define Ver_val Ver_val_ASL /* report version */ +#define WS_val WS_val_ASL /* set wantsol in Option_Info */ + +extern char *Lic_info_add_ASL; /* for show_version_ASL() */ +extern char WS_desc_ASL[]; /* desc for WS_val, constrained problems */ +extern char WSu_desc_ASL[]; /* desc for WS_val, unconstrained problems */ + +extern Kwfunc C_val, CK_val, DA_val, DK_val, DU_val, D_val, FI_val, IA_val; +extern Kwfunc IK0_val, IK1_val, IK_val, IU_val, I_val, LK_val, LU_val; +extern Kwfunc L_val, Ver_val, WS_val; +extern Kwfunc SU_val; + +/* Routines for converting Double (real), Long, and int values: */ + +extern char *Dval_ASL (Option_Info*, keyword*, char*, real*); +extern char *Ival_ASL (Option_Info*, keyword*, char*, int*); +extern char *Lval_ASL (Option_Info*, keyword*, char*, Long*); + +#define voffset_of(t,c) ((void *)&((t*)0)->c) + +/* Structs whose address can be the info field for known values... */ + +#define C_Known C_Known_ASL /* char* value for CK_val */ +#define D_Known D_Known_ASL /* real (double) value for DK_val */ +#define I_Known I_Known_ASL /* int value for IK_val */ +#define L_Known L_Known_ASL /* Long value for LK_val */ + + typedef struct +C_Known { + char *val; + char **valp; + } C_Known; + + typedef struct +D_Known { + real val; + real *valp; + } D_Known; + + typedef struct +I_Known { + int val; + int *valp; + } I_Known; + + typedef struct +L_Known { + Long val; + Long *valp; + } L_Known; + +#ifdef __cplusplus + } +#endif + +#endif /* GETSTUB_H_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/nlp.h b/thirdparty/linux/include/coin/ThirdParty/nlp.h new file mode 100644 index 0000000..67d00c4 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/nlp.h @@ -0,0 +1,260 @@ +/**************************************************************** +Copyright (C) 1997-1998, 2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#ifndef NLP_H_included +#define NLP_H_included + +#ifndef ASL_included +#include "asl.h" +#endif + +typedef struct argpair argpair; +typedef struct cde cde; +typedef struct cexp cexp; +typedef struct cexp1 cexp1; +typedef struct de de; +typedef union ei ei; +typedef struct expr expr; +typedef struct expr_f expr_f; +typedef struct expr_h expr_h; +typedef struct expr_if expr_if; +typedef struct expr_v expr_v; +typedef struct expr_va expr_va; +typedef struct funnel funnel; +typedef struct list list; + +typedef real efunc ANSI((expr * A_ASL)); + +#define r_ops r_ops_ASL +#define obj1val obj1val_ASL +#define obj1grd obj1grd_ASL +#define con1val con1val_ASL +#define jac1val jac1val_ASL +#define con1ival con1ival_ASL +#define con1grd con1grd_ASL +#define lcon1val lcon1val_ASL +#define x1known x1known_ASL + + union +ei { + expr *e; + expr **ep; + expr_if *eif; + expr_n *en; + int i; + plterm *p; + de *d; + real *rp; + derp *D; + cexp *ce; + }; + + struct +expr { + efunc *op; + int a; + real dL; + ei L, R; + real dR; + }; + + struct +expr_v { + efunc *op; + int a; + real v; + }; + + struct +expr_if { + efunc *op; + int a; + expr *e, *T, *F; + derp *D, *dT, *dF, *d0; + ei Tv, Fv; + expr_if *next, *next2; + }; + + struct +expr_va { + efunc *op; + int a; + ei L, R; + expr_va *next, *next2; + derp *d0; + }; + + struct +cde { + expr *e; + derp *d; + int zaplen; + }; + + struct +de { + expr *e; + derp *d; + ei dv; + }; + + struct +list { + list *next; + ei item; + }; + + struct +cexp1 { + expr *e; + int nlin; + linpart *L; + }; + + struct +cexp { + expr *e; + int nlin; + linpart *L; + funnel *funneled; + list *cref; + ei z; + int zlen; + derp *d; + int *vref; + }; + + struct +funnel { + funnel *next; + cexp *ce; + derp *fulld; + cplist *cl; + cde fcde; + }; + + struct +argpair { + expr *e; + union { + char **s; + real *v; + } u; + }; + + struct +expr_f { + efunc *op; + int a; + func_info *fi; + arglist *al; + argpair *ap, *ape, *sap, *sape; + expr *args[1]; + }; + + struct +expr_h { + efunc *op; + int a; + char sym[1]; + }; + + typedef struct +Edag1info { + cde *con_de_; /* constraint deriv. and expr. info */ + cde *lcon_de_; /* logical constraints */ + cde *obj_de_; /* objective deriv. and expr. info */ + expr_v *var_e_; /* variable values (and related items) */ + + /* stuff for "defined" variables */ + funnel *f_b_; + funnel *f_c_; + funnel *f_o_; + expr_v *var_ex_, + *var_ex1_; + cexp *cexps_; + cexp1 *cexps1_; + efunc **r_ops_; + char *c_class; /* class of each constraint: */ + /* 0 = constant */ + /* 1 = linear */ + /* 2 = quadratic */ + /* 3 = general nonlinear */ + char *o_class; /* class of each objective */ + char *v_class; /* class of each defined variable */ + int c_class_max; /* max of c_class values */ + int o_class_max; /* max of o_class values */ + /* The above are only computed if requested */ + /* by the ASL_find_c_class and */ + /* ASL_find_o_class bits of the flags arg */ + /* to pfgh_read() and pfg_read() */ + } Edag1info; + + typedef struct +ASL_fg { + Edagpars p; + Edaginfo i; + Edag1info I; + } ASL_fg; + +#ifdef __cplusplus + extern "C" { +#endif + extern efunc *r_ops_ASL[]; + extern void com1eval_ASL ANSI((ASL_fg*, int, int)); + extern void comeval_ASL ANSI((ASL_fg*, int, int)); + extern void funnelset_ASL ANSI((ASL_fg*, funnel *)); + extern real obj1val ANSI((ASL*, int nobj, real *X, fint *nerror)); + extern void obj1grd ANSI((ASL*, int nobj, real *X, real *G, fint *nerror)); + extern void con1val ANSI((ASL*, real *X, real *F, fint *nerror)); + extern void jac1val ANSI((ASL*, real *X, real *JAC, fint *nerror)); + extern real con1ival ANSI((ASL*,int nc, real *X, fint *ne)); + extern void con1grd ANSI((ASL*, int nc, real *X, real *G, fint *nerror)); + extern int lcon1val ANSI((ASL*,int nc, real *X, fint *ne)); + extern int x0_check_ASL ANSI((ASL_fg*, real *)); + extern void x1known ANSI((ASL*, real*, fint*)); +#ifdef __cplusplus + } +#endif + +#define comeval(a,b) comeval_ASL((ASL_fg*)asl,a,b) +#define com1eval(a,b) com1eval_ASL((ASL_fg*)asl,a,b) +#define funnelset(a) funnelset_ASL((ASL_fg*)asl,a) + +#define cexps asl->I.cexps_ +#define cexps1 asl->I.cexps1_ +#define con_de asl->I.con_de_ +#define f_b asl->I.f_b_ +#define f_c asl->I.f_c_ +#define f_o asl->I.f_o_ +#define lcon_de asl->I.lcon_de_ +#define obj_de asl->I.obj_de_ +#define var_e asl->I.var_e_ +#define var_ex asl->I.var_ex_ +#define var_ex1 asl->I.var_ex1_ + +#undef f_OPNUM +#define f_OPNUM (efunc*)f_OPNUM_ASL + +#endif /* NLP_H_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/nlp2.h b/thirdparty/linux/include/coin/ThirdParty/nlp2.h new file mode 100644 index 0000000..ceefe2b --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/nlp2.h @@ -0,0 +1,342 @@ +/**************************************************************** +Copyright (C) 1997-1998, 2000-2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +/* Variant of nlp.h for Hessian times vector computations. */ + +#ifndef NLP_H2_included +#define NLP_H2_included + +#ifndef ASL_included +#include "asl.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +typedef struct argpair2 argpair2; +typedef struct cde2 cde2; +typedef struct cexp2 cexp2; +typedef struct cexp21 cexp21; +typedef struct de2 de2; +typedef union ei2 ei2; +typedef struct expr2 expr2; +typedef struct expr2_f expr2_f; +typedef struct expr2_h expr2_h; +typedef struct expr2_if expr2_if; +typedef struct expr2_v expr2_v; +typedef struct expr2_va expr2_va; +typedef struct funnel2 funnel2; +typedef struct hes_fun hes_fun; +typedef struct list2 list2; +typedef union uir uir; + +typedef real efunc2 ANSI((expr2* A_ASL)); +typedef char *sfunc ANSI((expr2* A_ASL)); + + union +uir { + int i; + real r; + }; + + union +ei2 { + expr2 *e; + expr2 **ep; + expr2_if*eif; + expr_n *en; + expr2_v *ev; + int i; + plterm *p; + de2 *d; + real *rp; + derp *D; + cexp2 *ce; + }; + + struct +expr2 { + efunc2 *op; + int a; /* adjoint index (for gradient computation) */ + expr2 *fwd, *bak; + uir dO; /* deriv of op w.r.t. t in x + t*p */ + real aO; /* adjoint (in Hv computation) of op */ + real adO; /* adjoint (in Hv computation) of dO */ + real dL; /* deriv of op w.r.t. left operand */ + ei2 L, R; /* left and right operands */ + real dR; /* deriv of op w.r.t. right operand */ + real dL2; /* second partial w.r.t. L, L */ + real dLR; /* second partial w.r.t. L, R */ + real dR2; /* second partial w.r.t. R, R */ + }; + + struct +expr2_v { + efunc2 *op; + int a; + expr2 *fwd, *bak; + uir dO; + real aO, adO; + real v; + }; + + struct +expr2_if { + efunc2 *op; + int a; + expr2 *fwd, *bak; + uir dO; + real aO, adO; + expr2 *val, *vale, *valf, *e, *T, *Te, *Tf, *F, *Fe, *Ff; + derp *D, *dT, *dF, *d0; + ei2 Tv, Fv; + expr2_if *next, *next2; + derp *dTlast; + }; + + struct +expr2_va { + efunc2 *op; + int a; + expr2 *fwd, *bak; + uir dO; + real aO, adO; + expr2 *val, *vale, *valf; + ei2 L, R; + expr2_va *next, *next2; + derp *d0; + }; + + struct +cde2 { + expr2 *e, *ee, *ef; + derp *d; + int zaplen; + int com11, n_com1; + }; + + struct +de2 { /* for varargs */ + expr2 *e, *ee, *ef; + derp *d; + ei2 dv; + derp *dlast; /* for sputhes setup */ + }; + + struct +list2 { + list2 *next; + ei2 item; + }; + + struct +cexp21 { + expr2 *e, *ee, *ef; + linpart *L; + int nlin; + }; + + struct +cexp2 { + expr2 *e, *ee, *ef; + linpart *L; + int nlin; + funnel2 *funneled; + list2 *cref; + ei2 z; + int zlen; + derp *d; + int *vref; + hes_fun *hfun; + }; + + struct +funnel2 { + funnel2 *next; + cexp2 *ce; + cde2 fcde; + derp *fulld; + cplist *cl; + }; + + struct +argpair2 { + expr2 *e; + union { + char **s; + real *v; + } u; + }; + + struct +expr2_f { + efunc2 *op; + int a; + expr2 *fwd, *bak; + uir dO; + real aO, adO; + func_info *fi; + arglist *al; + argpair2 *ap, *ape, *sap, *sape; + argpair2 *da; /* differentiable args -- nonconstant */ + argpair2 *dae; + real **fh; /* Hessian info */ + expr2 *args[1]; + }; + + struct +expr2_h { + efunc2 *op; + int a; + char sym[1]; + }; + + typedef struct +Edag2info { + cde2 *con2_de_; /* constraint deriv. and expr. info */ + cde2 *lcon2_de_; /* logical constraints */ + cde2 *obj2_de_; /* objective deriv. and expr. info */ + expr2_v *var2_e_; /* variable values (and related items) */ + + /* stuff for "defined" variables */ + funnel2 *f2_b_; + funnel2 *f2_c_; + funnel2 *f2_o_; + expr2_v *var2_ex_, + *var2_ex1_; + cexp2 *cexps2_, *cexpsc_, *cexpso_, *cexpse_; + cexp21 *cexps21_; + hes_fun *hesthread; + char *c_class; /* class of each constraint: */ + /* 0 = constant */ + /* 1 = linear */ + /* 2 = quadratic */ + /* 3 = general nonlinear */ + char *o_class; /* class of each objective */ + char *v_class; /* class of each defined variable */ + int c_class_max; /* max of c_class values */ + int o_class_max; /* max of o_class values */ + /* The above are only computed if requested */ + /* by the ASL_find_c_class and */ + /* ASL_find_o_class bits of the flags arg */ + /* to pfgh_read() and pfg_read() */ + int x0kind_init; + } Edag2info; + + typedef struct +ASL_fgh { + Edagpars p; + Edaginfo i; + Edag2info I; + } ASL_fgh; + + extern efunc2 *r2_ops_ASL[]; + extern void com21eval_ASL ANSI((ASL_fgh*, int, int)); + extern void com2eval_ASL ANSI((ASL_fgh*, int, int)); + extern void fun2set_ASL ANSI((ASL_fgh*, funnel2 *)); +#ifdef __cplusplus + } +#endif + +#ifndef SKIP_NL2_DEFINES +extern efunc2 f2_OPVARVAL_ASL; + +#define cexpsc asl->I.cexpsc_ +#define cexpse asl->I.cexpse_ +#define cexpso asl->I.cexpso_ +#define cexps1 asl->I.cexps21_ +#define cexps asl->I.cexps2_ +#define con_de asl->I.con2_de_ +#define f_b asl->I.f2_b_ +#define f_c asl->I.f2_c_ +#define f_o asl->I.f2_o_ +#define lcon_de asl->I.lcon2_de_ +#define obj_de asl->I.obj2_de_ +#define var_e asl->I.var2_e_ +#define var_ex1 asl->I.var2_ex1_ +#define var_ex asl->I.var2_ex_ + +#define argpair argpair2 +#define cde cde2 +#define cexp cexp2 +#define cexp1 cexp21 +#define de de2 +#define ei ei2 +#define expr expr2 +#define expr_f expr2_f +#define expr_h expr2_h +#define expr_if expr2_if +#define expr_v expr2_v +#define expr_va expr2_va +#define funnel funnel2 +#define list list2 + +#define com1eval com21eval_ASL +#define comeval com2eval_ASL +#define funnelset fun2set_ASL +#undef r_ops +#define r_ops r2_ops_ASL + +#ifndef PSHVREAD +#define f_OPIFSYM f2_IFSYM_ASL +#define f_OPPLTERM f2_PLTERM_ASL +#define f_OPFUNCALL f2_FUNCALL_ASL +#define f_OP1POW f2_1POW_ASL +#define f_OP2POW f2_2POW_ASL +#define f_OPCPOW f2_CPOW_ASL +#define f_OPPLUS f2_PLUS_ASL +#define f_OPSUMLIST f2_SUMLIST_ASL +#define f_OPHOL f2_HOL_ASL +#define f_OPPOW f2_POW_ASL +#define f_OPVARVAL f2_VARVAL_ASL +#endif + +/* operation classes (for H*v computation) */ + +#define Hv_binaryR 0 +#define Hv_binaryLR 1 +#define Hv_unary 2 +#define Hv_vararg 3 +#define Hv_if 4 +#define Hv_plterm 5 +#define Hv_sumlist 6 +#define Hv_func 7 +#define Hv_negate 8 +#define Hv_plusR 9 +#define Hv_plusL 10 +#define Hv_plusLR 11 +#define Hv_minusR 12 +#define Hv_minusLR 13 +#define Hv_timesR 14 +#define Hv_timesL 15 +#define Hv_timesLR 16 + +/* treat if as vararg, minusL as plusL, binaryL as unary */ + +#endif /* SKIP_NL2_DEFINES */ + +#undef f_OPNUM +#define f_OPNUM (efunc2*)f_OPNUM_ASL +#endif /* NLP_H2_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/opcode.hd b/thirdparty/linux/include/coin/ThirdParty/opcode.hd new file mode 100644 index 0000000..899972c --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/opcode.hd @@ -0,0 +1,70 @@ +#define OPPLUS 0 +#define OPMINUS 1 +#define OPMULT 2 +#define OPDIV 3 +#define OPREM 4 +#define OPPOW 5 +#define OPLESS 6 +#define MINLIST 11 +#define MAXLIST 12 +#define FLOOR 13 +#define CEIL 14 +#define ABS 15 +#define OPUMINUS 16 +#define OPOR 20 +#define OPAND 21 +#define LT 22 +#define LE 23 +#define EQ 24 +#define GE 28 +#define GT 29 +#define NE 30 +#define OPNOT 34 +#define OPIFnl 35 +#define OP_tanh 37 +#define OP_tan 38 +#define OP_sqrt 39 +#define OP_sinh 40 +#define OP_sin 41 +#define OP_log10 42 +#define OP_log 43 +#define OP_exp 44 +#define OP_cosh 45 +#define OP_cos 46 +#define OP_atanh 47 +#define OP_atan2 48 +#define OP_atan 49 +#define OP_asinh 50 +#define OP_asin 51 +#define OP_acosh 52 +#define OP_acos 53 +#define OPSUMLIST 54 +#define OPintDIV 55 +#define OPprecision 56 +#define OPround 57 +#define OPtrunc 58 +#define OPCOUNT 59 +#define OPNUMBEROF 60 +#define OPNUMBEROFs 61 +#define OPATLEAST 62 +#define OPATMOST 63 +#define OPPLTERM 64 +#define OPIFSYM 65 +#define OPEXACTLY 66 +#define OPNOTATLEAST 67 +#define OPNOTATMOST 68 +#define OPNOTEXACTLY 69 +#define ANDLIST 70 +#define ORLIST 71 +#define OPIMPELSE 72 +#define OP_IFF 73 +#define OPALLDIFF 74 +#define OPSOMESAME 75 +#define OP1POW 76 +#define OP2POW 77 +#define OPCPOW 78 +#define OPFUNCALL 79 +#define OPNUM 80 +#define OPHOL 81 +#define OPVARVAL 82 +#define N_OPS 83 diff --git a/thirdparty/linux/include/coin/ThirdParty/psinfo.h b/thirdparty/linux/include/coin/ThirdParty/psinfo.h new file mode 100644 index 0000000..e91eda1 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/psinfo.h @@ -0,0 +1,337 @@ +/**************************************************************** +Copyright (C) 1997, 1998, 2001 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +#ifdef PSHVREAD +#ifndef PSINFO_H2_included +#define PSINFO_H2_included +#undef PSINFO_H_included +#ifndef NLP_H2_included +#include "nlp2.h" +#endif +#define cde cde2 +#define la_ref la_ref2 +#define linarg linarg2 +#define range range2 +#define rhead rhead2 +#define psb_elem psb_elem2 +#define psg_elem psg_elem2 +#define ps_func ps_func2 +#define dv_info dv_info2 +#define split_ce split_ce2 +#define ps_info ps_info2 +#define psinfo psinfo2 +#endif /* PSINFO_H2_included */ +#else /* PSHVREAD */ +#ifndef PSINFO_H1_included +#define PSINFO_H1_included +#undef PSINFO_H_included +#ifndef NLP_H_included +#include "nlp.h" +#endif +#endif +#endif /* PSHVREAD */ +#ifndef PSINFO_H_included +#define PSINFO_H_included + + typedef struct la_ref la_ref; + typedef struct linarg linarg; + typedef struct range range; + + struct +la_ref { + la_ref *next; + expr **ep; + real c; + real scale; + }; + + struct +linarg { + linarg *hnext; /* for hashing */ + linarg *tnext; /* next linear argument to this term */ + linarg *lnext; /* for adjusting v->op */ + la_ref *refs; /* references */ + expr_v *v; /* variable that evaluates this linear term */ + ograd *nz; /* the nonzeros */ + int nnz; /* number of nonzeros (to help hashing) */ + int termno; /* helps tell whether new to this term */ + }; + + typedef struct +rhead { + range *next, *prev; + } rhead; + +#ifndef PSINFO_H0_included +#define MBLK_KMAX 30 +#endif /* PSINFO_H0_included */ + + typedef struct psb_elem psb_elem; + + struct +range { + rhead rlist; /* list of all ranges */ + range *hnext; /* for hashing U */ + range *hunext; /* for hashing unit vectors */ + int n; /* rows in U */ + int nv; /* variables involved in U */ + int nintv; /* number of internal variables (non-unit */ + /* rows in U) */ + int lasttermno; /* termno of prev. use in this term */ + /* -1 ==> not yet used in this constr or obj. */ + /* Set to least variable (1st = 0) in this */ + /* range at the end of psedread. */ + int lastgroupno; /* groupno at last use of this term */ + unsigned int chksum; /* for hashing */ + psb_elem *refs; /* constraints and objectives with this range */ + int *ui; /* unit vectors defining this range */ + /* (for n >= nv) */ + linarg **lap; /* nonzeros in U */ + int *cei; /* common expressions: union over refs */ + real *hest; /* nonzero ==> internal Hessian triangle */ + /* computed by hvpinit */ + }; + + struct +psb_elem { /* basic element of partially-separable func */ + psb_elem *next; /* for range.refs */ + range *U; + int *ce; /* common exprs if nonzero: ce[i], 1 <= i <= ce[0] */ + cde D; /* derivative and expr info */ + int conno; /* constraint no. (if >= 0) or -2 - obj no. */ + int termno; + int groupno; + }; + + typedef struct +psg_elem { /* group element details of partially-separable func */ + real g0; /* constant term */ + real g1; /* first deriv of g */ + real g2; /* 2nd deriv of g */ + real scale; /* temporary(?!!) until we introduce unary OPSCALE */ + expr_n esum; /* esum.v = result of summing g0, E and L */ + expr *g; /* unary operator */ + expr *ge; /* "last" unary operator */ + ograd *og; /* first deriv = g1 times og */ + int nlin; /* number of linear terms */ + int ns; /* number of nonlinear terms */ + linpart *L; /* the linear terms */ + psb_elem *E; /* the nonlinear terms */ + } psg_elem; + + typedef struct +ps_func { + int nb; /* number of basic terms */ + int ng; /* number of group terms */ + int nxval; /* for psgcomp */ + psb_elem *b; /* the basic terms */ + psg_elem *g; /* the group terms */ + } ps_func; + + typedef struct +dv_info { /* defined variable info */ + ograd *ll; /* list of linear defined vars referenced */ + linarg **nl; /* nonlinear part, followed by 0 */ + real scale; /* scale factor for linear term */ + linarg *lt; /* linear term of nonlinear defined var */ + } dv_info; + + typedef struct +split_ce { + range *r; + int *ce; /* common expressions */ + } split_ce; + +#ifdef PSHVREAD + + struct +hes_fun { + hes_fun *hfthread; + cexp2 *c; + real *grdhes; + ograd *og; + expr_v **vp; + int n; + }; + + typedef struct Hesoprod Hesoprod; + struct +Hesoprod { + Hesoprod *next; + ograd *left, *right; + real coef; + }; + + typedef struct uHeswork uHeswork; + struct +uHeswork { + uHeswork *next; + int k; + range *r; + int *ui, *uie; + ograd *ogp[1]; /* scratch of length r->n */ + }; + + typedef struct Umultinfo Umultinfo; + struct +Umultinfo { + Umultinfo *next; + ograd *og, *og0; + expr_v *v; + int i; + }; + + typedef struct Ihinfo Ihinfo; + struct +Ihinfo { + Ihinfo *next; /* for chaining ihinfo's with positive count */ + range *r; /* list, on prev, of ranges with this ihd */ + real *hest; /* hest memory to free */ + int ihd; /* internal Hessian dimension, min(n,nv) */ + int k; /* htcl(nr*(ihd*(ihd+1)/2)*sizeof(real)) */ + int nr; /* number of ranges with this ihd */ + }; + +#endif /* PSHVREAD */ + + typedef struct +ps_info { + Long merge; /* for noadjust = 1 */ + ps_func *cps; + ps_func *ops; + dv_info *dv; + expr_v **vp; /* for values of common variables */ + rhead rlist; + linarg *lalist; /* all linargs */ + int *dvsp0; /* dvsp0[i] = subscript of first var into which */ + /* cexp i was split, 0 <= i <= ncom */ + int nc1; /* common expressions for just this function */ + int ns0; /* initial number of elements */ + int ncom; /* number of common expressions before splitting */ + int ndupdt; /* duplicate linear terms in different terms */ + int ndupst; /* duplicate linear terms in the same term */ + int nlttot; /* total number of distinct linear terms */ + int ndvspcand; /* # of defined variable candidates for splitting */ + int ndvsplit; /* number of defined variables actually split */ + int ndvspin; /* number of incoming terms from split defined vars */ + int ndvspout; /* number of terms from split defined variables */ + int max_var1_; /* used in psedread and pshvread */ + int nv0_; /* used in psedread and pshvread */ + +#ifdef PSHVREAD + /* Stuff for partially separable Hessian computations... */ + /* These arrays are allocated and zero-initialized by hes_setup, */ + /* which also supplies the cei field to ranges. */ + + range **rtodo; /* rtodo[i] = ranges first incident on col i */ + uHeswork **utodo; /* unit ranges affecting this col */ + Hesoprod **otodo;/* otodo[i] = contributions to col i dispatched */ + /* by previous rtodo entries */ + Hesoprod *hop_free; + real *dOscratch;/* length = nmax (below) */ + int *iOscratch; /* length = nmax */ + Ihinfo *ihi; + Ihinfo *ihi1; /* first with positive count */ + int hes_setup_called; + int nmax; /* max{r in ranges} r->n */ + int ihdcur; /* Current max internal Hessian dimension, */ + /* set by hvpinit. */ + int ihdmax; /* max possible ihd */ + int ihdmin; /* min possible ihd > 0 and <= ihdmax, or 0 */ + int khesoprod; /* used in new_Hesoprod in sputhes.c */ + int pshv_g1; /* whether pshv_prod should multiply by g1 */ + int linmultr; /* linear common terms used in more than one range */ + int linhesfun; /* linear common terms in Hessian funnels */ + int nlmultr; /* nonlin common terms used in more than one range */ + int nlhesfun; /* nonlin common terms in Hessian funnels */ + int ncongroups; /* # of groups in constraints */ + int nobjgroups; /* # of groups in objectives */ + int nhvprod; /* # of Hessian-vector products at this Hessian */ + int npsgcomp; /* Has psgcomp been called? For sphes_setup. */ + expr_va *valist; /* for sphes_setup */ + expr_if *iflist; /* for sphes_setup */ + int *zlsave; /* for S->_zl */ + real *oyow; /* for xpsg_check */ + int onobj; /* for xpsg_check */ + int onxval; /* for xpsg_check */ + int nynz; /* for xpsg_check */ + int ndhmax; /* set by hvpinit_ASL */ +#endif /* PSHVREAD */ + split_ce *Split_ce; /* for sphes_setup */ + } ps_info; + +#ifdef PSHVREAD + + typedef struct +ASL_pfgh { + Edagpars p; + Edaginfo i; + Char *mblk_free[MBLK_KMAX]; + Edag2info I; + ps_info2 P; + } ASL_pfgh; + +#else + + typedef struct +ASL_pfg { + Edagpars p; + Edaginfo i; + Char *mblk_free[MBLK_KMAX]; + Edag1info I; + ps_info P; + } ASL_pfg; + +#endif /* PSHVREAD */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef PSINFO_H0_included +#define PSINFO_H0_included +typedef unsigned Long Ulong; + +#endif /* PSINFO_H0_included */ +#ifdef PSHVREAD + extern void duthes_ASL(ASL*, real *H, int nobj, real *ow, real *y); + extern void fullhes_ASL(ASL*, real*H, fint LH, int nobj, real*ow, real*y); + extern void hvpinit_ASL(ASL*, int ndhmax, int nobj, real *ow, real *y); + extern void ihd_clear_ASL(ASL_pfgh*); + extern ASL_pfgh *pscheck_ASL(ASL*, const char*); + extern void pshv_prod_ASL(ASL_pfgh*, range*r, int nobj, real*ow, real*y); + extern fint sphes_setup_ASL(ASL*, SputInfo**, int nobj, int ow, int y, int ul); + extern void sphes_ASL(ASL*, SputInfo**, real *H, int nobj, real*ow, real *y); + extern void xpsg_check_ASL(ASL_pfgh*, int nobj, real *ow, real *y); +#else /* PSHVREAD */ + extern void xp1known_ASL(ASL*, real*, fint*); +#endif /* PSHVREAD */ + +#ifdef __cplusplus + } +#endif + +#define pshv_prod(r,no,ow,y) pshv_prod_ASL(asl,r,no,ow,y) + +#endif /* PSINFO_H_included */ diff --git a/thirdparty/linux/include/coin/ThirdParty/r_opn.hd b/thirdparty/linux/include/coin/ThirdParty/r_opn.hd new file mode 100644 index 0000000..4c4f456 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/r_opn.hd @@ -0,0 +1,16 @@ +#undef f_OPNUM +#define f_OPMULT r_ops[2] +#define f_OPPOW r_ops[5] +#define f_MINLIST r_ops[11] +#define f_MAXLIST r_ops[12] +#define f_ABS r_ops[15] +#define f_OPPLTERM r_ops[64] +#define f_OPIFSYM r_ops[65] +#define f_OP1POW r_ops[76] +#define f_OP2POW r_ops[77] +#define f_OPCPOW r_ops[78] +#define f_OPFUNCALL r_ops[79] +#define f_OPNUM r_ops[80] +#define f_OPHOL r_ops[81] +#define f_OPVARVAL r_ops[82] +#define N_OPS 83 diff --git a/thirdparty/linux/include/coin/ThirdParty/stdio1.h b/thirdparty/linux/include/coin/ThirdParty/stdio1.h new file mode 100644 index 0000000..ef2bb63 --- /dev/null +++ b/thirdparty/linux/include/coin/ThirdParty/stdio1.h @@ -0,0 +1,103 @@ +/**************************************************************** +Copyright (C) 1997-1999 Lucent Technologies +All Rights Reserved + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of Lucent or any of its entities +not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. + +LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. +IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER +IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF +THIS SOFTWARE. +****************************************************************/ + +/* stdio1.h -- for using Printf, Fprintf, Sprintf while + * retaining the system-supplied printf, fprintf, sprintf. + */ + +#ifndef STDIO1_H_included +#define STDIO1_H_included +#ifndef STDIO_H_included /* allow suppressing stdio.h */ +#include <stdio.h> /* in case it's already included, */ +#endif /* e.g., by cplex.h */ + +#ifdef KR_headers +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif +#define ANSI(x) () +#include "varargs.h" +#ifndef Char +#define Char char +#endif +#else +#define ANSI(x) x +#include "stdarg.h" +#ifndef Char +#define Char void +#endif +#endif + +#ifndef NO_STDIO1 + +#ifdef __cplusplus +extern "C" { +#endif + +extern int Fprintf ANSI((FILE*, const char*, ...)); +extern int Printf ANSI((const char*, ...)); +extern int Sprintf ANSI((char*, const char*, ...)); +extern int Snprintf ANSI((char*, size_t, const char*, ...)); +extern void Perror ANSI((const char*)); +extern int Vfprintf ANSI((FILE*, const char*, va_list)); +extern int Vsprintf ANSI((char*, const char*, va_list)); +extern int Vsnprintf ANSI((char*, size_t, const char*, va_list)); + +#ifdef PF_BUF +extern FILE *stderr_ASL; +extern void (*pfbuf_print_ASL) ANSI((char*)); +extern char *pfbuf_ASL; +extern void fflush_ASL ANSI((FILE*)); +#ifdef fflush +#define old_fflush_ASL fflush +#undef fflush +#endif +#define fflush fflush_ASL +#endif + +#ifdef __cplusplus + } +#endif + +#undef printf +#undef fprintf +#undef sprintf +#undef perror +#undef vfprintf +#undef vsprintf +#define printf Printf +#define fprintf Fprintf +#undef snprintf /* for MacOSX */ +#undef vsnprintf /* for MacOSX */ +#define snprintf Snprintf +#define sprintf Sprintf +#define perror Perror +#define vfprintf Vfprintf +#define vsnprintf Vsnprintf +#define vsprintf Vsprintf + +#endif /* NO_STDIO1 */ + +#endif /* STDIO1_H_included */ diff --git a/thirdparty/linux/include/coin/amd.h b/thirdparty/linux/include/coin/amd.h new file mode 100644 index 0000000..a38fd31 --- /dev/null +++ b/thirdparty/linux/include/coin/amd.h @@ -0,0 +1,411 @@ +/* ========================================================================= */ +/* === AMD: approximate minimum degree ordering =========================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD Version 2.2, Copyright (c) 2007 by Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: DrTimothyAldenDavis@gmail.com */ +/* ------------------------------------------------------------------------- */ + +/* AMD finds a symmetric ordering P of a matrix A so that the Cholesky + * factorization of P*A*P' has fewer nonzeros and takes less work than the + * Cholesky factorization of A. If A is not symmetric, then it performs its + * ordering on the matrix A+A'. Two sets of user-callable routines are + * provided, one for int integers and the other for SuiteSparse_long integers. + * + * The method is based on the approximate minimum degree algorithm, discussed + * in Amestoy, Davis, and Duff, "An approximate degree ordering algorithm", + * SIAM Journal of Matrix Analysis and Applications, vol. 17, no. 4, pp. + * 886-905, 1996. This package can perform both the AMD ordering (with + * aggressive absorption), and the AMDBAR ordering (without aggressive + * absorption) discussed in the above paper. This package differs from the + * Fortran codes discussed in the paper: + * + * (1) it can ignore "dense" rows and columns, leading to faster run times + * (2) it computes the ordering of A+A' if A is not symmetric + * (3) it is followed by a depth-first post-ordering of the assembly tree + * (or supernodal elimination tree) + * + * For historical reasons, the Fortran versions, amd.f and amdbar.f, have + * been left (nearly) unchanged. They compute the identical ordering as + * described in the above paper. + */ + +#ifndef AMD_H +#define AMD_H + +/* make it easy for C++ programs to include AMD */ +#ifdef __cplusplus +extern "C" { +#endif + +/* get the definition of size_t: */ +#include <stddef.h> + +#include "SuiteSparse_config.h" + +int amd_order /* returns AMD_OK, AMD_OK_BUT_JUMBLED, + * AMD_INVALID, or AMD_OUT_OF_MEMORY */ +( + int n, /* A is n-by-n. n must be >= 0. */ + const int Ap [ ], /* column pointers for A, of size n+1 */ + const int Ai [ ], /* row indices of A, of size nz = Ap [n] */ + int P [ ], /* output permutation, of size n */ + double Control [ ], /* input Control settings, of size AMD_CONTROL */ + double Info [ ] /* output Info statistics, of size AMD_INFO */ +) ; + +SuiteSparse_long amd_l_order /* see above for description of arguments */ +( + SuiteSparse_long n, + const SuiteSparse_long Ap [ ], + const SuiteSparse_long Ai [ ], + SuiteSparse_long P [ ], + double Control [ ], + double Info [ ] +) ; + +/* Input arguments (not modified): + * + * n: the matrix A is n-by-n. + * Ap: an int/SuiteSparse_long array of size n+1, containing column + * pointers of A. + * Ai: an int/SuiteSparse_long array of size nz, containing the row + * indices of A, where nz = Ap [n]. + * Control: a double array of size AMD_CONTROL, containing control + * parameters. Defaults are used if Control is NULL. + * + * Output arguments (not defined on input): + * + * P: an int/SuiteSparse_long array of size n, containing the output + * permutation. If row i is the kth pivot row, then P [k] = i. In + * MATLAB notation, the reordered matrix is A (P,P). + * Info: a double array of size AMD_INFO, containing statistical + * information. Ignored if Info is NULL. + * + * On input, the matrix A is stored in column-oriented form. The row indices + * of nonzero entries in column j are stored in Ai [Ap [j] ... Ap [j+1]-1]. + * + * If the row indices appear in ascending order in each column, and there + * are no duplicate entries, then amd_order is slightly more efficient in + * terms of time and memory usage. If this condition does not hold, a copy + * of the matrix is created (where these conditions do hold), and the copy is + * ordered. This feature is new to v2.0 (v1.2 and earlier required this + * condition to hold for the input matrix). + * + * Row indices must be in the range 0 to + * n-1. Ap [0] must be zero, and thus nz = Ap [n] is the number of nonzeros + * in A. The array Ap is of size n+1, and the array Ai is of size nz = Ap [n]. + * The matrix does not need to be symmetric, and the diagonal does not need to + * be present (if diagonal entries are present, they are ignored except for + * the output statistic Info [AMD_NZDIAG]). The arrays Ai and Ap are not + * modified. This form of the Ap and Ai arrays to represent the nonzero + * pattern of the matrix A is the same as that used internally by MATLAB. + * If you wish to use a more flexible input structure, please see the + * umfpack_*_triplet_to_col routines in the UMFPACK package, at + * http://www.suitesparse.com. + * + * Restrictions: n >= 0. Ap [0] = 0. Ap [j] <= Ap [j+1] for all j in the + * range 0 to n-1. nz = Ap [n] >= 0. Ai [0..nz-1] must be in the range 0 + * to n-1. Finally, Ai, Ap, and P must not be NULL. If any of these + * restrictions are not met, AMD returns AMD_INVALID. + * + * AMD returns: + * + * AMD_OK if the matrix is valid and sufficient memory can be allocated to + * perform the ordering. + * + * AMD_OUT_OF_MEMORY if not enough memory can be allocated. + * + * AMD_INVALID if the input arguments n, Ap, Ai are invalid, or if P is + * NULL. + * + * AMD_OK_BUT_JUMBLED if the matrix had unsorted columns, and/or duplicate + * entries, but was otherwise valid. + * + * The AMD routine first forms the pattern of the matrix A+A', and then + * computes a fill-reducing ordering, P. If P [k] = i, then row/column i of + * the original is the kth pivotal row. In MATLAB notation, the permuted + * matrix is A (P,P), except that 0-based indexing is used instead of the + * 1-based indexing in MATLAB. + * + * The Control array is used to set various parameters for AMD. If a NULL + * pointer is passed, default values are used. The Control array is not + * modified. + * + * Control [AMD_DENSE]: controls the threshold for "dense" rows/columns. + * A dense row/column in A+A' can cause AMD to spend a lot of time in + * ordering the matrix. If Control [AMD_DENSE] >= 0, rows/columns + * with more than Control [AMD_DENSE] * sqrt (n) entries are ignored + * during the ordering, and placed last in the output order. The + * default value of Control [AMD_DENSE] is 10. If negative, no + * rows/columns are treated as "dense". Rows/columns with 16 or + * fewer off-diagonal entries are never considered "dense". + * + * Control [AMD_AGGRESSIVE]: controls whether or not to use aggressive + * absorption, in which a prior element is absorbed into the current + * element if is a subset of the current element, even if it is not + * adjacent to the current pivot element (refer to Amestoy, Davis, + * & Duff, 1996, for more details). The default value is nonzero, + * which means to perform aggressive absorption. This nearly always + * leads to a better ordering (because the approximate degrees are + * more accurate) and a lower execution time. There are cases where + * it can lead to a slightly worse ordering, however. To turn it off, + * set Control [AMD_AGGRESSIVE] to 0. + * + * Control [2..4] are not used in the current version, but may be used in + * future versions. + * + * The Info array provides statistics about the ordering on output. If it is + * not present, the statistics are not returned. This is not an error + * condition. + * + * Info [AMD_STATUS]: the return value of AMD, either AMD_OK, + * AMD_OK_BUT_JUMBLED, AMD_OUT_OF_MEMORY, or AMD_INVALID. + * + * Info [AMD_N]: n, the size of the input matrix + * + * Info [AMD_NZ]: the number of nonzeros in A, nz = Ap [n] + * + * Info [AMD_SYMMETRY]: the symmetry of the matrix A. It is the number + * of "matched" off-diagonal entries divided by the total number of + * off-diagonal entries. An entry A(i,j) is matched if A(j,i) is also + * an entry, for any pair (i,j) for which i != j. In MATLAB notation, + * S = spones (A) ; + * B = tril (S, -1) + triu (S, 1) ; + * symmetry = nnz (B & B') / nnz (B) ; + * + * Info [AMD_NZDIAG]: the number of entries on the diagonal of A. + * + * Info [AMD_NZ_A_PLUS_AT]: the number of nonzeros in A+A', excluding the + * diagonal. If A is perfectly symmetric (Info [AMD_SYMMETRY] = 1) + * with a fully nonzero diagonal, then Info [AMD_NZ_A_PLUS_AT] = nz-n + * (the smallest possible value). If A is perfectly unsymmetric + * (Info [AMD_SYMMETRY] = 0, for an upper triangular matrix, for + * example) with no diagonal, then Info [AMD_NZ_A_PLUS_AT] = 2*nz + * (the largest possible value). + * + * Info [AMD_NDENSE]: the number of "dense" rows/columns of A+A' that were + * removed from A prior to ordering. These are placed last in the + * output order P. + * + * Info [AMD_MEMORY]: the amount of memory used by AMD, in bytes. In the + * current version, this is 1.2 * Info [AMD_NZ_A_PLUS_AT] + 9*n + * times the size of an integer. This is at most 2.4nz + 9n. This + * excludes the size of the input arguments Ai, Ap, and P, which have + * a total size of nz + 2*n + 1 integers. + * + * Info [AMD_NCMPA]: the number of garbage collections performed. + * + * Info [AMD_LNZ]: the number of nonzeros in L (excluding the diagonal). + * This is a slight upper bound because mass elimination is combined + * with the approximate degree update. It is a rough upper bound if + * there are many "dense" rows/columns. The rest of the statistics, + * below, are also slight or rough upper bounds, for the same reasons. + * The post-ordering of the assembly tree might also not exactly + * correspond to a true elimination tree postordering. + * + * Info [AMD_NDIV]: the number of divide operations for a subsequent LDL' + * or LU factorization of the permuted matrix A (P,P). + * + * Info [AMD_NMULTSUBS_LDL]: the number of multiply-subtract pairs for a + * subsequent LDL' factorization of A (P,P). + * + * Info [AMD_NMULTSUBS_LU]: the number of multiply-subtract pairs for a + * subsequent LU factorization of A (P,P), assuming that no numerical + * pivoting is required. + * + * Info [AMD_DMAX]: the maximum number of nonzeros in any column of L, + * including the diagonal. + * + * Info [14..19] are not used in the current version, but may be used in + * future versions. + */ + +/* ------------------------------------------------------------------------- */ +/* direct interface to AMD */ +/* ------------------------------------------------------------------------- */ + +/* amd_2 is the primary AMD ordering routine. It is not meant to be + * user-callable because of its restrictive inputs and because it destroys + * the user's input matrix. It does not check its inputs for errors, either. + * However, if you can work with these restrictions it can be faster than + * amd_order and use less memory (assuming that you can create your own copy + * of the matrix for AMD to destroy). Refer to AMD/Source/amd_2.c for a + * description of each parameter. */ + +void amd_2 +( + int n, + int Pe [ ], + int Iw [ ], + int Len [ ], + int iwlen, + int pfree, + int Nv [ ], + int Next [ ], + int Last [ ], + int Head [ ], + int Elen [ ], + int Degree [ ], + int W [ ], + double Control [ ], + double Info [ ] +) ; + +void amd_l2 +( + SuiteSparse_long n, + SuiteSparse_long Pe [ ], + SuiteSparse_long Iw [ ], + SuiteSparse_long Len [ ], + SuiteSparse_long iwlen, + SuiteSparse_long pfree, + SuiteSparse_long Nv [ ], + SuiteSparse_long Next [ ], + SuiteSparse_long Last [ ], + SuiteSparse_long Head [ ], + SuiteSparse_long Elen [ ], + SuiteSparse_long Degree [ ], + SuiteSparse_long W [ ], + double Control [ ], + double Info [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* amd_valid */ +/* ------------------------------------------------------------------------- */ + +/* Returns AMD_OK or AMD_OK_BUT_JUMBLED if the matrix is valid as input to + * amd_order; the latter is returned if the matrix has unsorted and/or + * duplicate row indices in one or more columns. Returns AMD_INVALID if the + * matrix cannot be passed to amd_order. For amd_order, the matrix must also + * be square. The first two arguments are the number of rows and the number + * of columns of the matrix. For its use in AMD, these must both equal n. + * + * NOTE: this routine returned TRUE/FALSE in v1.2 and earlier. + */ + +int amd_valid +( + int n_row, /* # of rows */ + int n_col, /* # of columns */ + const int Ap [ ], /* column pointers, of size n_col+1 */ + const int Ai [ ] /* row indices, of size Ap [n_col] */ +) ; + +SuiteSparse_long amd_l_valid +( + SuiteSparse_long n_row, + SuiteSparse_long n_col, + const SuiteSparse_long Ap [ ], + const SuiteSparse_long Ai [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* AMD memory manager and printf routines */ +/* ------------------------------------------------------------------------- */ + +/* The user can redefine these to change the malloc, free, and printf routines + * that AMD uses. */ + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN void *(*amd_malloc) (size_t) ; /* pointer to malloc */ +EXTERN void (*amd_free) (void *) ; /* pointer to free */ +EXTERN void *(*amd_realloc) (void *, size_t) ; /* pointer to realloc */ +EXTERN void *(*amd_calloc) (size_t, size_t) ; /* pointer to calloc */ +EXTERN int (*amd_printf) (const char *, ...) ; /* pointer to printf */ + +/* ------------------------------------------------------------------------- */ +/* AMD Control and Info arrays */ +/* ------------------------------------------------------------------------- */ + +/* amd_defaults: sets the default control settings */ +void amd_defaults (double Control [ ]) ; +void amd_l_defaults (double Control [ ]) ; + +/* amd_control: prints the control settings */ +void amd_control (double Control [ ]) ; +void amd_l_control (double Control [ ]) ; + +/* amd_info: prints the statistics */ +void amd_info (double Info [ ]) ; +void amd_l_info (double Info [ ]) ; + +#define AMD_CONTROL 5 /* size of Control array */ +#define AMD_INFO 20 /* size of Info array */ + +/* contents of Control */ +#define AMD_DENSE 0 /* "dense" if degree > Control [0] * sqrt (n) */ +#define AMD_AGGRESSIVE 1 /* do aggressive absorption if Control [1] != 0 */ + +/* default Control settings */ +#define AMD_DEFAULT_DENSE 10.0 /* default "dense" degree 10*sqrt(n) */ +#define AMD_DEFAULT_AGGRESSIVE 1 /* do aggressive absorption by default */ + +/* contents of Info */ +#define AMD_STATUS 0 /* return value of amd_order and amd_l_order */ +#define AMD_N 1 /* A is n-by-n */ +#define AMD_NZ 2 /* number of nonzeros in A */ +#define AMD_SYMMETRY 3 /* symmetry of pattern (1 is sym., 0 is unsym.) */ +#define AMD_NZDIAG 4 /* # of entries on diagonal */ +#define AMD_NZ_A_PLUS_AT 5 /* nz in A+A' */ +#define AMD_NDENSE 6 /* number of "dense" rows/columns in A */ +#define AMD_MEMORY 7 /* amount of memory used by AMD */ +#define AMD_NCMPA 8 /* number of garbage collections in AMD */ +#define AMD_LNZ 9 /* approx. nz in L, excluding the diagonal */ +#define AMD_NDIV 10 /* number of fl. point divides for LU and LDL' */ +#define AMD_NMULTSUBS_LDL 11 /* number of fl. point (*,-) pairs for LDL' */ +#define AMD_NMULTSUBS_LU 12 /* number of fl. point (*,-) pairs for LU */ +#define AMD_DMAX 13 /* max nz. in any column of L, incl. diagonal */ + +/* ------------------------------------------------------------------------- */ +/* return values of AMD */ +/* ------------------------------------------------------------------------- */ + +#define AMD_OK 0 /* success */ +#define AMD_OUT_OF_MEMORY -1 /* malloc failed, or problem too large */ +#define AMD_INVALID -2 /* input arguments are not valid */ +#define AMD_OK_BUT_JUMBLED 1 /* input matrix is OK for amd_order, but + * columns were not sorted, and/or duplicate entries were present. AMD had + * to do extra work before ordering the matrix. This is a warning, not an + * error. */ + +/* ========================================================================== */ +/* === AMD version ========================================================== */ +/* ========================================================================== */ + +/* AMD Version 1.2 and later include the following definitions. + * As an example, to test if the version you are using is 1.2 or later: + * + * #ifdef AMD_VERSION + * if (AMD_VERSION >= AMD_VERSION_CODE (1,2)) ... + * #endif + * + * This also works during compile-time: + * + * #if defined(AMD_VERSION) && (AMD_VERSION >= AMD_VERSION_CODE (1,2)) + * printf ("This is version 1.2 or later\n") ; + * #else + * printf ("This is an early version\n") ; + * #endif + * + * Versions 1.1 and earlier of AMD do not include a #define'd version number. + */ + +#define AMD_DATE "Jun 20, 2012" +#define AMD_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define AMD_MAIN_VERSION 2 +#define AMD_SUB_VERSION 3 +#define AMD_SUBSUB_VERSION 1 +#define AMD_VERSION AMD_VERSION_CODE(AMD_MAIN_VERSION,AMD_SUB_VERSION) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/linux/include/coin/amd_internal.h b/thirdparty/linux/include/coin/amd_internal.h new file mode 100644 index 0000000..c5f5493 --- /dev/null +++ b/thirdparty/linux/include/coin/amd_internal.h @@ -0,0 +1,347 @@ +/* ========================================================================= */ +/* === amd_internal.h ====================================================== */ +/* ========================================================================= */ + +/* ------------------------------------------------------------------------- */ +/* AMD, Copyright (c) Timothy A. Davis, */ +/* Patrick R. Amestoy, and Iain S. Duff. See ../README.txt for License. */ +/* email: DrTimothyAldenDavis@gmail.com */ +/* ------------------------------------------------------------------------- */ + +/* This file is for internal use in AMD itself, and does not normally need to + * be included in user code (it is included in UMFPACK, however). All others + * should use amd.h instead. + * + * The following compile-time definitions affect how AMD is compiled. + * + * -DNPRINT + * + * Disable all printing. stdio.h will not be included. Printing can + * be re-enabled at run-time by setting the global pointer amd_printf + * to printf (or mexPrintf for a MATLAB mexFunction). + * + * -DNMALLOC + * + * No memory manager is defined at compile-time. You MUST define the + * function pointers amd_malloc, amd_free, amd_realloc, and + * amd_calloc at run-time for AMD to work properly. + */ + +/* ========================================================================= */ +/* === NDEBUG ============================================================== */ +/* ========================================================================= */ + +/* + * Turning on debugging takes some work (see below). If you do not edit this + * file, then debugging is always turned off, regardless of whether or not + * -DNDEBUG is specified in your compiler options. + * + * If AMD is being compiled as a mexFunction, then MATLAB_MEX_FILE is defined, + * and mxAssert is used instead of assert. If debugging is not enabled, no + * MATLAB include files or functions are used. Thus, the AMD library libamd.a + * can be safely used in either a stand-alone C program or in another + * mexFunction, without any change. + */ + +/* + AMD will be exceedingly slow when running in debug mode. The next three + lines ensure that debugging is turned off. +*/ +#ifndef NDEBUG +#define NDEBUG +#endif + +/* + To enable debugging, uncomment the following line: +#undef NDEBUG +*/ + +/* ------------------------------------------------------------------------- */ +/* ANSI include files */ +/* ------------------------------------------------------------------------- */ + +/* from stdlib.h: size_t, malloc, free, realloc, and calloc */ +#include <stdlib.h> + +#if !defined(NPRINT) || !defined(NDEBUG) +/* from stdio.h: printf. Not included if NPRINT is defined at compile time. + * fopen and fscanf are used when debugging. */ +#include <stdio.h> +#endif + +/* from limits.h: INT_MAX and LONG_MAX */ +#include <limits.h> + +/* from math.h: sqrt */ +#include <math.h> + +/* ------------------------------------------------------------------------- */ +/* MATLAB include files (only if being used in or via MATLAB) */ +/* ------------------------------------------------------------------------- */ + +#ifdef MATLAB_MEX_FILE +#include "matrix.h" +#include "mex.h" +#endif + +/* ------------------------------------------------------------------------- */ +/* basic definitions */ +/* ------------------------------------------------------------------------- */ + +#ifdef FLIP +#undef FLIP +#endif + +#ifdef MAX +#undef MAX +#endif + +#ifdef MIN +#undef MIN +#endif + +#ifdef EMPTY +#undef EMPTY +#endif + +#ifdef GLOBAL +#undef GLOBAL +#endif + +#ifdef PRIVATE +#undef PRIVATE +#endif + +/* FLIP is a "negation about -1", and is used to mark an integer i that is + * normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY + * is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i + * for all integers i. UNFLIP (i) is >= EMPTY. */ +#define EMPTY (-1) +#define FLIP(i) (-(i)-2) +#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i)) + +/* for integer MAX/MIN, or for doubles when we don't care how NaN's behave: */ +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +/* logical expression of p implies q: */ +#define IMPLIES(p,q) (!(p) || (q)) + +/* Note that the IBM RS 6000 xlc predefines TRUE and FALSE in <types.h>. */ +/* The Compaq Alpha also predefines TRUE and FALSE. */ +#ifdef TRUE +#undef TRUE +#endif +#ifdef FALSE +#undef FALSE +#endif + +#define TRUE (1) +#define FALSE (0) +#define PRIVATE static +#define GLOBAL +#define EMPTY (-1) + +/* Note that Linux's gcc 2.96 defines NULL as ((void *) 0), but other */ +/* compilers (even gcc 2.95.2 on Solaris) define NULL as 0 or (0). We */ +/* need to use the ANSI standard value of 0. */ +#ifdef NULL +#undef NULL +#endif + +#define NULL 0 + +/* largest value of size_t */ +#ifndef SIZE_T_MAX +#ifdef SIZE_MAX +/* C99 only */ +#define SIZE_T_MAX SIZE_MAX +#else +#define SIZE_T_MAX ((size_t) (-1)) +#endif +#endif + +/* ------------------------------------------------------------------------- */ +/* integer type for AMD: int or SuiteSparse_long */ +/* ------------------------------------------------------------------------- */ + +#include "amd.h" + +#if defined (DLONG) || defined (ZLONG) + +#define Int SuiteSparse_long +#define ID SuiteSparse_long_id +#define Int_MAX SuiteSparse_long_max + +#define AMD_order amd_l_order +#define AMD_defaults amd_l_defaults +#define AMD_control amd_l_control +#define AMD_info amd_l_info +#define AMD_1 amd_l1 +#define AMD_2 amd_l2 +#define AMD_valid amd_l_valid +#define AMD_aat amd_l_aat +#define AMD_postorder amd_l_postorder +#define AMD_post_tree amd_l_post_tree +#define AMD_dump amd_l_dump +#define AMD_debug amd_l_debug +#define AMD_debug_init amd_l_debug_init +#define AMD_preprocess amd_l_preprocess + +#else + +#define Int int +#define ID "%d" +#define Int_MAX INT_MAX + +#define AMD_order amd_order +#define AMD_defaults amd_defaults +#define AMD_control amd_control +#define AMD_info amd_info +#define AMD_1 amd_1 +#define AMD_2 amd_2 +#define AMD_valid amd_valid +#define AMD_aat amd_aat +#define AMD_postorder amd_postorder +#define AMD_post_tree amd_post_tree +#define AMD_dump amd_dump +#define AMD_debug amd_debug +#define AMD_debug_init amd_debug_init +#define AMD_preprocess amd_preprocess + +#endif + +/* ========================================================================= */ +/* === PRINTF macro ======================================================== */ +/* ========================================================================= */ + +/* All output goes through the PRINTF macro. */ +#define PRINTF(params) { if (amd_printf != NULL) (void) amd_printf params ; } + +/* ------------------------------------------------------------------------- */ +/* AMD routine definitions (not user-callable) */ +/* ------------------------------------------------------------------------- */ + +GLOBAL size_t AMD_aat +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Len [ ], + Int Tp [ ], + double Info [ ] +) ; + +GLOBAL void AMD_1 +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int P [ ], + Int Pinv [ ], + Int Len [ ], + Int slen, + Int S [ ], + double Control [ ], + double Info [ ] +) ; + +GLOBAL void AMD_postorder +( + Int nn, + Int Parent [ ], + Int Npiv [ ], + Int Fsize [ ], + Int Order [ ], + Int Child [ ], + Int Sibling [ ], + Int Stack [ ] +) ; + +GLOBAL Int AMD_post_tree +( + Int root, + Int k, + Int Child [ ], + const Int Sibling [ ], + Int Order [ ], + Int Stack [ ] +#ifndef NDEBUG + , Int nn +#endif +) ; + +GLOBAL void AMD_preprocess +( + Int n, + const Int Ap [ ], + const Int Ai [ ], + Int Rp [ ], + Int Ri [ ], + Int W [ ], + Int Flag [ ] +) ; + +/* ------------------------------------------------------------------------- */ +/* debugging definitions */ +/* ------------------------------------------------------------------------- */ + +#ifndef NDEBUG + +/* from assert.h: assert macro */ +#include <assert.h> + +#ifndef EXTERN +#define EXTERN extern +#endif + +EXTERN Int AMD_debug ; + +GLOBAL void AMD_debug_init ( char *s ) ; + +GLOBAL void AMD_dump +( + Int n, + Int Pe [ ], + Int Iw [ ], + Int Len [ ], + Int iwlen, + Int pfree, + Int Nv [ ], + Int Next [ ], + Int Last [ ], + Int Head [ ], + Int Elen [ ], + Int Degree [ ], + Int W [ ], + Int nel +) ; + +#ifdef ASSERT +#undef ASSERT +#endif + +/* Use mxAssert if AMD is compiled into a mexFunction */ +#ifdef MATLAB_MEX_FILE +#define ASSERT(expression) (mxAssert ((expression), "")) +#else +#define ASSERT(expression) (assert (expression)) +#endif + +#define AMD_DEBUG0(params) { PRINTF (params) ; } +#define AMD_DEBUG1(params) { if (AMD_debug >= 1) PRINTF (params) ; } +#define AMD_DEBUG2(params) { if (AMD_debug >= 2) PRINTF (params) ; } +#define AMD_DEBUG3(params) { if (AMD_debug >= 3) PRINTF (params) ; } +#define AMD_DEBUG4(params) { if (AMD_debug >= 4) PRINTF (params) ; } + +#else + +/* no debugging */ +#define ASSERT(expression) +#define AMD_DEBUG0(params) +#define AMD_DEBUG1(params) +#define AMD_DEBUG2(params) +#define AMD_DEBUG3(params) +#define AMD_DEBUG4(params) + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonArraysHelpers.hpp b/thirdparty/linux/include/coin/coin/BonArraysHelpers.hpp new file mode 100644 index 0000000..a397fb8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonArraysHelpers.hpp @@ -0,0 +1,52 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#include "CoinHelperFunctions.hpp" +#ifndef BonArraysHelpers_H +#define BonArraysHelpers_H + +namespace Bonmin { +template <class X> void +resizeAndCopyArray(X *& array, unsigned int oldSize, unsigned int newSize){ + if(newSize == 0){ + if(oldSize > 0){ + delete [] array; + array = NULL; + } + return; + } + X * buffy = new X[newSize]; + if(oldSize > 0){ + if(oldSize < newSize) + CoinCopyN(array, oldSize, buffy); + else + CoinCopyN(array, newSize, buffy); + delete [] array; + } + array = buffy; +} + +template <class X> void +resizeAndCopyArray(X *& array, unsigned int oldSize, unsigned int newSize, + unsigned int& capacity){ + if(newSize > capacity){ + X * buffy = new X[newSize]; + if(oldSize > 0){ + CoinCopyN(array, oldSize, buffy); + delete [] array; + } + array = buffy; + } + else { + newSize = oldSize; + } +} +}// Ends Bonmin namespace +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonAuxInfos.hpp b/thirdparty/linux/include/coin/coin/BonAuxInfos.hpp new file mode 100644 index 0000000..8643a57 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonAuxInfos.hpp @@ -0,0 +1,110 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/23/2007 + +#ifndef BonAuxInfos_H +#define BonAuxInfos_H +#include <cstdlib> +#include <vector> +#include "OsiAuxInfo.hpp" +#include "CoinSmartPtr.hpp" +#include "BonTypes.hpp" + + +namespace Bonmin { + + + /** Bonmin class for passing info between components of branch-and-cuts.*/ +class AuxInfo : public OsiBabSolver { +public: + /** Default constructor.*/ + AuxInfo(int type); + + /** Constructor from OsiBabSolver.*/ + AuxInfo(const OsiBabSolver &other); + + /** Copy constructor.*/ + AuxInfo(const AuxInfo &other); + + /** Destructor.*/ + virtual ~AuxInfo(); + + /** Virtual copy constructor.*/ + virtual OsiAuxInfo * clone() const; + + /** Declare the node to be feasible.*/ + void setFeasibleNode(){ + infeasibleNode_ = false;} + + /** Declare the node to be infeasible.*/ + void setInfeasibleNode(){ + infeasibleNode_ = true;} + + /** Say if current node is found feasible by cut generators.*/ + bool infeasibleNode(){ + return infeasibleNode_;} + + /** Get solution found by nlp solver (or NULL if none found).*/ + const double * nlpSolution(){ + + if(hasNlpSolution_) + return nlpSolution_; + else + return NULL; + } + + /** Get objective value of nlp solution found, or +infinity if none exists */ + double nlpObjValue (); + + /** Pass a solution found by an nlp solver.*/ + void setNlpSolution(const double * sol, int numcols, double objValue); + + /** Say if has an nlp solution*/ + void setHasNlpSolution(bool b){ + hasNlpSolution_ = b;} + /** get the best solution computed with alternative objective function.*/ + const std::vector<double>& bestSolution2() const + { + return (*bestSolution2_)(); + } + /** return objective value of the best solution computed with alternative + objective function.*/ + double bestObj2() const + { + return (*bestObj2_)(); + } + /** Set an alternate objective value.*/ + void setBestObj2(double o) + { + (*bestObj2_)() = o; + } + void setBestSolution2(int n, double * d) + { + (*bestSolution2_)().clear(); + (*bestSolution2_)().insert((*bestSolution2_)().end(),d, d+n); + } +protected: + /** Say if current node was found infeasible during cut generation*/ + bool infeasibleNode_; + /** value of the objective function of this nlp solution */ + double objValue_; + /** nlp solution found by heuristic if any.*/ + double * nlpSolution_; + /** numcols_ gives the size of nlpSolution_.*/ + int numcols_; + /** say if has a solution.*/ + bool hasNlpSolution_; + /** Stores the solution with alternate objective.*/ + Coin::SmartPtr< SimpleReferenced<std::vector<double> > > bestSolution2_; + /** Alternate solution objective value.*/ + Coin::SmartPtr< SimpleReferenced<double> > bestObj2_; + }; +}/* End namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonBabInfos.hpp b/thirdparty/linux/include/coin/coin/BonBabInfos.hpp new file mode 100644 index 0000000..4ff4b37 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonBabInfos.hpp @@ -0,0 +1,57 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/23/2007 + +#ifndef BonBabInfos_H +#define BonBabInfos_H +#include <stdlib.h> +#include "BonAuxInfos.hpp" + +namespace Bonmin +{ + class Bab; + /** Bonmin class for passing info between components of branch-and-cuts.*/ + class BabInfo : public Bonmin::AuxInfo + { + public: + /** Default constructor.*/ + BabInfo(int type); + + /** Constructor from OsiBabSolver.*/ + BabInfo(const OsiBabSolver &other); + + /** Copy constructor.*/ + BabInfo(const BabInfo &other); + + /** Destructor.*/ + virtual ~BabInfo(); + + /** Virtual copy constructor.*/ + virtual OsiAuxInfo * clone() const; + + /** Set pointer to the branch-and-bound algorithm (to access CbcModel).*/ + void setBabPtr(Bab * babPtr) + { + babPtr_ = babPtr; + } + + /** Pointer to the branch-and-bound algorithm (to access CbcModel).*/ + Bab * babPtr() + { + return babPtr_; + } + + bool hasSolution() const{ + return bestSolution_ != NULL;} + protected: + /** Pointer to branch-and-bound algorithm.*/ + Bab * babPtr_; + }; +}/* End namespace.*/ + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonBabSetupBase.hpp b/thirdparty/linux/include/coin/coin/BonBabSetupBase.hpp new file mode 100644 index 0000000..c51c67c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonBabSetupBase.hpp @@ -0,0 +1,386 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/12/2007 + +#ifndef BabSetupBase_H +#define BabSetupBase_H + +#include <string> +#include <list> +#include "CglCutGenerator.hpp" +#include "CbcHeuristic.hpp" +#include "OsiChooseVariable.hpp" +#include "BonOsiTMINLPInterface.hpp" +#include "IpSmartPtr.hpp" +#include "BonTMINLP2OsiLP.hpp" + +namespace Bonmin +{ + /** A class to have all elements necessary to setup a branch-and-bound.*/ + class BabSetupBase + { + public: + /** Type for cut generation method with its frequency and string identification. */ + struct CuttingMethod + { + int frequency; + std::string id; + CglCutGenerator * cgl; + bool atSolution; + bool normal; + bool always; + CuttingMethod(): + atSolution(false), + normal(true), + always(false) + {} + + CuttingMethod(const CuttingMethod & other): + frequency(other.frequency), + id(other.id), + cgl(other.cgl), + atSolution(other.atSolution), + normal(other.normal), + always(other.always) + {} + }; + /** Type for heuristic method with its string identification. */ + struct HeuristicMethod + { + std::string id; + CbcHeuristic* heuristic; + HeuristicMethod() + {} + + HeuristicMethod(const HeuristicMethod & other): + id(other.id), + heuristic(other.heuristic) + {} + }; + typedef std::list<CuttingMethod> CuttingMethods; + typedef std::list<HeuristicMethod > HeuristicMethods; + + /** Strategies for comparing the nodes on the heap. */ + enum NodeComparison { + bestBound = 0 /** Best bound*/, + DFS /** Depth First Search*/, + BFS /** Best First Search */, + dynamic /** Dynamic strategy, see <a href="http://www.coin-or.org/Doxygen/Cbc/class_cbc_branch_dynamic_decision.html"> + CbcBranchActual.hpp </a> for explanations.*/, + bestGuess /** Best guessed integer solution is subtree below, based on pseudo costs */ + }; + + /** Strategies for traversing the tree.*/ + enum TreeTraversal { + HeapOnly=0 /** Only using the heap, uses CbcTree.*/, + DiveFromBest /** dive from top node of the heap untill it gets to a leaf of the tree. Uses Bonmin::CbcDiver.*/, + ProbedDive /** Eplore two kids before following on dive.*/, + DfsDiveFromBest /** dive from top node of the heap with more elaborate strategy (see options doc). Uses Bonmin::CbcDfsDiver.*/, + DfsDiveDynamic /** Same as DfsDiveFromBest, but after a prescribed number of integer solution are found switch to best-bound and if too many node switches to depth-first. Uses Bonmin::CbcDfsDiver.*/ + }; + + + /** @name Enums for optionslist parameters */ + enum VarSelectStra_Enum { + MOST_FRACTIONAL=0, + STRONG_BRANCHING, + RELIABILITY_BRANCHING, +#ifdef BONMIN_CURVATURE_BRANCHING + CURVATURE_ESTIMATOR, +#endif + QP_STRONG_BRANCHING, + LP_STRONG_BRANCHING, + NLP_STRONG_BRANCHING, + OSI_SIMPLE, + OSI_STRONG, + RANDOM + }; + + /** Parameters represented by an integer. */ + enum IntParameter{ + BabLogLevel = 0 /** Log level of main branch-and-bound*/, + BabLogInterval/** Display information every logIntervval nodes.*/, + MaxFailures /** Max number of failures in a branch.*/, + FailureBehavior /** Behavior of the algorithm in the case of a failure.*/, + MaxInfeasible /** Max number of consecutive infeasible problem in a branch + before fathoming.*/, + NumberStrong /** Number of candidates for strong branching.*/, + MinReliability /** Minimum reliability before trust pseudo-costs.*/, + MaxNodes /** Global node limit.*/, + MaxSolutions /** limit on number of integer feasible solution.*/, + MaxIterations /** Global iteration limit. */, + SpecialOption /** Spetial option in particular for Cbc. */, + DisableSos /** Consider or not SOS constraints.*/, + NumCutPasses/** Number of cut passes at nodes.*/, + NumCutPassesAtRoot/** Number of cut passes at nodes.*/, + RootLogLevel/** Log level for root relaxation.*/, + NumberIntParam /** Dummy end to size table*/ + }; + + + /** Parameters represented by a double.*/ + enum DoubleParameter{ + CutoffDecr = 0 /** Amount by which cutoff is incremented */, + Cutoff /** cutoff value */, + AllowableGap /** Stop if absolute gap is less than this. */, + AllowableFractionGap /** Stop if relative gap is less than this.*/, + IntTol /** Integer tolerance.*/, + MaxTime /** Global time limit. */, + NumberDoubleParam /** Dummy end to size table*/ + }; + + /** Default constructor. */ + BabSetupBase(const CoinMessageHandler * handler = NULL); + + /** Construct from existing tminlp. */ + BabSetupBase(Ipopt::SmartPtr<TMINLP> tminlp, const CoinMessageHandler * handler = NULL); + /** Construct from existing application.*/ + BabSetupBase(Ipopt::SmartPtr<TNLPSolver> app); + /** Construct from existing TMINLP interface.*/ + BabSetupBase(const OsiTMINLPInterface& nlp); + /** Copy but uses an other nlp.*/ + BabSetupBase(const BabSetupBase &setup, + OsiTMINLPInterface &nlp); + + /** Copy but uses an other nlp.*/ + BabSetupBase(const BabSetupBase &setup, + OsiTMINLPInterface &nlp, + const std::string &prefix); + + /** Copy constructor. */ + BabSetupBase(const BabSetupBase & other); + + /** virtual copy constructor. */ + virtual BabSetupBase * clone() const = 0; + + /** Make a copy with solver replace by one passed .*/ + virtual BabSetupBase *clone(OsiTMINLPInterface&nlp)const; + /** Virtual destructor. */ + virtual ~BabSetupBase(); + + /** @name Methods to initialize algorithm with various inputs. */ + /** @{ */ + /** use existing TMINLP interface (containing the options).*/ + void use(const OsiTMINLPInterface& nlp); + /** Read options (if not done before) and create interface using tminlp.*/ + void use(Ipopt::SmartPtr<TMINLP> tminlp ); + /** use specific instanciation of a TMINLP2TNLP.*/ + void use(Ipopt::SmartPtr<TMINLP2TNLP> prob); + /** Set the non-linear solver used */ + void setNonlinearSolver(OsiTMINLPInterface * s) + { + nonlinearSolver_ = s; + } + /** @} */ + + /** @name Methods to manipulate options. */ + /** @{ */ + /** Register all the options for this algorithm instance.*/ + virtual void registerOptions(); + /** Setup the defaults options for this algorithm. */ + virtual void setBabDefaultOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + {} + /** Register all the options for this algorithm instance.*/ + static void registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Get the options from default text file (bonmin.opt) if don't already have them.*/ + virtual void readOptionsFile() + { + if (readOptions_) return; + readOptionsFile("bonmin.opt"); + } + + /** Get the options from given fileName */ + void readOptionsFile(std::string fileName); + + /** Get the options from long string containing all.*/ + void readOptionsString(std::string opt_string); + + /** Get the options from stream.*/ + void readOptionsStream(std::istream& is); + + /** May print documentation of options if options print_options_documentation is set to yes.*/ + void mayPrintDoc(); + + + /** Get prefix to use for options.*/ + const char * prefix() const { + return prefix_.c_str(); + } + + /** Set the value for options, output...*/ + void setOptionsAndJournalist(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist) + { + options_ = options; + roptions_ = roptions; + journalist_ = journalist; + } + + /** Initialize the options and the journalist.*/ + void initializeOptionsAndJournalist(); + /** @} */ + + /** @name Elements of the branch-and-bound setup.*/ + /** @{ */ + /** Pointer to the non-linear solver used.*/ + OsiTMINLPInterface * nonlinearSolver() + { + return nonlinearSolver_; + } + /** Pointer to the continuous solver to use for relaxations. */ + OsiSolverInterface * continuousSolver() + { + return continuousSolver_; + } + /** list of cutting planes methods to apply with their frequencies. */ + CuttingMethods& cutGenerators() + { + return cutGenerators_; + } + /** list of Heuristic methods to use. */ + HeuristicMethods& heuristics() + { + return heuristics_; + } + /** branching method to use. */ + OsiChooseVariable * branchingMethod() + { + return branchingMethod_; + } + /** Method used to compare nodes. */ + NodeComparison& nodeComparisonMethod() + { + return nodeComparisonMethod_; + } + /** Method used to traverse tree.*/ + TreeTraversal treeTraversalMethod() + { + return treeTraversalMethod_; + } + /** Return value of integer parameter. */ + int getIntParameter(const IntParameter &p) const + { + return intParam_[p]; + } + /** Return value of double parameter.*/ + double getDoubleParameter(const DoubleParameter &p) const + { + return doubleParam_[p]; + } + /** Return value of integer parameter. */ + void setIntParameter(const IntParameter &p, const int v) + { + intParam_[p] = v; + } + /** Return value of double parameter.*/ + void setDoubleParameter(const DoubleParameter &p, const double v) + { + doubleParam_[p] = v; + } + /** @} */ + + /** Get the values of base parameters from the options stored.*/ + void gatherParametersValues() + { + gatherParametersValues(options_); + } + /** Get the values of the base parameters from the passed options.*/ + void gatherParametersValues(Ipopt::SmartPtr<Ipopt::OptionsList> options); + /** Acces storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist() + { + return journalist_; + } + + /** Acces list of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options() + { + return options_; + } + + /** Access registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions() + { + return roptions_; + } + + /** Access to extra objects.*/ + const vector<OsiObject *>& objects() const + { + return objects_; + } + + /** Access to extra objects.*/ + vector<OsiObject *>& objects() + { + return objects_; + } + + void addCutGenerator(CuttingMethod & cg){ + cutGenerators_.push_back(cg); + } + + void set_linearizer(TMINLP2OsiLP * linearizer){ + linearizer_ = linearizer; + } + + protected: + /** Set the priorities into OsiTMINLPInterface when needed.*/ + void setPriorities(); + /** Add SOS constraints to OsiTMINLPInterface when needed.*/ + void addSos(); + + /** storage of integer parameters.*/ + int intParam_[NumberIntParam]; + /** default values for int parameters.*/ + static int defaultIntParam_[NumberIntParam]; + /** storage of double parameters. */ + double doubleParam_[NumberDoubleParam]; + /** default values for double parameters. */ + static double defaultDoubleParam_[NumberDoubleParam]; + /** Storage of the non-linear solver used.*/ + OsiTMINLPInterface * nonlinearSolver_; + /** Storage of continuous solver.*/ + OsiSolverInterface * continuousSolver_; + /** Method to linearize MINLPs */ + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer_; + /** Cut generation methods. */ + CuttingMethods cutGenerators_; + /** Heuristic methods. */ + HeuristicMethods heuristics_; + /** Branching method.*/ + OsiChooseVariable * branchingMethod_; + /** Node comparison method.*/ + NodeComparison nodeComparisonMethod_; + /** Tree traversal method.*/ + TreeTraversal treeTraversalMethod_; + /** Extra object to add to Cbc (not OsiObjects).*/ + vector<OsiObject *> objects_; + + + /** Storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist_; + + /** List of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + + /** Registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions_; + + /** flag to say if option file was read.*/ + bool readOptions_; + /** separate message handler.*/ + CoinMessageHandler * messageHandler_; + /** Prefix to use when reading options.*/ + std::string prefix_; + }; +}/* End namespace Bonmin. */ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonBonminSetup.hpp b/thirdparty/linux/include/coin/coin/BonBonminSetup.hpp new file mode 100644 index 0000000..c1ea003 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonBonminSetup.hpp @@ -0,0 +1,95 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/13/2007 +#ifndef BonminSetup_H +#define BonminSetup_H +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** Type of algorithms which can be used.*/ + enum Algorithm{ + Dummy=-1/** Dummy value before initialization.*/, + B_BB=0/** Bonmin's Branch-and-bound.*/, + B_OA=1/** Bonmin's Outer Approximation Decomposition.*/, + B_QG=2/** Bonmin's Quesada & Grossmann branch-and-cut.*/, + B_Hyb=3/** Bonmin's hybrid outer approximation.*/, + B_Ecp=4/** Bonmin's implemantation of ecp cuts based branch-and-cut a la FilMINT.*/, + B_IFP=5/** Bonmin's implemantation of iterated feasibility pump for MINLP.*/ + }; + /* Bonmin algorithm setup. */ + class BonminSetup : public BabSetupBase + { + public: + /** Default constructor. */ + BonminSetup(const CoinMessageHandler * handler = NULL); + /** Copy constructor. */ + BonminSetup(const BonminSetup & other); + + /** Copy but uses an other nlp.*/ + BonminSetup(const BonminSetup &setup, + OsiTMINLPInterface &nlp); + + /** Copy but uses another nlp and algorithm.*/ + BonminSetup(const BonminSetup &setup, + OsiTMINLPInterface &nlp, + const std::string & prefix); + /** virtual copy constructor. */ + virtual BabSetupBase * clone() const + { + return new BonminSetup(*this); + } + /** Make a copy with solver replace by one passed .*/ + // virtual BabSetupBase *clone(OsiTMINLPInterface&nlp)const{ + // return new BonminSetup(*this, nlp); + // } + /** Make a copy with solver replace by one passed .*/ + BonminSetup *clone(OsiTMINLPInterface&nlp)const{ + return new BonminSetup(*this, nlp); + } + /** Make a copy but take options with different prefix.*/ + BonminSetup *clone(OsiTMINLPInterface &nlp, const std::string & prefix)const{ + return new BonminSetup(*this, nlp, prefix); + } + virtual ~BonminSetup() + {} + /** @name Methods to instantiate: Registering and retrieving options and initializing everything. */ + /** @{ */ + /** Register all the options for this algorithm instance.*/ + virtual void registerOptions(); + /** Setup the defaults options for this algorithm. */ + virtual void setBabDefaultOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + {} + /** @} */ + /** Register all bonmin type executable options.*/ + static void registerAllOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + /** Initialize, read options and create appropriate bonmin setup.*/ + void initialize(Ipopt::SmartPtr<TMINLP> tminlp, bool createContinuousSolver = true); + /** Initialize, read options and create appropriate bonmin setup.*/ + void initialize(const OsiTMINLPInterface& nlpSi, bool createContinuousSolver = true); + /** Get the algorithm used.*/ + Bonmin::Algorithm getAlgorithm(); + + void addCutGenerator(CuttingMethod & cg){ + BabSetupBase::addCutGenerator(cg); + } + protected: + /** Register standard MILP cut generators. */ + static void registerMilpCutGenerators(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + /** Add milp cut generators according to options.*/ + void addMilpCutGenerators(); + /** Initialize a plain branch-and-bound.*/ + void initializeBBB(); + /** Initialize a branch-and-cut with some OA.*/ + void initializeBHyb(bool createContinuousSolver = false); + private: + Algorithm algo_; + }; +}/** end namespace Bonmin*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonBranchingTQP.hpp b/thirdparty/linux/include/coin/coin/BonBranchingTQP.hpp new file mode 100644 index 0000000..f718419 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonBranchingTQP.hpp @@ -0,0 +1,197 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2006, 2008 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Andreas Waechter, International Business Machines Corporation +// (derived from BonTMINLP2TNLP.hpp) 12/22/2006 + +#ifndef __BONBRANCHINGTQP_HPP__ +#define __BONBRANCHINGTQP_HPP__ + +#include "BonTMINLP2TNLP.hpp" + +namespace Bonmin +{ + /** This is an adapter class that converts a TMINLP2TNLP object into + * a TNLP, which is now just a QP. The QP is the linear quadratic + * of the TNLP at the optimal point. The purpose of the + * BranchingTQP is that it is used in a strong-branching framework, + * strong branching is only done for the QP approximation of the + * TNLP, not on the TNLP itself. The variables of the QP are the + * displacement from the reference point. + */ + class BranchingTQP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + BranchingTQP(Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp); + + /** Default destructor */ + virtual ~BranchingTQP(); + //@} + + /**@name methods to gather information about the NLP, only those + * that need to be overloaded from TNLP */ + //@{ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + /** Returns the constraint linearity. array should be alocated + * with length at least n. Since this is a QP, all constraints are + * linear.*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types); + /** Method called by Ipopt to get the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Accessor Methods for QP data */ + //@{ + const Ipopt::Number ObjVal() + { + return obj_val_; + } + const Ipopt::Number* ObjGrad() + { + return obj_grad_; + } + const Ipopt::Number* ObjHessVals() + { + return obj_hess_; + } + const Ipopt::Index* ObjHessIRow() + { + return obj_hess_irow_; + } + const Ipopt::Index* ObjHessJCol() + { + return obj_hess_jcol_; + } + const Ipopt::Number* ConstrRhs() + { + return g_vals_; + } + const Ipopt::Number* ConstrJacVals() + { + return g_jac_; + } + const Ipopt::Index* ConstrJacIRow() + { + return g_jac_irow_; + } + const Ipopt::Index* ConstrJacJCol() + { + return g_jac_jcol_; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + BranchingTQP(); + + /** Copy Constructor */ + BranchingTQP(const BranchingTQP&); + + /** Overloaded Equals Operator */ + void operator=(const BranchingTQP&); + //@} + + /** @name static information about the QP's constraints and + * objective function */ + //@{ + Ipopt::Number obj_val_; + Ipopt::Number* obj_grad_; + Ipopt::Number* obj_hess_; + Ipopt::Index* obj_hess_irow_; + Ipopt::Index* obj_hess_jcol_; + Ipopt::Number* g_vals_; + Ipopt::Number* g_jac_; + Ipopt::Index* g_jac_irow_; + Ipopt::Index* g_jac_jcol_; + //@} + + /** @name Data from the MINLP */ + //@{ + Ipopt::Index n_; + Ipopt::Index m_; + Ipopt::Index nnz_jac_g_; + Ipopt::Index nnz_h_lag_; + Ipopt::TNLP::IndexStyleEnum index_style_; + //@} + + /** Copy of original x_sol_. x_sol_ is changed after the first QP + * has been solved once. */ + Ipopt::Number* x_sol_copy_; + + /** Copy of original duals_sol_. duals_sol_ is changed after the + * first QP has been solved once. */ + Ipopt::Number* duals_sol_copy_; + + /** Pointer to the TMINLP2TNLP model which stores the bounds + * information */ + Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCbc.hpp b/thirdparty/linux/include/coin/coin/BonCbc.hpp new file mode 100644 index 0000000..caa178e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCbc.hpp @@ -0,0 +1,127 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/19/2007 + +#ifndef BonCbc_H +#define BonCbc_H + +//#include "BonBabSetupBase.hpp" +#include "CbcModel.hpp" + +namespace Bonmin +{ + class BabSetupBase; + class Bab + { + public: + /** Integer optimization return codes.*/ + enum MipStatuses {FeasibleOptimal /** Optimum solution has been found and its optimality proved.*/, + ProvenInfeasible /** Problem has been proven to be infeasible.*/, + Feasible /** An integer solution to the problem has been found.*/, + UnboundedOrInfeasible /*Coninuous relaxation is unbounded.*/, + NoSolutionKnown/** No feasible solution to the problem is known*/, + NumMipStats}; + + + /** Constructor.*/ + Bab(); + /** destructor.*/ + virtual ~Bab(); + /** Perform a branch-and-bound using given setup.*/ + virtual void branchAndBound(BabSetupBase & s); + + /**operator() performs the branchAndBound*/ + virtual void operator()(BabSetupBase & s); + + /**operator() performs the branchAndBound*/ + virtual void operator()(BabSetupBase * s){ + operator()(*s);} + + /** get the best solution known to the problem (is optimal if MipStatus is FeasibleOptimal). + if no solution is known returns NULL.*/ + const double * bestSolution() const + { + return bestSolution_; + } + /** return objective value of the bestSolution */ + double bestObj() const + { + return bestObj_; + } + + /** return Mip Status */ + MipStatuses mipStatus() const + { + return mipStatus_; + } + + /** return the best known lower bound on the objective value*/ + double bestBound(); + + /** return the total number of nodes explored.*/ + int numNodes() const + { + return numNodes_; + } + /** return the total number of iterations in the last mip solved.*/ + int iterationCount() + { + return mipIterationCount_; + } + /** returns the value of the continuous relaxation. */ + double continuousRelaxation() + { + return continuousRelaxation_; + } + + /** virtual callback function to eventually modify objects for integer variable + (replace with user set). This is called after CbcModel::findIntegers */ + virtual void replaceIntegers(OsiObject ** objects, int numberObjects) + {} + /** Get cbc model used to solve. */ + const CbcModel& model() const + { + return model_; + } + + /** Get cbc model used to solve as non-const, in case we want to + change options before things happen */ + CbcModel& model() + { + return model_; + } + + protected: + /** Stores the solution of MIP. */ + double * bestSolution_; + + /** Status of the mip solved*/ + MipStatuses mipStatus_; + /** objValue of MIP */ + double bestObj_; + /** best known (lower) bound.*/ + double bestBound_; + /** Continuous relaxation of the problem */ + double continuousRelaxation_; + /** Number of nodes enumerated.*/ + int numNodes_; + /** get total number of iterations in last mip solved.*/ + int mipIterationCount_; + /** CbcModel used to solve problem.*/ + CbcModel model_; + /** Message handler for CbcModel. */ + CoinMessageHandler * modelHandler_; + /** \brief OsiObjects of the model. + * this is not null if and only if there are some non-simple-integer branching objects such as SOS constraints. + * It is up to Bab to pass them over to appropriate components of the algorithm. */ + OsiObject** objects_; + /** number of objects.*/ + int nObjects_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCbcLpStrategy.hpp b/thirdparty/linux/include/coin/coin/BonCbcLpStrategy.hpp new file mode 100644 index 0000000..6d16e91 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCbcLpStrategy.hpp @@ -0,0 +1,45 @@ +// (C) Copyright Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + + +#ifndef CbcOaStrategy_HPP +#define CbcOaStrategy_HPP + +#include "CbcStrategy.hpp" +#include <string> +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** A class to setup default strategy for Cbc specifying which cut generators to use.*/ + class CbcStrategyChooseCuts : public CbcStrategyDefault { + public: + /** Default constructor.*/ + CbcStrategyChooseCuts(); + /** Constructor with a setup. */ + CbcStrategyChooseCuts(BabSetupBase &s, const std::string & prefix); + /** Copy constructor.*/ + CbcStrategyChooseCuts(const CbcStrategyChooseCuts &other); + /** Virtual copy constructor.*/ + CbcStrategy * clone() const{ + return new CbcStrategyChooseCuts(*this); + } + /** Setup strategy.*/ + void setup(BabSetupBase &s, const std::string &prefix); + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + + private: + /** Generators frequencies.*/ + int gen_freqs_[6]; + /** Flag to say which cut generators to use.*/ + int genFlag_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCbcNlpStrategy.hpp b/thirdparty/linux/include/coin/coin/BonCbcNlpStrategy.hpp new file mode 100644 index 0000000..b642ad0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCbcNlpStrategy.hpp @@ -0,0 +1,98 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// John J. Forrest, International Business Machines Corporation +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + +#ifndef BonCbcNlpStrategy_H +#define BonCbcNlpStrategy_H + +#include "CbcStrategy.hpp" +class CglPreProcess; +class CbcNodeInfo; +class CbcNode; +class CoinWarmStartDiff; + + +namespace Bonmin +{ + class CbcNlpStrategy : public CbcStrategy + { + public: + + // Default Constructor + CbcNlpStrategy (int maxFailures, + int maxInfeasibles, + int pretendFailIsInfeasible); + + // Copy constructor + CbcNlpStrategy ( const CbcNlpStrategy &); + + // Destructor + virtual ~CbcNlpStrategy (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Return a new Full node information pointer (descendant of CbcFullNodeInfo) + virtual CbcNodeInfo * fullNodeInfo(CbcModel * model,int numberRowsAtContinuous) const; + /// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo) + virtual CbcNodeInfo * partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds,const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) const; + /** After a CbcModel::resolve this can return a status + -1 no effect + 0 treat as optimal + 1 as 0 but do not do any more resolves (i.e. no more cuts) + 2 treat as infeasible + */ + virtual int status(CbcModel * model, CbcNodeInfo * parent, int whereFrom); + /// set maximum number of consecutive failures in a branch before giving up + inline void setMaxFailure(int value) + { + maxFailure_ = value; + } + /// maximum number of consecutive infeasible nodes before giving up + inline void setMaxInfeasible(int value) + { + maxInfeasible_ = value; + } + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model,int modelLogLevel); + /// Other stuff e.g. strong branching and preprocessing + virtual void setupOther(CbcModel & model); + + bool hasFailed() + { + return hasFailed_; + } + protected: + // Data + /// did we fail? + bool hasFailed_; + /// maximum number of consecutive failures in a branch before giving up + int maxFailure_; + /// maximum number of consecutive infeasible nodes before giving up + int maxInfeasible_; + /** If yes when a problem is not solved (failed to be solved) + will pretend that it is infeasible. */ + int pretendFailIsInfeasible_; + + private: + /// Illegal Assignment operator + CbcNlpStrategy & operator=(const CbcNlpStrategy& rhs); + + }; +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCbcNode.hpp b/thirdparty/linux/include/coin/coin/BonCbcNode.hpp new file mode 100644 index 0000000..9594124 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCbcNode.hpp @@ -0,0 +1,133 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// John J. Forrest, International Business Machines Corporation +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 03/15/2006 + +#ifndef BonminCbcNode_H +#define BonminCbcNode_H + +#include "CbcNode.hpp" +#include "BonRegisteredOptions.hpp" + + +namespace Bonmin +{ + /** \brief Holds information for recreating a subproblem by incremental change + from the parent for Bonmin + + A BonminBonminCbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. + */ + + class BonCbcFullNodeInfo : public CbcFullNodeInfo + { + + public: + friend class BonCbcPartialNodeInfo; + // Default Constructor + BonCbcFullNodeInfo (); + + // Constructor from current state + BonCbcFullNodeInfo (CbcModel * model, int numberRowsAtContinuous); + + // Copy constructor + BonCbcFullNodeInfo ( const BonCbcFullNodeInfo &); + + // Destructor + ~BonCbcFullNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + + /**Method called when all direct sons have been explored to flush + useless warm start information.*/ + virtual void allBranchesGone(); + + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + inline int getSequenceOfInfeasiblesSize() + { + return sequenceOfInfeasiblesSize_; + } + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + inline int getSequenceOfUnsolvedSize() + { + return sequenceOfUnsolvedSize_; + } + /** Register all the options for class instance.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /* Data values */ + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + int sequenceOfInfeasiblesSize_; + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + int sequenceOfUnsolvedSize_; + private: + + /// Illegal Assignment operator + BonCbcFullNodeInfo & operator=(const BonCbcFullNodeInfo& rhs); + }; + + /** \brief Holds information for recreating a subproblem by incremental change + from the parent for + + A BonminCbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. + */ + + class BonCbcPartialNodeInfo : public CbcPartialNodeInfo + { + + public: + // Default Constructor + BonCbcPartialNodeInfo (); + + // Constructor from current state + BonCbcPartialNodeInfo (CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds,const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) ; + + // Copy constructor + BonCbcPartialNodeInfo ( const BonCbcPartialNodeInfo &); + + // Destructor + ~BonCbcPartialNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + + /**Method called when all direct sons have been explored to flush + useless warm start information.*/ + virtual void allBranchesGone(); + + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + inline int getSequenceOfInfeasiblesSize() + { + return sequenceOfInfeasiblesSize_; + } + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + inline int getSequenceOfUnsolvedSize() + { + return sequenceOfUnsolvedSize_; + } + private: + /* Data values */ + /** Number of consecutive infeasible parents only recorded if node is infeasible*/ + int sequenceOfInfeasiblesSize_; + /** Number of consecutive unsolved parents only recorded if node is infeasible*/ + int sequenceOfUnsolvedSize_; + private: + + /// Illegal Assignment operator + BonCbcPartialNodeInfo & operator=(const Bonmin::BonCbcPartialNodeInfo& rhs); + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonChooseVariable.hpp b/thirdparty/linux/include/coin/coin/BonChooseVariable.hpp new file mode 100644 index 0000000..82e7575 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonChooseVariable.hpp @@ -0,0 +1,345 @@ +// Copyright (C) 2006, 2008 International Business Machines +// Corporation and others. All Rights Reserved. +#ifndef BonChooseVariable_H +#define BonChooseVariable_H + +#include "OsiChooseVariable.hpp" +#ifdef BONMIN_CURVATURE_BRANCHING +#include "BonCurvatureEstimator.hpp" +#endif +#include "BonOsiTMINLPInterface.hpp" +#include "CoinMessageHandler.hpp" +#include "BonBabSetupBase.hpp" +// Forward declaration +class CbcModel; + +#define OLD_USEFULLNESS + +namespace Bonmin +{ + + class HotInfo : public OsiHotInfo { + public: + /// Default constructor + HotInfo(); + + /// Constructor from usefull information + HotInfo( OsiSolverInterface * solver, + const OsiBranchingInformation *info, + const OsiObject * const * objects, int whichObject); + + /// Copy constructor + HotInfo(const HotInfo & other); + + /// Assignment operator + HotInfo & operator=(const HotInfo & rhs); + + /// Clone + virtual OsiHotInfo * clone() const; + + /// Destructor + virtual ~HotInfo(); + + /// Fill in some usefull information after a strong branching is done: + int updateInformation( const OsiSolverInterface * solver, const OsiBranchingInformation * info, + OsiChooseVariable * choose); + + /// up infeasibility + double upInfeasibility() const{ + return infeasibilities_[1]; + } + + /// down infeasibility + double downInfeasibility() const{ + return infeasibilities_[0]; + } + + + /// Set the down infeasibility + void setUpInfeasibility(double x){ + assert(branchingObject_->numberBranches()==2); + infeasibilities_[1] = x; + } + + /// Set the down infeasibility + void setDownInfeasibility(double x){ + assert(branchingObject_->numberBranches()==2); + infeasibilities_[0] = x; + } + private: + /// infeasibilities of children + vector<double> infeasibilities_; + }; + + /** This class chooses a variable to branch on + + This is the base class for the branching rules in Bonmin (inherits + from OsiChooseVariable). This class implements a simple strong branching algorithm where the changes in the objective + value induced by branching on a specific object are estimated with the pure virtual function fill_changes. + */ + + class BonChooseVariable : public OsiChooseVariable + { + protected: + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + virtual int doStrongBranching( OsiSolverInterface * solver, + OsiBranchingInformation *info, + int numberToDo, int returnCriterion); +#ifndef OLD_USEFULLNESS + /** Criterion applied to sort candidates.*/ + enum CandidateSortCriterion { + DecrPs = 0, + IncrPs, + DecrInfeas, + IncrInfeas}; +#endif + + /** Statuses for strong branching candidates.*/ + enum StrongStatus{ + NotDone=-1, + Feasible/** Child is proven feasible.*/, + Infeasible /** Child is proven infeasible.*/, + NotFinished /** Child is not finished.*/}; + public: + /** \name Message handling.*/ + /** @{ */ + enum Messages_Types { + PS_COST_HISTORY = 0, + PS_COST_MULT, + PS_COST_ESTIMATES, + CANDIDATE_LIST, + CANDIDATE_LIST2, + CANDIDATE_LIST3, + SB_START, + SB_HEADER, + SB_RES, + BRANCH_VAR, + CHOSEN_VAR, + UPDATE_PS_COST, + BON_CHOOSE_MESSAGES_DUMMY_END + }; + + class Messages : public CoinMessages + { + public: + Messages(); + }; + + void passInMessageHandler(CoinMessageHandler * handler) { + int logLevel = handler_->logLevel(); + delete handler_; + handler_ = handler->clone(); + handler_->setLogLevel(logLevel); + } + + CoinMessageHandler& message(Messages_Types type) const { + return handler_->message(type, messages_); + } + /** @} */ + + + + enum DoStrongReturnStatuses{ + provenInfeasible = -1 /** One branch has two infeasible children.*/, + doneNoFixing /** All done no variable can be fixed.*/, + doneCanFix /** Several variable can be fixed.*/, + interuptedCanFix /** Interupted and found a variable to fix.*/, + maxTime /** Interupted because of time limit.*/}; + + /** Return statuses for chooseVariable.*/ + enum chooseVariableReturnStatuses{ + infeasibleNode = -1/** Node has been proven infeasible.*/, + hasCandidate /** Normal termination, found a variable to branch on.*/, + feasibleNode /** All variable are feasible, the node is feasible.*/, + canFixAndStrongBranch /** Found variable to fix and also has remaining candidate for strong branching.*/, + canFixAndBranch/** Found variable to fix and also has a (non-strong) branching candidate.*/, + canFixNoCandidate /** Can fix variables but does not have strong branching candidates.*/ + }; + /// Constructor from solver (so we can set up arrays etc) + BonChooseVariable (BabSetupBase& b, const OsiSolverInterface* solver); + + /// Copy constructor + BonChooseVariable (const BonChooseVariable &); + + /// Assignment operator + BonChooseVariable & operator= (const BonChooseVariable& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~BonChooseVariable (); + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Helper functions for setupList and chooseVariable */ + double maxminCrit(const OsiBranchingInformation* info) const; + void computeMultipliers(double& upMult, double& downMult) const; + double computeUsefulness(const double MAXMIN_CRITERION, + const double upMult, const double dowMult, + const double value, + const OsiObject* object, int i, + double& value2) const; + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation(const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif + + /** Method for setting CbcModel, which is used to get statusOfSearch */ + void setCbcModel(CbcModel* cbc_model) + { + cbc_model_ = cbc_model; + } + + void setOnlyPseudoWhenTrusted(bool only_pseudo_when_trusted) + { + only_pseudo_when_trusted_ = only_pseudo_when_trusted; + } + + + /** Access to pseudo costs storage.*/ + const OsiPseudoCosts & pseudoCosts() const{ + return pseudoCosts_;} + + /** Access to pseudo costs storage.*/ + OsiPseudoCosts & pseudoCosts() { + return pseudoCosts_;} + protected: + + /// Holding on the a pointer to the journalist + Ipopt::SmartPtr<Ipopt::Journalist> jnlst_; + + /// verbosity level + int bb_log_level_; + + /** Stores strong branching results.*/ + vector<HotInfo> results_; + + /** Determine status of strong branching solution.*/ + int determineStatus(OsiSolverInterface * solver) const { + if (solver->isProvenOptimal()) + return 0; // optimal + else if (solver->isIterationLimitReached() + &&!solver->isDualObjectiveLimitReached()) + return 2; // unknown + else + return 1; // infeasible + } + + private: + /** Default Constructor, forbiden for some reason.*/ + BonChooseVariable (); + + /** Global time limit for algorithm. */ + double time_limit_; + + /** Starting time of algorithm.*/ + double start_time_; + protected: + /// CbcModel, used to get status of search + CbcModel* cbc_model_; + + /** Flag indicating whether we don't want to mix strong branching + * and pseudo costs during the decision which variable to branch + * on */ + bool only_pseudo_when_trusted_; + + /** Number of variables put into the list because there were not + * trusted */ + int number_not_trusted_; + + /** Message handler.*/ + CoinMessageHandler * handler_; + + /** Messages.*/ + Messages messages_; + // ToDo: Make this options + /** @name Algoirithmic options */ + //@{ + /** maxmin weight in branching decision when no solution has been + * found yet */ + double maxmin_crit_no_sol_; + /** maxmin weight in branching decision when no solution has been + * found yet */ + double maxmin_crit_have_sol_; + /** fraction of branching candidates that are not trusted yet */ + double setup_pseudo_frac_; + /** number of times a branch has to happen so that it is trusted in + * setupList */ + int numberBeforeTrustedList_; + /** number of strong branching points at root node */ + int numberStrongRoot_; + /** backup of numberStrong_ before Root node solve */ + int numberStrongBackup_; + /** number of look-ahead strong-branching steps */ + int numberLookAhead_; +#ifndef OLD_USEFULLNESS + /** Criterion to use in setup list.*/ + CandidateSortCriterion sortCrit_; +#endif + /** Always strong branch that many first candidate in the list regardless of numberTrusted.*/ + int minNumberStrongBranch_; + /** Stores the pseudo costs. */ + OsiPseudoCosts pseudoCosts_; + /** Wether or not to trust strong branching results for updating pseudo costs.*/ + int trustStrongForPseudoCosts_; + + //@} + + /** detecting if this is root node */ + bool isRootNode(const OsiBranchingInformation *info) const; + + /** Stores the class name for throwing errors.*/ + static const std::string CNAME; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCurvBranchingSolver.hpp b/thirdparty/linux/include/coin/coin/BonCurvBranchingSolver.hpp new file mode 100644 index 0000000..83be1ac --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCurvBranchingSolver.hpp @@ -0,0 +1,77 @@ +// Copyright (C) 2006, 2007 International Business Machines +// Corporation and others. All Rights Reserved. +// +// +#error "BonCurvBranchingSolver not supported anymore" +#ifndef BonCurvBranchingSolver_H +#define BonCurvBranchingSolver_H + +#include "BonStrongBranchingSolver.hpp" +#include "BonCurvatureEstimator.hpp" + +namespace Bonmin +{ + + /** Implementation of BonChooseVariable for curvature-based braching. + */ + + class CurvBranchingSolver : public StrongBranchingSolver + { + + public: + + /// Constructor from solver (so we can set up arrays etc) + CurvBranchingSolver (OsiTMINLPInterface * solver); + + /// Copy constructor + CurvBranchingSolver (const CurvBranchingSolver &); + + /// Assignment operator + CurvBranchingSolver & operator= (const CurvBranchingSolver& rhs); + + /// Destructor + virtual ~CurvBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface); + + private: + /// Default Constructor + CurvBranchingSolver (); + + SmartPtr<CurvatureEstimator> cur_estimator_; + + /** @name Stuff for the curvature estimator */ + //@{ + bool new_bounds_; + bool new_x_; + bool new_mults_; + double* orig_d_; + double* projected_d_; + Number* x_l_orig_; + Number* x_u_orig_; + Number* g_l_orig_; + Number* g_u_orig_; + //@} + + /** @name Information about the problem */ + //@{ + int numCols_; + int numRows_; + const double* solution_; + const double* duals_; + double obj_value_; + //@} + + }; + +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonCutStrengthener.hpp b/thirdparty/linux/include/coin/coin/BonCutStrengthener.hpp new file mode 100644 index 0000000..7e2b92f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonCutStrengthener.hpp @@ -0,0 +1,244 @@ +// Copyright (C) 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: BonCutStrengthener.hpp 2106 2015-01-20 10:33:55Z stefan $ +// +// Author: Andreas Waechter IBM 2007-03-29 + +#ifndef __BONCUTSTRENGTHENER_HPP__ +#define __BONCUTSTRENGTHENER_HPP__ + +#include "BonTMINLP.hpp" +#include "CoinPackedVector.hpp" +#include "BonTNLPSolver.hpp" + +namespace Bonmin +{ + enum CutStrengtheningType{ + CS_None=0, + CS_StrengthenedGlobal=1, + CS_UnstrengthenedGlobal_StrengthenedLocal=2, + CS_StrengthenedGlobal_StrengthenedLocal=3 + }; + + enum DisjunctiveCutType{ + DC_None=0, + DC_MostFractional=1 + }; + + /** Class for strengthening OA cuts, and generating additional ones. + */ + class CutStrengthener: public Ipopt::ReferencedObject + { + /** Class implementing the TNLP for strengthening one cut. We + * assume that the cut has a lower bound. */ + class StrengtheningTNLP: public Ipopt::TNLP { + public: + /** Contructor */ + StrengtheningTNLP(Ipopt::SmartPtr<TMINLP> tminlp, + const CoinPackedVector& cut, + bool lower_bound, + Ipopt::Index n, + const Ipopt::Number* starting_point, + const double* x_l_orig, + const double* x_u_orig, + Ipopt::Index constr_index, + Ipopt::Index nvar_constr /** Ipopt::Number of variables in constraint */, + const Ipopt::Index* jCol); + + /** Destructor */ + ~StrengtheningTNLP(); + + /**@name Overloaded from TNLP */ + //@{ + /** Method to return some info about the nlp */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + + /** Method to return the bounds for my problem */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Method to return the starting point for the algorithm */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method to return the objective value */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number& obj_value); + + /** Method to return the gradient of the objective */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number* grad_f); + + /** Method to return the constraint residuals */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Index m, Ipopt::Number* g); + + /** Method to return: + * 1) The structure of the jacobian (if "values" is NULL) + * 2) The values of the jacobian (if "values" is not NULL) + */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol, + Ipopt::Number* values); + + /** Method to return: + * 1) The structure of the hessian of the lagrangian (if "values" is NULL) + * 2) The values of the hessian of the lagrangian (if "values" is not NULL) + */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index* iRow, + Ipopt::Index* jCol, Ipopt::Number* values); + + //@} + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method for asking for the strengthened bound. */ + Ipopt::Number StrengthenedBound() const; + + private: + /**@name Methods to block default compiler methods. */ + //@{ + StrengtheningTNLP(); + StrengtheningTNLP(const StrengtheningTNLP&); + StrengtheningTNLP& operator=(const StrengtheningTNLP&); + //@} + + /** TMINLP (with current bounds) for which the cut it to be + * generated */ + const Ipopt::SmartPtr<TMINLP> tminlp_; + + /** Gradient of the (linear) objective function */ + Ipopt::Number* obj_grad_; + + /** Dimension of original problem */ + const Ipopt::Index n_orig_; + + /** Ipopt::Number of constraints in original problem */ + Ipopt::Index m_orig_; + + /** Starting point */ + Ipopt::Number* starting_point_; + + /** Full dimentional x which is used to call the TMINLP + * evaluation routines */ + Ipopt::Number* x_full_; + + /** Lower bounds for constraint variables */ + Ipopt::Number* x_l_; + + /** Upper bounds for constraint variables */ + Ipopt::Number* x_u_; + + /** Ipopt::Index of the constraint */ + const Ipopt::Index constr_index_; + + /** Ipopt::Number of variables appearing in the constraint */ + const Ipopt::Index nvar_constr_; + + /** List of variables appearing on the constraints */ + Ipopt::Index* var_indices_; + + /** Flag indicating if the cut has a lower or upper bound */ + bool lower_bound_; + + /** Flag indicating if we TNLP has been solved successfully */ + bool have_final_bound_; + + /** Final strengthened bound */ + Ipopt::Number strengthened_bound_; + + /** space for original gradient if objective function is handled */ + Ipopt::Number* grad_f_; + + /** Auxilliary method for updating the full x variable */ + void update_x_full(const Ipopt::Number *x); + }; + + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It is given a TNLP solver to solve the internal + * NLPs. */ + CutStrengthener(Ipopt::SmartPtr<TNLPSolver> tnlp_solver, + Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /** Destructor */ + virtual ~CutStrengthener(); + //@} + + /** Method for generating and strenghtening all desired cuts */ + bool ComputeCuts(OsiCuts &cs, + TMINLP* tminlp, + TMINLP2TNLP* problem, + const int gindex, CoinPackedVector& cut, + double& cut_lb, double& cut_ub, + const double g_val, const double g_lb, + const double g_ub, + int n, const double* x, + double infty); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CutStrengthener(); + + /** Copy Constructor */ + CutStrengthener(const CutStrengthener&); + + /** Overloaded Equals Operator */ + void operator=(const CutStrengthener&); + //@} + + /** Method for strengthening one cut. */ + bool StrengthenCut(Ipopt::SmartPtr<TMINLP> tminlp /** current TMINLP */, + int constr_index /** Ipopt::Index number of the constraint to be strengthened, -1 means objective function */, + const CoinPackedVector& row /** Cut to be strengthened */, + int n /** Ipopt::Number of variables */, + const double* x /** solution from node */, + const double* x_l /** Lower bounds for x in which should be valid. */, + const double* x_u /** Upper bounds for x in which should be valid. */, + double& lb, + double& ub); + + /** Method for generating one type of cut (strengthened or disjunctive) */ + bool HandleOneCut(bool is_tight, TMINLP* tminlp, + TMINLP2TNLP* problem, + const double* minlp_lb, + const double* minlp_ub, + const int gindex, CoinPackedVector& cut, + double& cut_lb, double& cut_ub, + int n, const double* x, + double infty); + + /** Object for solving the TNLPs */ + Ipopt::SmartPtr<TNLPSolver> tnlp_solver_; + + /** Type of OA cut strengthener */ + int cut_strengthening_type_; + /** What kind of disjuntion should be done */ + int disjunctive_cut_type_; + /** verbosity level for OA-related output */ + int oa_log_level_; + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/BonDiver.hpp b/thirdparty/linux/include/coin/coin/BonDiver.hpp new file mode 100644 index 0000000..20a9fa6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonDiver.hpp @@ -0,0 +1,424 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 09/01/2007 + +#ifndef BonDiver_H +#define BonDiver_H + +#include "BonminConfig.h" +#include "CbcCompareBase.hpp" +#include "CbcTree.hpp" +#include "IpRegOptions.hpp" +#include "IpOptionsList.hpp" +#include "CbcCompareActual.hpp" +#include "BonRegisteredOptions.hpp" +#include <list> +namespace Bonmin +{ + class BabSetupBase; + /** Class to do diving in the tree. Principle is that branch-and-bound follows current branch of the tree untill it + hits the bottom at which point it goes to the best candidate (according to CbcCompare) on the heap.*/ + class CbcDiver : public CbcTree + { + public: + /// Default constructor. + CbcDiver(); + + ///Copy constructor. + CbcDiver(const CbcDiver &rhs); + + /// Assignment operator. + CbcDiver & operator=(const CbcDiver &rhs); + + /// Destructor. + virtual ~CbcDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return (static_cast<int>(nodes_.size()) + (nextOnBranch_ != NULL) ); + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + + ///Don't know what this is yet? + virtual void endSearch() + { + nextOnBranch_ = NULL; + } + + ///Register the options of the method. + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); + + private: + /** Say if we are cleaning the tree (then only call CbcTree functions).*/ + bool treeCleaning_; + /** Noext node on the branch.*/ + CbcNode * nextOnBranch_; + /** Flag indicating if we want to stop diving based on the guessed + objective value and the cutoff value */ + bool stop_diving_on_cutoff_; + }; + + + /** Class to do probed diving in the tree. + * Principle is that branch-and-bound follows current branch of the tree by exploring the two children at each level + * and continuing the dive on the best one of the two. Untill it + * hits the bottom at which point it goes to the best candidate (according to CbcCompare) on the heap.*/ + class CbcProbedDiver : public CbcTree + { + public: + /// Default constructor. + CbcProbedDiver(); + + ///Copy constructor. + CbcProbedDiver(const CbcProbedDiver &rhs); + + /// Assignment operator. + CbcProbedDiver & operator=(const CbcProbedDiver &rhs); + + /// Destructor. + virtual ~CbcProbedDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return (static_cast<int>(nodes_.size()) + (nextOnBranch_ != NULL) + (candidateChild_ != NULL) ); + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + + ///Don't know what this is yet? + virtual void endSearch() + { + nextOnBranch_ = NULL; + } + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); + + private: + /** Say if we are cleaning the tree (then only call CbcTree functions).*/ + bool treeCleaning_; + /** Next node on the branch.*/ + CbcNode * nextOnBranch_; + /** Candidate child explored.*/ + CbcNode * candidateChild_; + /** Flag indicating if we want to stop diving based on the guessed + objective value and the cutoff value */ + bool stop_diving_on_cutoff_; + }; + + + /** A more elaborate diving class. First there are several modes which can be commanded by the Comparison class below. + In particular can command to dive to find solutions, to try to close the bound as possible or to limit the size of + the tree. + + The diving goes into the tree doing depth-first search until one of the following happens: + \li A prescibed \c maxDiveBacktrack_ number of backtracking are performed. + \li The guessed objective value of the current node is worst than the best incumbent. + \li The depth of the dive is bigger than \c maxDiveDepth_ + + In the first case all the nodes are put on the tree and the next node on top will be the top of the heap, in the + two latter case we just put the node on the tree and backtrack in the list of depth-first search nodes. + + \bug This won't work in a non-convex problem where objective does not decrease down branches. + */ + class CbcDfsDiver :public CbcTree + { + public: + enum ComparisonModes{ + Enlarge/** At the very beginning we might want to enlarge the tree just a bit*/, + FindSolutions, + CloseBound, + LimitTreeSize}; + /// Default constructor. + CbcDfsDiver(); + + ///Copy constructor. + CbcDfsDiver(const CbcDfsDiver &rhs); + + /// Assignment operator. + CbcDfsDiver & operator=(const CbcDfsDiver &rhs); + + /// Destructor. + virtual ~CbcDfsDiver(); + + ///Virtual copy constructor. + virtual CbcTree * clone() const; + + /** \name Heap access and maintenance methods.*/ + /**@{*/ + ///Return top node (next node to process.*/ + virtual CbcNode * top() const; + + /// Add node to the heap. + virtual void push(CbcNode * x); + /// Remove the top node of the heap. + virtual void pop(); + /// Remove the best node from the heap and return it + virtual CbcNode * bestNode(double cutoff); + /** @} */ + + /// \name vector methods + /** @{ */ + /** Test if empty. */ + virtual bool empty(); + /** Give size of the tree.*/ + virtual int size() + { + return static_cast<int>(nodes_.size()) + diveListSize_; + } + /** @} */ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + \bug This won't work in a non-convex problem where objective does not decrease down branches. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + +//#ifdef COIN_HAS_BONMIN + ///Register the options of the method. + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /// Initialize the method (get options) + void initialize(BabSetupBase &b); +//#endif + ///Don't know what this is yet? + virtual void endSearch() + {} + + /** Changes the mode of comparison of the tree for "safety reasons" if the mode really changes we always + finish the current dive and put all the node back onto the heap.*/ + void setComparisonMode(ComparisonModes newMode); + /** get the mode of comparison of the tree.*/ + ComparisonModes getComparisonMode() + { + return mode_; + } + protected: + /**Flag to say that we are currently cleaning the tree and should work only + on the heap.*/ + int treeCleaning_; + /** List of the nodes in the current dive.*/ + std::list<CbcNode *> dive_; + /** Record dive list size for constant time access.*/ + int diveListSize_; + /** Depth of the node from which diving was started (we call this node the diving board).*/ + int divingBoardDepth_; + /** Last reported cutoff.*/ + double cutoff_; + /** number of backtracks done in current dive.*/ + int nBacktracks_; + /** \name Parameters of the method.*/ + /** @{ */ + /** Maximum depth until which we'll do a bredth-first-search.*/ + int maxDepthBFS_; + /** Maximum number of backtrack in one dive.*/ + int maxDiveBacktracks_; + /** Maximum depth to go from divingBoard.*/ + int maxDiveDepth_; + /** Current mode of the diving strategy.*/ + ComparisonModes mode_; + /** @} */ + private: + /** Pushes onto heap all the nodes with objective value > cutoff. */ + void pushDiveOntoHeap(double cutoff); + + }; + + class DiverCompare : public CbcCompareBase + { + public: + // Default Constructor + DiverCompare (): + CbcCompareBase(), + diver_(NULL), + numberSolToStopDive_(5), + numberNodesToLimitTreeSize_(1000000), + comparisonDive_(NULL), + comparisonBound_(NULL) + {} + + + virtual ~DiverCompare() + { + delete comparisonDive_; + delete comparisonBound_; + } + + // Copy constructor + DiverCompare ( const DiverCompare & rhs): + CbcCompareBase(rhs), + diver_(rhs.diver_), + numberSolToStopDive_(rhs.numberSolToStopDive_), + numberNodesToLimitTreeSize_(rhs.numberNodesToLimitTreeSize_), + comparisonDive_(rhs.comparisonDive_->clone()), + comparisonBound_(rhs.comparisonBound_->clone()) + {} + + // Assignment operator + DiverCompare & operator=( const DiverCompare& rhs) + { + if (this != &rhs) { + CbcCompareBase::operator=(rhs); + diver_ = rhs.diver_; + numberSolToStopDive_ = rhs.numberSolToStopDive_; + numberNodesToLimitTreeSize_ = rhs.numberNodesToLimitTreeSize_; + delete comparisonDive_; + delete comparisonBound_; + comparisonDive_ = NULL; + comparisonBound_ = NULL; + if (rhs.comparisonDive_) comparisonDive_ = rhs.comparisonDive_->clone(); + if (rhs.comparisonBound_) comparisonBound_ = rhs.comparisonBound_->clone(); + } + return *this; + } + + /// Clone + virtual CbcCompareBase * clone() const + { + return new DiverCompare(*this); + } + + /// This is test function + virtual bool test (CbcNode * x, CbcNode * y); + + /// Called after each new solution + virtual bool newSolution(CbcModel * model); + + /// Called after each new solution + virtual bool newSolution(CbcModel * model, + double objectiveAtContinuous, + int numberInfeasibilitiesAtContinuous); + + /** Called 1000 nodes. + * Return true if want tree re-sorted.*/ + virtual bool every1000Nodes(CbcModel * model,int numberNodes); + + /** Set the dfs diver to use.*/ + void setDiver(CbcDfsDiver * diver) + { + diver_ = diver; + } + + /** Set numberSolToStopDive_ */ + void setNumberSolToStopDive(int val) + { + numberSolToStopDive_ = val; + } + + /** Set numberNodesToLimitTreeSize_.*/ + void setNumberNodesToLimitTreeSize(int val) + { + numberNodesToLimitTreeSize_ = val; + } + + /** Set comparison method when diving.*/ + void setComparisonDive(const CbcCompareBase & val) + { + comparisonDive_ = val.clone(); + } + /** Set comparison method when closing bound.*/ + void setComparisonBound(const CbcCompareBase & val) + { + comparisonBound_ = val.clone(); + } + private: + /** Pointer to the CbcDfsDiver handling the tree.*/ + CbcDfsDiver * diver_; + /** Number of solution before we command diver_ to stop diving.*/ + int numberSolToStopDive_; + /** Number of nodes before we command diver_ to limit the tree size.*/ + int numberNodesToLimitTreeSize_; + /** Comparison method used in diving mode*/ + CbcCompareBase * comparisonDive_; + /** Comparison method used bound mode*/ + CbcCompareBase * comparisonBound_; + /** Comparison method used when limit tree size.*/ + CbcCompareDepth comparisonDepth_; + }; + +}/* Ends bonmin namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonDummyHeuristic.hpp b/thirdparty/linux/include/coin/coin/BonDummyHeuristic.hpp new file mode 100644 index 0000000..5c3d7fa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonDummyHeuristic.hpp @@ -0,0 +1,53 @@ +// (C) Copyright Carnegie Mellon University 2005 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + +#ifndef BonDummyHeuristic_HPP +#define BonDummyHeuristic_HPP +#include "BonOsiTMINLPInterface.hpp" + +#include "CbcHeuristic.hpp" +namespace Bonmin +{ + class DummyHeuristic : public CbcHeuristic + { + public: + /// Default constructor + DummyHeuristic(OsiTMINLPInterface * si = NULL); + /// Usefull constructor + DummyHeuristic(CbcModel &model, OsiTMINLPInterface * si = NULL); + ///Copy constructor + DummyHeuristic( const DummyHeuristic ©): + CbcHeuristic(copy), + nlp_(copy.nlp_), + knowsSolution(copy.knowsSolution) + {} + /// Set nlp_ + void setNlp(OsiTMINLPInterface * si); + /// heuristic method + virtual int solution(double &solutionValue, double *betterSolution); + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + virtual CbcHeuristic * clone()const + { + return new DummyHeuristic(*this); + } + virtual void resetModel(CbcModel*) + {} + virtual bool shouldHeurRun(int whereFrom){ + return true;} + private: + /// Pointer to the Ipopt interface + OsiTMINLPInterface * nlp_; + /// Do I have a solution? + bool knowsSolution; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonDummyPump.hpp b/thirdparty/linux/include/coin/coin/BonDummyPump.hpp new file mode 100644 index 0000000..45316c0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonDummyPump.hpp @@ -0,0 +1,43 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonDummyPump_H +#define BonDummyPump_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class DummyPump:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + DummyPump(); + /** Constructor with setup.*/ + DummyPump(BonminSetup * setup); + + /** Copy constructor.*/ + DummyPump(const DummyPump &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new DummyPump(*this); + } + + /** Destructor*/ + virtual ~DummyPump(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonEcpCuts.hpp b/thirdparty/linux/include/coin/coin/BonEcpCuts.hpp new file mode 100644 index 0000000..8f57038 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonEcpCuts.hpp @@ -0,0 +1,97 @@ +// (C) Copyright International Business Machines (IBM) 2006, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/20/2006 + +#ifndef BonECPCuts_HPP +#define BonECPCuts_HPP + +#include "BonOaDecBase.hpp" +#include "CglCutGenerator.hpp" +namespace Bonmin +{ + class EcpCuts: public OaDecompositionBase + { + public: + EcpCuts(BabSetupBase & b); + + /// Copy constructor + EcpCuts(const EcpCuts & copy): + OaDecompositionBase(copy), + objValue_(copy.objValue_), + numRounds_(copy.numRounds_), + abs_violation_tol_(copy.abs_violation_tol_), + rel_violation_tol_(copy.rel_violation_tol_), + beta_(copy.beta_) + {} + + /// clone + CglCutGenerator * clone() const + { + return new EcpCuts(*this); + } + + /// Destructor + virtual ~EcpCuts() + {} + /** Standard cut generation methods. */ + virtual void generateCuts(const OsiSolverInterface &si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()) const; + double doEcpRounds(OsiSolverInterface &si, + bool leaveSiUnchanged, + double* violation = NULL); + + void setNumRounds(int value) + { + numRounds_ = value; + } + + void setPropabilityFactor(double value) + { + beta_ = value; + } + + void setAbsViolationTolerance(double value) + { + abs_violation_tol_ = value; + } + void setRelViolationTolerance(double value) + { + rel_violation_tol_ = value; + } + + /** Register ecp cuts options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo &info) const + { + throw -1; + } + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const + { + return 0; + } + private: + /** Record obj value at final point of Ecp. */ + mutable double objValue_; + /** Record NLP infeasibility at final point of Ecp */ + mutable double violation_; + /** maximum number of iterations of generation. */ + int numRounds_; + /** absolute tolerance for NLP constraint violation to stop ECP rounds */ + double abs_violation_tol_; + /** relative tolerance for NLP constraint violation to stop ECP rounds */ + double rel_violation_tol_; + /** Factor for probability for skipping cuts */ + double beta_; + }; +} /* end namespace Bonmin.*/ +#endif diff --git a/thirdparty/linux/include/coin/coin/BonExitCodes.hpp b/thirdparty/linux/include/coin/coin/BonExitCodes.hpp new file mode 100644 index 0000000..74234b1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonExitCodes.hpp @@ -0,0 +1,12 @@ +#ifndef BonExitCodes_H +#define BonExitCodes_H + + +namespace Bonmin{ + /** Some error codes for uncatachable errors.*/ +enum ErrorCodes{ + ERROR_IN_AMPL_SUFFIXES = 111, + UNSUPPORTED_CBC_OBJECT/** There is a CbcObject in the model which is not understood by Bonmin.*/ +}; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonFixAndSolveHeuristic.hpp b/thirdparty/linux/include/coin/coin/BonFixAndSolveHeuristic.hpp new file mode 100644 index 0000000..e0c35ea --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonFixAndSolveHeuristic.hpp @@ -0,0 +1,43 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonFixAndSolveHeuristic_H +#define BonFixAndSolveHeuristic_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class FixAndSolveHeuristic:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + FixAndSolveHeuristic(); + /** Constructor with setup.*/ + FixAndSolveHeuristic(BonminSetup * setup); + + /** Copy constructor.*/ + FixAndSolveHeuristic(const FixAndSolveHeuristic &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new FixAndSolveHeuristic(*this); + } + + /** Destructor*/ + virtual ~FixAndSolveHeuristic(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonGuessHeuristic.hpp b/thirdparty/linux/include/coin/coin/BonGuessHeuristic.hpp new file mode 100644 index 0000000..c8c4e6f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonGuessHeuristic.hpp @@ -0,0 +1,46 @@ +// (C) Copyright International Business Machines 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Andreas Waechter IBM 2007-09-01 + +#ifndef BonGuessHeuristic_HPP +#define BonGuessHeuristic_HPP +#include "BonOsiTMINLPInterface.hpp" + +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class GuessHeuristic : public CbcHeuristic + { + public: + /// Usefull constructor + GuessHeuristic(CbcModel &model); + ///Copy constructor + GuessHeuristic( const GuessHeuristic ©): + CbcHeuristic(copy) + {} + + /// heuristic method providing guess, based on pseudo costs + virtual int solution(double &solutionValue, double *betterSolution); + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + virtual CbcHeuristic * clone()const + { + return new GuessHeuristic(*this); + } + virtual void resetModel(CbcModel*) + {} + private: + /// Default constructor + GuessHeuristic(); + + /// Assignment operator + GuessHeuristic & operator=(const GuessHeuristic& rhs); + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDive.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDive.hpp new file mode 100644 index 0000000..71039d8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDive.hpp @@ -0,0 +1,88 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDive_HPP +#define BonHeuristicDive_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class HeuristicDive : public CbcHeuristic + { + public: + /// Default constructor + HeuristicDive(); + + /// Constructor with setup + HeuristicDive(BonminSetup * setup); + + /// Copy constructor + HeuristicDive(const HeuristicDive ©); + + /// Destructor + ~HeuristicDive() {} + + /// Assignment operator + HeuristicDive & operator=(const HeuristicDive & rhs); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Set percentage of integer variables to fix at bounds + void setPercentageToFix(double value) + { percentageToFix_ = value; } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp) = 0; + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + /// Percentage of integer variables to fix at bounds + double percentageToFix_; + + private: + /// How often to do (code can change) + int howOften_; + + }; + + /// checks if the NLP relaxation of the problem is feasible + bool isNlpFeasible(TMINLP2TNLP* minlp, const double primalTolerance); + + /// Adjusts the primalTolerance in case some of the constraints are violated + void adjustPrimalTolerance(TMINLP2TNLP* minlp, double & primalTolerance); +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDiveFractional.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDiveFractional.hpp new file mode 100644 index 0000000..a5efbc6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDiveFractional.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveFractional_H +#define BonHeuristicDiveFractional_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDive.hpp" + +/** DiveFractional class + */ + +namespace Bonmin +{ + class HeuristicDiveFractional : public HeuristicDive { + public: + /// Default Constructor + HeuristicDiveFractional (); + + /// Constructor with setup + HeuristicDiveFractional(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveFractional(const HeuristicDiveFractional ©); + + /// Destructor + ~HeuristicDiveFractional() {} + + /// Assignment operator + HeuristicDiveFractional & operator=(const HeuristicDiveFractional & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDive::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIP.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIP.hpp new file mode 100644 index 0000000..11da60a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIP.hpp @@ -0,0 +1,83 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIP_HPP +#define BonHeuristicDiveMIP_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" +#include "CbcStrategy.hpp" +namespace Bonmin +{ + class SubMipSolver; + class HeuristicDiveMIP : public CbcHeuristic + { + public: +#if 0 + /// Default constructor + HeuristicDiveMIP(); +#endif + + /// Constructor with setup + HeuristicDiveMIP(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIP(const HeuristicDiveMIP ©); + + /// Destructor + ~HeuristicDiveMIP(); + + /// Assignment operator + HeuristicDiveMIP & operator=(const HeuristicDiveMIP & rhs); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Initialize method + void Initialize(BonminSetup * setup); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp) = 0; + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + private: + /// How often to do (code can change) + int howOften_; + /// A subsolver for MIP + SubMipSolver * mip_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPFractional.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPFractional.hpp new file mode 100644 index 0000000..dae7b3f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPFractional.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIPFractional_H +#define BonHeuristicDiveMIPFractional_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDiveMIP.hpp" + +/** DiveMIPFractional class + */ + +namespace Bonmin +{ + class HeuristicDiveMIPFractional : public HeuristicDiveMIP { + public: + /// Default Constructor + HeuristicDiveMIPFractional (); + + /// Constructor with setup + HeuristicDiveMIPFractional(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIPFractional(const HeuristicDiveMIPFractional ©); + + /// Destructor + ~HeuristicDiveMIPFractional() {} + + /// Assignment operator + HeuristicDiveMIPFractional & operator=(const HeuristicDiveMIPFractional & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDiveMIP::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPVectorLength.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPVectorLength.hpp new file mode 100644 index 0000000..c14ba30 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDiveMIPVectorLength.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveMIPVectorLength_H +#define BonHeuristicDiveMIPVectorLength_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDiveMIP.hpp" + +/** DiveMIPVectorLength class + */ + +namespace Bonmin +{ + class HeuristicDiveMIPVectorLength : public HeuristicDiveMIP { + public: + /// Default Constructor + HeuristicDiveMIPVectorLength (); + + /// Constructor with setup + HeuristicDiveMIPVectorLength(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveMIPVectorLength(const HeuristicDiveMIPVectorLength ©); + + /// Destructor + ~HeuristicDiveMIPVectorLength() + { + delete [] columnLength_; + } + + /// Assignment operator + HeuristicDiveMIPVectorLength & operator=(const HeuristicDiveMIPVectorLength & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDiveMIP::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// the number of nonzero elements in each column + int* columnLength_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicDiveVectorLength.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicDiveVectorLength.hpp new file mode 100644 index 0000000..90942a2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicDiveVectorLength.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicDiveVectorLength_H +#define BonHeuristicDiveVectorLength_H + +#include "BonBonminSetup.hpp" +#include "BonHeuristicDive.hpp" + +/** DiveVectorLength class + */ + +namespace Bonmin +{ + class HeuristicDiveVectorLength : public HeuristicDive { + public: + /// Default Constructor + HeuristicDiveVectorLength (); + + /// Constructor with setup + HeuristicDiveVectorLength(BonminSetup * setup); + + /// Copy constructor + HeuristicDiveVectorLength(const HeuristicDiveVectorLength ©); + + /// Destructor + ~HeuristicDiveVectorLength() + { + delete [] columnLength_; + } + + /// Assignment operator + HeuristicDiveVectorLength & operator=(const HeuristicDiveVectorLength & rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + HeuristicDive::setSetup(setup); + Initialize(setup->options()); + } + + /// sets internal variables + virtual void setInternalVariables(TMINLP2TNLP* minlp); + + /// Selects the next variable to branch on + /** If bestColumn = -1, it means that no variable was found + */ + virtual void selectVariableToBranch(TMINLP2TNLP* minlp, + const vector<int> & integerColumns, + const double* newSolution, + int& bestColumn, + int& bestRound); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// the number of nonzero elements in each column + int* columnLength_; + + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicFPump.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicFPump.hpp new file mode 100644 index 0000000..e8381a0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicFPump.hpp @@ -0,0 +1,111 @@ +// Copyright (C) 2007, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Joao P. Goncalves, International Business Machines Corporation +// +// Date : November 12, 2007 + +#ifndef BonHeuristicFPump_HPP +#define BonHeuristicFPump_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin +{ + class HeuristicFPump : public CbcHeuristic + { + public: + /// Default constructor + HeuristicFPump(); + + /// Constructor with setup + HeuristicFPump(BonminSetup * setup); + + /// Copy constructor + HeuristicFPump(const HeuristicFPump ©); + + /// Destructor + ~HeuristicFPump() {} + + /// Assignment operator + HeuristicFPump & operator=(const HeuristicFPump & rhs); + + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicFPump(*this); + } + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + void setSetup(BonminSetup * setup){ + setup_ = setup; + Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + /// Performs heuristic with add cust + virtual int solution(double &solutionValue, double *betterSolution, OsiCuts & cs) + { + return solution(solutionValue, betterSolution); + } + + /** Register the options for this heuristic */ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + /** Norm of the objective function - either 1 or 2 */ + int objective_norm_; + + /// To enable advanced unstable stuff + int enableAdvanced_; + }; + + class RoundingFPump + { + public: + /// Default constructor + RoundingFPump(TMINLP2TNLP* minlp); + + /// Destructor + ~RoundingFPump(); + + /// Rounds the solution + void round(const double integerTolerance, + const double primalTolerance, + double* solution); + + private: + /// gutsOfConstructor + void gutsOfConstructor(); + + /// Pointer to problem + TMINLP2TNLP* minlp_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Jacobian of g + std::vector<std::pair<int, int> >* col_and_jac_g_; + + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicLocalBranching.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicLocalBranching.hpp new file mode 100644 index 0000000..ac56a56 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicLocalBranching.hpp @@ -0,0 +1,59 @@ +// (C) Copyright CNRS and International Business Machines Corporation +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// Joao Goncalves, International Business Machines Corporation +// +// Date : 06/18/2008 + +#ifndef BonHeuristicLocalBranching_H +#define BonHeuristicLocalBranching_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class HeuristicLocalBranching:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + HeuristicLocalBranching(); + /** Constructor with setup.*/ + HeuristicLocalBranching(BonminSetup * setup); + + /** Copy constructor.*/ + HeuristicLocalBranching(const HeuristicLocalBranching &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicLocalBranching(*this); + } + + /** Destructor*/ + virtual ~HeuristicLocalBranching(); + + /// Update model + virtual void setModel(CbcModel * model); + + /// Validate model i.e. sets when_ to 0 if necessary + virtual void validate(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + private: + /// How often to do (code can change) + int howOften_; + /// Number of solutions so we can do something at solution + int numberSolutions_; + + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonHeuristicRINS.hpp b/thirdparty/linux/include/coin/coin/BonHeuristicRINS.hpp new file mode 100644 index 0000000..5dcc68b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonHeuristicRINS.hpp @@ -0,0 +1,55 @@ +// (C) Copyright CNRS and International Business Machines Corporation +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// Joao Goncalves, International Business Machines Corporation +// +// Date : 06/18/2008 + +#ifndef BonHeuristicRINS_H +#define BonHeuristicRINS_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class HeuristicRINS:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + HeuristicRINS(); + /** Constructor with setup.*/ + HeuristicRINS(BonminSetup * setup); + + /** Copy constructor.*/ + HeuristicRINS(const HeuristicRINS &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new HeuristicRINS(*this); + } + + /** Destructor*/ + virtual ~HeuristicRINS(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /// Sets how often to do it + inline void setHowOften(int value) + { howOften_=value;} + + private: + /// How often to do (code can change) + int howOften_; + /// Number of solutions so we can do something at solution + int numberSolutions_; + + }; + +}/* Ends Bonmin namepace.*/ +#endif diff --git a/thirdparty/linux/include/coin/coin/BonIpoptInteriorWarmStarter.hpp b/thirdparty/linux/include/coin/coin/BonIpoptInteriorWarmStarter.hpp new file mode 100644 index 0000000..d477548 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonIpoptInteriorWarmStarter.hpp @@ -0,0 +1,103 @@ +// (C) Copyright International Business Machines Corporation 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: BonIpoptInteriorWarmStarter.hpp 2106 2015-01-20 10:33:55Z stefan $ +// +// Authors: Andreas Waechter IBM 2006-03-02 + +#ifndef __IPOPTINTERIORWARMSTARTER_HPP__ +#define __IPOPTINTERIORWARMSTARTER_HPP__ + +#include "IpSmartPtr.hpp" +#include "IpNLP.hpp" +#include <vector> + +namespace Bonmin +{ + class IpoptInteriorWarmStarter : public Ipopt::ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor. We give it the values of the current bounds so that + * it can figure out which variables are fixed for this NLP. */ + IpoptInteriorWarmStarter(Ipopt::Index n, const Ipopt::Number* x_L, const Ipopt::Number* x_u, + Ipopt::Number nlp_lower_bound_inf, + Ipopt::Number nlp_upper_bound_inf, + bool store_several_iterates); + + /** Default destructor */ + ~IpoptInteriorWarmStarter(); + //@} + + /** Method for possibly storing another iterate during the current + * optimizatin for possible use for a warm start for a new + * problem */ + bool UpdateStoredIterates(Ipopt::AlgorithmMode mode, + const Ipopt::IpoptData& ip_data, + Ipopt::IpoptCalculatedQuantities& ip_cq); + + /** Method for doing whatever needs to be done after the parent NLP + * has been solved */ + bool Finalize(); + + /** Method for computing the initial point based on the stored + * information */ + bool WarmStartIterate(Ipopt::Index n, const Ipopt::Number* x_l_new, const Ipopt::Number* x_u_new, + Ipopt::IteratesVector& warm_start_iterate); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor. */ + IpoptInteriorWarmStarter(); + + /** Copy Constructor */ + IpoptInteriorWarmStarter(const IpoptInteriorWarmStarter&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptInteriorWarmStarter&); + //@} + + //@{ + /** Value for a lower bound that denotes -infinity */ + Ipopt::Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Ipopt::Number nlp_upper_bound_inf_; + /** Flag indicating whether more than one iterate is to be + * stored. */ + bool store_several_iterates_; + //@} + + /** @name Copy of the bounds for the previously solved NLP. This is + * required to find out the remapping for fixed variables, and it + * might also help to see how large the perturbation of the new + * problem is. */ + //@{ + Ipopt::Index n_; + Ipopt::Number* x_l_prev_; + Ipopt::Number* x_u_prev_; + //@} + + /** @name Selected Iterates and quantities from the previous + * optimization */ + //@{ + Ipopt::Index n_stored_iterates_; + std::vector<Ipopt::Index> stored_iter_; + std::vector<Ipopt::SmartPtr<const Ipopt::IteratesVector> > stored_iterates_; + std::vector<Ipopt::Number> stored_mu_; + std::vector<Ipopt::Number> stored_nlp_error_; + std::vector<Ipopt::Number> stored_primal_inf_; + std::vector<Ipopt::Number> stored_dual_inf_; + std::vector<Ipopt::Number> stored_compl_; + //@} + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonIpoptSolver.hpp b/thirdparty/linux/include/coin/coin/BonIpoptSolver.hpp new file mode 100644 index 0000000..0f96693 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonIpoptSolver.hpp @@ -0,0 +1,188 @@ +// (C) Copyright International Business Machines (IBM) 2005, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, IBM +// +// Date : 26/09/2006 + +#ifndef IpoptSolver_HPP +#define IpoptSolver_HPP +#include "BonTNLPSolver.hpp" +#include "IpIpoptApplication.hpp" + + +namespace Bonmin +{ + class IpoptSolver: public TNLPSolver + { + public: + class UnsolvedIpoptError: public TNLPSolver::UnsolvedError + { + public: + UnsolvedIpoptError(int errorNum, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name): + TNLPSolver::UnsolvedError(errorNum, problem, name) + {} + virtual const std::string& errorName() const; + + virtual const std::string& solverName() const; + virtual ~UnsolvedIpoptError() + {} + private: + static std::string errorNames [17]; + static std::string solverName_; + }; + + virtual UnsolvedError * newUnsolvedError(int num, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name) + { + return new UnsolvedIpoptError(num, problem, name); + } + + + + /// Constructor + IpoptSolver(bool createEmpty = false); + +/// Constructor with Passed in journalist, registered options, options + IpoptSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + +/// Constructor with Passed in journalist, registered options, options + IpoptSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist); + + /// Copy constructor + IpoptSolver(const IpoptSolver &other); + + ///virtual copy constructor + virtual Ipopt::SmartPtr<TNLPSolver> clone(); + + /// Virtual destructor + virtual ~IpoptSolver(); + + /** Initialize the TNLPSolver (read options from params_file) + */ + virtual bool Initialize(std::string params_file); + + /** Initialize the TNLPSolver (read options from istream is) + */ + virtual bool Initialize(std::istream& is); + + /** @name Solve methods */ + //@{ + /// Solves a problem expresses as a TNLP + virtual TNLPSolver::ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp); + + /// Resolves a problem expresses as a TNLP + virtual TNLPSolver::ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp); + + /// Set the warm start in the solver + virtual bool setWarmStart(const CoinWarmStart * warm, + Ipopt::SmartPtr<TMINLP2TNLP> tnlp); + + /// Get warm start used in last optimization + virtual CoinWarmStart * getUsedWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const; + + + /// Get the warm start form the solver + virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr<Bonmin::TMINLP2TNLP> tnlp) const; + + virtual CoinWarmStart * getEmptyWarmStart() const; + + /** Check that warm start object is valid.*/ + virtual bool warmStartIsValid(const CoinWarmStart * ws) const; + + /// Enable the warm start options in the solver + virtual void enableWarmStart(); + + /// Disable the warm start options in the solver + virtual void disableWarmStart(); + + //@} + + /// Get the CpuTime of the last optimization. + virtual double CPUTime(); + + /// Get the iteration count of the last optimization. + virtual int IterationCount(); + + /// turn off all output from the solver + virtual void setOutputToDefault(); + /// turn on all output from the solver + virtual void forceSolverOutput(int log_level); + + /// Get the solver name + virtual std::string & solverName() + { + return solverName_; + } + + /// Register this solver options into passed roptions + static void RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions) + { + Ipopt::IpoptApplication::RegisterAllIpoptOptions(GetRawPtr(roptions)); + } + + + + /// Return status of last optimization + Ipopt::ApplicationReturnStatus getOptStatus() const + { + return optimizationStatus_; + } + + Ipopt::IpoptApplication& getIpoptApp() + { + return *app_; + } + + virtual int errorCode() const + { + return (int) optimizationStatus_; + } + private: + /** Set default Ipopt parameters for use in a MINLP */ + void setMinlpDefaults(Ipopt::SmartPtr< Ipopt::OptionsList> Options); + + /** get Bonmin return status from Ipopt one. */ + TNLPSolver::ReturnStatus solverReturnStatus(Ipopt::ApplicationReturnStatus optimization_status) const; + + /** Ipopt application */ + Ipopt::SmartPtr<Ipopt::IpoptApplication> app_; + /** return status of last optimization.*/ + Ipopt::ApplicationReturnStatus optimizationStatus_; + //@} + + + /** Flag to indicate if last problem solved had 0 dimension. (in this case Ipopt was not called).*/ + bool problemHadZeroDimension_; + + /** Warm start strategy : + <ol> + <li> no warm start,</li> + <li> simple warm start (optimal point),</li> + <li> more elaborate strategies (interior point...).</li> + </ol> + */ + int warmStartStrategy_; + + /** flag remembering if we want to use warm start option */ + bool enable_warm_start_; + + /** flag remembering if we have call the Optimize method of the + IpoptInterface before */ + bool optimized_before_; + //name of solver (Ipopt) + static std::string solverName_; + }; +} +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonIpoptWarmStart.hpp b/thirdparty/linux/include/coin/coin/BonIpoptWarmStart.hpp new file mode 100644 index 0000000..fffc3e3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonIpoptWarmStart.hpp @@ -0,0 +1,148 @@ +// (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 02/15/2006 + + +#ifndef IpoptWarmStart_HPP +#define IpoptWarmStart_HPP +#include "CoinWarmStartBasis.hpp" +#include "CoinWarmStartPrimalDual.hpp" +#include "BonIpoptInteriorWarmStarter.hpp" + + +namespace Bonmin +{ + class TMINLP2TNLP; + + /** \brief Class for storing warm start informations for Ipopt.<br> + * This class inherits from CoinWarmStartPrimalDual, because that's what + * this warmstart really is. <br> + * For practical reason (integration in Cbc) this class also inherits from + * CoinWarmStartBasis. <br> + * This class stores a starting point (primal and dual values) for Ipopt. + * <br> + * <p> + * The primal part of the base class contains the value of each primal + * variable. + * <p> + * The dual part of the base class consists of three sections (the number of + * values is 2*numcols+numrows): + <UL> + <li> First, values for dual variables associated with the lower bound + constraints on structurals, i.e., primal variables (constraints + \f$ l \leq x \f$); + <li> Then values for dual variables associated with upper bound + constraints on structurals (constraints \f$ x \leq u\f$). + <li> the values for dual variables associated with regular constraints + (constraints \f$ g(x) \leq 0 \f$) + </UL> + */ + class IpoptWarmStart : + public virtual CoinWarmStartPrimalDual, public virtual CoinWarmStartBasis + { + public: + + /// Default constructor + IpoptWarmStart(bool empty = 1, int numvars = 0, int numcont = 0); + /// Usefull constructor, stores the current optimum of ipopt + IpoptWarmStart(const Ipopt::SmartPtr<TMINLP2TNLP> tnlp, + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter); + /// Another usefull constructor, stores the passed point + IpoptWarmStart(int primal_size, int dual_size, + const double * primal, const double * dual); + /// Copy constructor + IpoptWarmStart( const IpoptWarmStart &other, bool ownValues = 1); + /// A constructor from a CoinWarmStartPrimalDual + IpoptWarmStart(const CoinWarmStartPrimalDual& pdws); + /// Abstract destructor + virtual ~IpoptWarmStart(); + + /// `Virtual constructor' + virtual CoinWarmStart *clone() const + { + return new IpoptWarmStart(*this,1); + } + + /** Generate the "differences" between two IpoptWarmStart.*/ + virtual CoinWarmStartDiff* + generateDiff(const CoinWarmStart *const oldCWS) const; + /** \brief Apply 'differences' to an Ipopt warm start. + * What this actually does is get a copy to the vector of values stored + in IpoptWarmStartDiff.*/ + virtual void + applyDiff (const CoinWarmStartDiff *const cwsdDiff); + + /** Accessor to warm start information obecjt */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const + { + return warm_starter_; + } + + /// flush the starting point + void flushPoint(); + + ///Is this an empty warm start? + bool empty() const + { + return empty_; + } + private: + /** warm start information object */ + mutable Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_; + ///Say if warm start is empty + bool empty_; + }; + + //########################################################################### + + /** \brief Diff class for IpoptWarmStart. + * Actually get the differences from CoinWarmStartBasis and stores the + whole vector of values. + \todo Find a way to free unused values. + */ + class IpoptWarmStartDiff : public CoinWarmStartPrimalDualDiff + { + public: + friend class IpoptWarmStart; + /** Useful constructor; takes over the data in \c diff */ + IpoptWarmStartDiff(CoinWarmStartPrimalDualDiff * diff, + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter): + CoinWarmStartPrimalDualDiff(), + warm_starter_(NULL)//(warm_starter) + { + CoinWarmStartPrimalDualDiff::swap(*diff); + } + /** Copy constructor. */ + IpoptWarmStartDiff(const IpoptWarmStartDiff &other): + CoinWarmStartPrimalDualDiff(other), + warm_starter_(NULL /*other.warm_starter_*/) {} + + /// Abstract destructor + virtual ~IpoptWarmStartDiff() {} + + /// `Virtual constructor' + virtual CoinWarmStartDiff *clone() const + { + return new IpoptWarmStartDiff(*this); + } + + /** Accessor to warm start information obecjt */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter() const + { + return warm_starter_; + } + void flushPoint(); + private: + + /** warm start information object */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter_; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonLinearCutsGenerator.hpp b/thirdparty/linux/include/coin/coin/BonLinearCutsGenerator.hpp new file mode 100644 index 0000000..4c80719 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonLinearCutsGenerator.hpp @@ -0,0 +1,75 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonLinearCutsGenerator_H +#define BonLinearCutsGenerator_H + +#include "CglCutGenerator.hpp" +#include "CoinSmartPtr.hpp" +#include "BonOuterApprox.hpp" +#include "BonBonminSetup.hpp" +#include <list> + +namespace Bonmin { +class LinearCutsGenerator : public CglCutGenerator { + public: + /** Type for cut generation method with its frequency and string identification. */ + struct CuttingMethod : public Coin::ReferencedObject + { + int frequency; + std::string id; + CglCutGenerator * cgl; + bool atSolution; + bool normal; + CuttingMethod(): + atSolution(false), + normal(true) + {} + + CuttingMethod(const CuttingMethod & other): + frequency(other.frequency), + id(other.id), + cgl(other.cgl), + atSolution(other.atSolution), + normal(other.normal) + {} + }; + LinearCutsGenerator(): + CglCutGenerator(), + methods_(){ + } + + + LinearCutsGenerator(const LinearCutsGenerator & other): + CglCutGenerator(other), + methods_(other.methods_){ + } + + CglCutGenerator * clone() const { + return new LinearCutsGenerator(*this); + } + + virtual ~LinearCutsGenerator(){ + } + + bool needsOptimalBasis() { return false;} + + void initialize(BabSetupBase& s); + + void generateCuts(const OsiSolverInterface &solver, OsiCuts &cs, + const CglTreeInfo info = CglTreeInfo()); + + private: + std::list<Coin::SmartPtr<CuttingMethod> > methods_; +}; + +}/* Ends Bonmin namespace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonLocalSolverBasedHeuristic.hpp b/thirdparty/linux/include/coin/coin/BonLocalSolverBasedHeuristic.hpp new file mode 100644 index 0000000..3f935e6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonLocalSolverBasedHeuristic.hpp @@ -0,0 +1,102 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 06/18/2008 + +#ifndef BonLocalSolverBasedHeuristic_H +#define BonLocalSolverBasedHeuristic_H +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" + +namespace Bonmin { + class LocalSolverBasedHeuristic : public CbcHeuristic { + public: + /** Default constructor.*/ + LocalSolverBasedHeuristic(); + + /** Constructor with setup.*/ + LocalSolverBasedHeuristic(BonminSetup * setup); + + /** Copy constructor.*/ + LocalSolverBasedHeuristic(const LocalSolverBasedHeuristic & other); + + /** Destructor.*/ + ~LocalSolverBasedHeuristic(); + + /** Virtual copy constructor.*/ + virtual CbcHeuristic * clone() const = 0; + + /// Assignment operator + LocalSolverBasedHeuristic & operator=(const LocalSolverBasedHeuristic& rhs); + +#if 0 + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model){throw -1;} +#endif + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + void setSetup(BonminSetup * setup){ + setup_ = setup; + Initialize(setup_->options()); + } + /** Performs heuristic */ + virtual int solution(double & objectiveValue, + double * newSolution)=0; + + /** Performs heuristic which adds cuts */ + virtual int solution(double & objectiveValue, + double * newSolution, + OsiCuts & cs) {return 0;} + + + /** Do a local search based on setup and passed solver.*/ + int doLocalSearch(OsiTMINLPInterface * solver, + double *solution, + double & solValue, + double cutoff, std::string prefix = "local_solver.") const; + + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Setup the defaults.*/ + virtual void setupDefaults(Ipopt::SmartPtr<Ipopt::OptionsList> options); + + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const std::string &value); + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const double &value); + + static void changeIfNotSet(Ipopt::SmartPtr<Ipopt::OptionsList> options, + std::string prefix, + const std::string &option, + const int &value); + private: + /** Time limit in local search.*/ + double time_limit_; + /** maximal number of nodes in local search.*/ + int max_number_nodes_; + /** Maximal number of solutions in local search.*/ + int max_number_solutions_; + }; +} /** ends namespace Bonmin.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonLpBranchingSolver.hpp b/thirdparty/linux/include/coin/coin/BonLpBranchingSolver.hpp new file mode 100644 index 0000000..9e10172 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonLpBranchingSolver.hpp @@ -0,0 +1,80 @@ +// Copyright (C) 2006, 2007 International Business Machines +// Corporation and others. All Rights Reserved. +#ifndef BonLpBranchingSolver_H +#define BonLpBranchingSolver_H + +#include "BonStrongBranchingSolver.hpp" +#include "BonEcpCuts.hpp" + +namespace Bonmin +{ + + /** Implementation of BonChooseVariable for curvature-based braching. + */ + + class LpBranchingSolver : public StrongBranchingSolver + { + + public: + + /// Constructor from setup + LpBranchingSolver (BabSetupBase *b); + /// Copy constructor + LpBranchingSolver (const LpBranchingSolver &); + + /// Assignment operator + LpBranchingSolver & operator= (const LpBranchingSolver& rhs); + + /// Destructor + virtual ~LpBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface); + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface); + + void setMaxCuttingPlaneIter(int num) + { + maxCuttingPlaneIterations_ = num; + } + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /// Default Constructor + LpBranchingSolver (); + + /// Linear solver + OsiSolverInterface* lin_; + + /// Warm start object for linear solver + CoinWarmStart* warm_; + + /// Ecp cut generate + EcpCuts* ecp_; + + /// Number of maximal ECP cuts + int maxCuttingPlaneIterations_; + + /// absolute tolerance for ECP cuts + double abs_ecp_tol_; + + /// relative tolerance for ECP cuts + double rel_ecp_tol_; + + + enum WarmStartMethod { + Basis=0 /** Use basis*/, + Clone /** clone problem*/ + }; + /// Way problems are warm started + WarmStartMethod warm_start_mode_; + }; + +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonMilpRounding.hpp b/thirdparty/linux/include/coin/coin/BonMilpRounding.hpp new file mode 100644 index 0000000..94f8723 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonMilpRounding.hpp @@ -0,0 +1,74 @@ +// Copyright (C) 2010, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami CNRS +// +// Date : May, 26 2010 + +#ifndef BonMilpRounding_HPP +#define BonMilpRounding_HPP +#include "BonOsiTMINLPInterface.hpp" +#include "BonBonminSetup.hpp" +#include "CbcHeuristic.hpp" +#include "CbcStrategy.hpp" +#include "OsiCuts.hpp" + +namespace Bonmin +{ + class SubMipSolver; + class MilpRounding : public CbcHeuristic + { + public: + + /// Constructor with setup + MilpRounding(BonminSetup * setup); + + /// Copy constructor + MilpRounding(const MilpRounding ©); + + /// Destructor + ~MilpRounding(); + + /// Assignment operator + MilpRounding & operator=(const MilpRounding & rhs); + + /// Clone + virtual CbcHeuristic * clone() const{ + return new MilpRounding(*this); + } + + /// Initialize method + void Initialize(BonminSetup * setup); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model){ + setModel(model); + } + + /** Change setup used for heuristic.*/ + virtual void setSetup(BonminSetup * setup){ + setup_ = setup; + // Initialize(setup_->options()); + } + + /// Performs heuristic + virtual int solution(double &solutionValue, double *betterSolution); + + + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + protected: + /** Setup to use for local searches (will make copies).*/ + BonminSetup * setup_; + + private: + /// How often to do (code can change) + int howOften_; + /// A subsolver for MIP + SubMipSolver * mip_; + + OsiCuts noGoods; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOACutGenerator2.hpp b/thirdparty/linux/include/coin/coin/BonOACutGenerator2.hpp new file mode 100644 index 0000000..c098c9b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOACutGenerator2.hpp @@ -0,0 +1,56 @@ +// (C) Copyright Carnegie Mellon University 2005 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + + +#ifndef BonOACutGenerator2_HPP +#define BonOACutGenerator2_HPP +#include "BonOaDecBase.hpp" + +namespace Bonmin +{ + /** Class to perform OA in its classical form.*/ + class OACutGenerator2 : public OaDecompositionBase + { + public: + /// Constructor with basic setup + OACutGenerator2(BabSetupBase & b); + + /// Copy constructor + OACutGenerator2(const OACutGenerator2 ©) + : + OaDecompositionBase(copy), + subMip_(new SubMipSolver (*copy.subMip_)) + {} + /// Destructor + ~OACutGenerator2(); + + void setStrategy(const CbcStrategy & strategy) + { + parameters_.setStrategy(strategy); + } + + virtual CglCutGenerator * clone() const + { + return new OACutGenerator2(*this); + } + /** Register OA options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo & info) const; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const; + + private: + SubMipSolver * subMip_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOAMessages.hpp b/thirdparty/linux/include/coin/coin/BonOAMessages.hpp new file mode 100644 index 0000000..cfe3272 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOAMessages.hpp @@ -0,0 +1,44 @@ +// (C) Copyright Carnegie Mellon University 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 07/15/2005 + +#ifndef OaMessages_H +#define OaMessages_H +#include "CoinMessage.hpp" + +namespace Bonmin +{ + enum OA_Message{ + FEASIBLE_NLP, + INFEASIBLE_NLP, + UPDATE_UB, + SOLVED_LOCAL_SEARCH, + LOCAL_SEARCH_ABORT, + UPDATE_LB, + ABORT, + OASUCCESS, + OAABORT, + OA_STATS, + LP_ERROR, + PERIODIC_MSG, + FP_DISTANCE, + FP_MILP_VAL, + FP_MAJOR_ITERATION, + FP_MINOR_ITERATION, + DUMMY_END + }; + + /** Output messages for Outer approximation cutting planes */ + class OaMessages : public CoinMessages + { + public: + OaMessages(); + }; + +} //end namespace Bonmin +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOaDecBase.hpp b/thirdparty/linux/include/coin/coin/BonOaDecBase.hpp new file mode 100644 index 0000000..61156f7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOaDecBase.hpp @@ -0,0 +1,297 @@ +// (C) Copyright International Business Machines (IBM) 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/07/2006 +#ifndef BonOaDecBase_HPP +#define BonOaDecBase_HPP +#include "BonSubMipSolver.hpp" +#include "CglCutGenerator.hpp" +#include "BonBabSetupBase.hpp" +#include "BonOAMessages.hpp" +#include "CbcModel.hpp" + +#include "CbcStrategy.hpp" + +#include "CoinTime.hpp" +#include "OsiAuxInfo.hpp" +#include "OsiBranchingObject.hpp" +#include <iostream> +#include "BonBabInfos.hpp" +namespace Bonmin +{ + /** Base class for OA algorithms.*/ + class OaDecompositionBase : public CglCutGenerator + { + public: + + + /** Small class to manipulatee various things in an OsiSolverInterface and restore them. + The OsiSolverInterface manipulated may already exist or may be cloned from another one.*/ + class solverManip + { + public: + /** Constructor. */ + solverManip(OsiSolverInterface *si , bool saveNumRows=true, + bool saveBasis=true, bool saveBounds=false, + bool saveCutoff = false, bool resolve=true); + + /** Constructor which clone an other interface. */ + solverManip(const OsiSolverInterface & si); + /** Destructor. */ + ~solverManip(); + /** Restore solver. */ + void restore(); + + /** Get pointer to solver interface. */ + OsiSolverInterface * si() + { + return si_; + } + + /** Set objects.*/ + void setObjects(OsiObject ** objects, int nObjects) + { + objects_ = objects; + nObjects_ = nObjects; + } + + private: + /** Interface saved. */ + OsiSolverInterface * si_; + /** Initial number of rows (-1 if don't save). */ + int initialNumberRows_; + + /** Initial lower bounds. */ + double * colLower_; + + /** Initial Upper bounds.*/ + double * colUpper_; + + /** Inital basis. */ + CoinWarmStart * warm_; + + /** Initial cutoff. */ + double cutoff_; + + /** delete si_ ? */ + bool deleteSolver_; + + /// Some objects the feasiblitiy of which to verify. + OsiObject * * objects_; + /// Number of objects.*/ + int nObjects_; + /** \name Cached info from solver interface.*/ + /** @{ */ + /** Number of columns. */ + int numcols_; + /** Number of rows. */ + int numrows_; + /** Lower bounds on variables.*/ + const double * siColLower_; + /** Upper bounds on variables. */ + const double * siColUpper_; + + void getCached(); + /** @} */ + }; + + /// New usefull constructor + OaDecompositionBase(BabSetupBase &b, bool leaveSiUnchanged, + bool reassignLpsolver); + + /// Copy constructor + OaDecompositionBase(const OaDecompositionBase & copy); + + + /// Destructor + virtual ~OaDecompositionBase(); + + /** Standard cut generation methods. */ + virtual void generateCuts(const OsiSolverInterface &si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Assign an OsiTMINLPInterface + void assignNlpInterface(OsiTMINLPInterface * nlp) + { + nlp_ = nlp; + } + + /// Assign an OsiTMINLPInterface + void assignLpInterface(OsiSolverInterface * si) + { + lp_ = si; + } + + bool reassignLpsolver() + { + return reassignLpsolver_; + } + /** Set objects.*/ + void setObjects(OsiObject ** objects, int nObjects) + { + objects_ = objects; + nObjects_ = nObjects; + } + /// Set whether to leave the solverinterface unchanged + inline void setLeaveSiUnchanged(bool yesno) + { + leaveSiUnchanged_ = yesno; + } + + /** Parameters for algorithm. */ + struct Parameters + { + /// Add cuts as global + bool global_; + /// Add only violated OA inequalities + bool addOnlyViolated_; + /// cutoff min increase (has to be intialized trhough Cbc) + double cbcCutoffIncrement_; + /// integer tolerance (has to be the same as Cbc's) + double cbcIntegerTolerance_; + /** setting for gap tolerance.*/ + double gap_tol_; + ///Total max number of local searches + int maxLocalSearch_; + /// maximum time for local searches + double maxLocalSearchTime_; + /** sub milp log level.*/ + int subMilpLogLevel_; + /** maximum number of solutions*/ + int maxSols_; + /** Frequency of log. */ + double logFrequency_; + + + /** Constructor with default values */ + Parameters(); + + /** Copy constructor */ + Parameters(const Parameters & other); + + /** Destructor */ + ~Parameters() + { + if (strategy_) delete strategy_; + } + + /** Strategy to apply when using Cbc as MILP sub-solver.*/ + void setStrategy(const CbcStrategy & strategy) + { + if (strategy_) delete strategy_; + strategy_ = strategy.clone(); + } + + const CbcStrategy * strategy() const + { + return strategy_; + } + +private: + /** Strategy to apply when using Cbc as MILP sub-solver.*/ + CbcStrategy * strategy_; + + }; + + Parameters& parameter() + { + return parameters_; + } + + const Parameters& parameter()const + { + return parameters_; + } + + void setLogLevel(int level) + { + handler_->setLogLevel(level); + } + + void setReassignLpSolver(bool v){ + reassignLpsolver_ = v; + } + void passInMessageHandler(CoinMessageHandler * handler); + protected: + void setupMipSolver(BabSetupBase &b, const std::string &prefix); + /// \name Protected helper functions + /**@{ */ + + /** Solve the nlp and do output. + \return true if feasible*/ + bool post_nlp_solve(BabInfo * babInfo, double cutoff) const; + /** @} */ + + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts &cs, solverManip &lpManip, + BabInfo * babInfo, double &, const CglTreeInfo & info) const = 0; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const = 0; + + /// \name Protected members + /** @{ */ + /// Pointer to nlp interface + mutable OsiTMINLPInterface * nlp_; + /// Pointer to setup + BabSetupBase * s_; + ///Number of nlp solved done + mutable int nSolve_; + /// A linear solver + mutable OsiSolverInterface * lp_; + /// Some objects the feasiblitiy of which to verify. + OsiObject * * objects_; + /// Number of objects.*/ + int nObjects_; + ///number of local searches performed + mutable int nLocalSearch_; + /** messages handler. */ + CoinMessageHandler * handler_; + /** Messages for OA */ + CoinMessages messages_; + /** Wether or not we should remove cuts at the end of the procedure */ + bool leaveSiUnchanged_; + /** Do we need to reassign the lp solver with Cbc.*/ + bool reassignLpsolver_; + /** time of construction*/ + double timeBegin_; + /** number of solutions found by OA_decomposition.*/ + mutable int numSols_; + + /** Parameters.*/ + Parameters parameters_; + + /** Saved cuts: in some cases when using OA to check feasible solution algorithm may loop because Cbc removes inactive cuts. + To overcome this we can impose that no OA cut can be discarded by Cbc but this consumes too much memory in some cases. + Here we do it another way: cuts generated at current node are saved if algorithm seems to enter a loop we impose the needed cuts to be kept.*/ + mutable OsiCuts savedCuts_; + /** Store the current node number.*/ + mutable int currentNodeNumber_; + /** @} */ + +#ifdef OA_DEBUG + class OaDebug + { + public: + bool checkInteger(const OsiSolverInterface&nlp, std::ostream & os) const; + + void printEndOfProcedureDebugMessage(const OsiCuts &cs, + bool foundSolution, + double solValue, + double milpBound, + bool isInteger, + bool feasible, + std::ostream & os) const; + }; + + /** debug object. */ + OaDebug debug_; + +#endif + }; +} +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonOaFeasChecker.hpp b/thirdparty/linux/include/coin/coin/BonOaFeasChecker.hpp new file mode 100644 index 0000000..5ef8c14 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOaFeasChecker.hpp @@ -0,0 +1,73 @@ +// (C) Copyright International Business Machines 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 12/26/2006 + + +#ifndef BonOaFeasibilityChecker_HPP +#define BonOaFeasibilityChecker_HPP +#include "BonOaDecBase.hpp" + +namespace Bonmin +{ + /** Class to perform OA in its classical form.*/ + class OaFeasibilityChecker : public OaDecompositionBase + { + public: + /// New usefull constructor + OaFeasibilityChecker(BabSetupBase &b); + /// Copy constructor + OaFeasibilityChecker(const OaFeasibilityChecker ©) + : + OaDecompositionBase(copy), + pol_(copy.pol_), + type_(copy.type_), + cut_count_(copy.cut_count_), + maximum_oa_cuts_(copy.maximum_oa_cuts_) + {} + /// Destructor + ~OaFeasibilityChecker(); + + /** Register OA options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + virtual CglCutGenerator * clone() const + { + return new OaFeasibilityChecker(*this); + } + protected: + /// virtual method which performs the OA algorithm by modifying lp and nlp. + virtual double performOa(OsiCuts & cs, solverManip &lpManip, + BabInfo * babInfo, double &cutoff, const CglTreeInfo & info) const; + /// virutal method to decide if local search is performed + virtual bool doLocalSearch(BabInfo * babInfo) const + { + return 0; + } + + /** See documentation for feas_check_discard_policy option.*/ + enum CutsPolicies { + DetectCycles = 0, + KeepAll, + TreatAsNormal}; + /** Policy for keeping cuts.*/ + CutsPolicies pol_; + + /** See documentation for feas_check_cut_types option.*/ + enum CutsTypes { + OA = 0, + Benders}; + /** Type of cuts.*/ + CutsTypes type_; + + /** Count the total number of cuts generated.*/ + mutable unsigned int cut_count_; + /** maximum number of OA cuts.*/ + unsigned int maximum_oa_cuts_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOaNlpOptim.hpp b/thirdparty/linux/include/coin/coin/BonOaNlpOptim.hpp new file mode 100644 index 0000000..c157b66 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOaNlpOptim.hpp @@ -0,0 +1,116 @@ +// (C) Copyright Carnegie Mellon University 2005, 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, Carnegie Mellon University +// +// Date : 05/26/2005 + +#ifndef BonOaNlpOptim_HPP +#define BonOaNlpOptim_HPP +#include "CglCutGenerator.hpp" +#include "BonOsiTMINLPInterface.hpp" +#include "BonOAMessages.hpp" +#include "BonBabSetupBase.hpp" +namespace Bonmin +{ + /** Generate cuts for the nlp corresponding to continuous relaxation at a node.*/ + class OaNlpOptim : public CglCutGenerator + { + public: + /// Default constructor + OaNlpOptim(OsiTMINLPInterface * si = NULL, + int maxDepth = 10, bool addOnlyViolated = false, + bool globalCuts = true); + + /// Constructor with basic setup + OaNlpOptim(BabSetupBase &b); + /// Copy constructor + OaNlpOptim(const OaNlpOptim ©) + : + CglCutGenerator(copy), + nlp_(copy.nlp_), + maxDepth_(copy.maxDepth_), + nSolve_(0), + addOnlyViolated_(copy.addOnlyViolated_), + global_(copy.global_), + solves_per_level_(copy.solves_per_level_) + { + handler_ = new CoinMessageHandler(); + handler_ -> setLogLevel(copy.handler_->logLevel()); + messages_ = OaMessages(); + } + void passInMessageHandler(const CoinMessageHandler * handler) + { + delete handler_; + handler_ = handler->clone(); + } + ///Abstract constructor + virtual CglCutGenerator * clone() const + { + return new OaNlpOptim(*this); + } + + /** Desctructor */ + virtual ~OaNlpOptim() + { + if (handler_) + delete handler_; + } + + /// Assign an OsiTMINLPInterface + void assignInterface(OsiTMINLPInterface * si); + /// cut generation method + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info); + + + + inline void setMaxDepth(int value) + { + maxDepth_ = value; + } + inline void setAddOnlyViolated(bool yesno) + { + addOnlyViolated_ = yesno; + } + inline void setGlobalCuts(bool yesno) + { + global_ = yesno; + } + inline int getNSolve() + { + return nSolve_; + } + /**set log level */ + void setLogLevel(int value) + { + handler_->setLogLevel(value); + } + + /** Register OaNlpOptim options.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + private: + /// Pointer to the Ipopt interface + OsiTMINLPInterface * nlp_; + + /** maximum depth at which generate cuts*/ + int maxDepth_; + + ///Number of NLP resolution done + mutable int nSolve_; + /** messages handler. */ + CoinMessageHandler * handler_; + /** handler */ + CoinMessages messages_; + /** Add only violated cuts?*/ + bool addOnlyViolated_; + /** Add cuts as global?*/ + bool global_; + /** Average number of nodes per level in tree */ + double solves_per_level_; + }; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOsiTMINLPInterface.hpp b/thirdparty/linux/include/coin/coin/BonOsiTMINLPInterface.hpp new file mode 100644 index 0000000..3d95545 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOsiTMINLPInterface.hpp @@ -0,0 +1,1342 @@ +// (C) Copyright International Business Machines Corporation, Carnegie Mellon University 2004, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + + +#ifndef OsiTMINLPInterface_H +#define OsiTMINLPInterface_H + +#define INT_BIAS 0e-8 + +#include <string> +#include <iostream> + +#include "OsiSolverInterface.hpp" +#include "CoinWarmStartBasis.hpp" + +#include "BonCutStrengthener.hpp" +//#include "BonRegisteredOptions.hpp" + +namespace Bonmin { + class TMINLP; + class TMINLP2TNLP; + class TMINLP2OsiLP; + class TNLP2FPNLP; + class TNLPSolver; + class RegisteredOptions; + class StrongBranchingSolver; + + /** Solvers for solving nonlinear programs.*/ + enum Solver{ + EIpopt=0 /** <a href="http://projects.coin-or.org/Ipopt"> Ipopt </a> interior point algorithm.*/, + EFilterSQP /** <a href="http://www-unix.mcs.anl.gov/~leyffer/solvers.html"> filterSQP </a> Sequential Quadratic Programming algorithm.*/, + EAll/** Use all solvers.*/ + }; +/** + This is class provides an Osi interface for a Mixed Integer Linear Program + expressed as a TMINLP + (so that we can use it for example as the continuous solver in Cbc). +*/ + +class OsiTMINLPInterface : public OsiSolverInterface +{ + friend class BonminParam; + +public: + + //############################################################################# + + /**Error class to throw exceptions from OsiTMINLPInterface. + * Inherited from CoinError, we just want to have a different class to be able to catch + * errors thrown by OsiTMINLPInterface. + */ +class SimpleError : public CoinError + { + private: + SimpleError(); + + public: + ///Alternate constructor using strings + SimpleError(std::string message, + std::string methodName, + std::string f = std::string(), + int l = -1) + : + CoinError(message,methodName,std::string("OsiTMINLPInterface"), f, l) + {} + } + ; + +#ifdef __LINE__ +#define SimpleError(x, y) SimpleError((x), (y), __FILE__, __LINE__) +#endif + + // Error when problem is not solved + TNLPSolver::UnsolvedError * newUnsolvedError(int num, Ipopt::SmartPtr<TMINLP2TNLP> problem, std::string name){ + return app_->newUnsolvedError(num, problem, name); + } + //############################################################################# + + enum WarmStartModes{ + None, + FakeBasis, + Optimum, + InteriorPoint}; + + /** Type of the messages specifically written by OsiTMINLPInterface.*/ + enum MessagesTypes{ + SOLUTION_FOUND/**found a feasible solution*/, + INFEASIBLE_SOLUTION_FOUND/**found an infeasible problem*/, + UNSOLVED_PROBLEM_FOUND/**found an unsolved problem*/, + WARNING_RESOLVING /** Warn that a problem is resolved*/, + WARN_SUCCESS_WS/** Problem not solved with warm start but solved without*/, + WARN_SUCCESS_RANDOM/** Subproblem not solve with warm start but solved with random point*/, + WARN_CONTINUING_ON_FAILURE/** a failure occured but is continuing*/, + SUSPECT_PROBLEM/** Output the number of the problem.*/, + SUSPECT_PROBLEM2/** Output the number of the problem.*/, + IPOPT_SUMMARY /** Output summary statistics on Ipopt solution.*/, + BETTER_SOL /** Found a better solution with random values.*/, + LOG_HEAD/** Head of "civilized" log.*/, + LOG_FIRST_LINE/** First line (first solve) of log.*/, + LOG_LINE/**standard line (retry solving) of log.*/, + ALTERNATE_OBJECTIVE/** Recomputed integer feasible with alternate objective function*/, + WARN_RESOLVE_BEFORE_INITIAL_SOLVE /** resolve() has been called but there + was no previous call to initialSolve(). + */, + ERROR_NO_TNLPSOLVER /** Trying to access non-existent TNLPSolver*/, + WARNING_NON_CONVEX_OA /** Warn that there are equality or ranged constraints and OA may works bad.*/, + SOLVER_DISAGREE_STATUS /** Different solver gives different status for problem.*/, + SOLVER_DISAGREE_VALUE /** Different solver gives different optimal value for problem.*/, + OSITMINLPINTERFACE_DUMMY_END + }; + + //############################################################################# + + + /** Messages written by an OsiTMINLPInterface. */ +class Messages : public CoinMessages + { + public: + /// Constructor + Messages(); + }; + + + //############################################################################# + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiTMINLPInterface(); + + /** Facilitator to initialize interface. */ + void initialize(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix, + Ipopt::SmartPtr<TMINLP> tminlp); + + /** Facilitator to initialize interface. */ + void initialize(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + Ipopt::SmartPtr<TMINLP> tminlp){ + initialize(roptions, options, journalist, "bonmin.", tminlp); + } + + /** Set the model to be solved by interface.*/ + void setModel(Ipopt::SmartPtr<TMINLP> tminlp); + /** Set the solver to be used by interface.*/ + void setSolver(Ipopt::SmartPtr<TNLPSolver> app); + /** Sets the TMINLP2TNLP to be used by the interface.*/ + void use(Ipopt::SmartPtr<TMINLP2TNLP> tminlp2tnlp); + /** Copy constructor + */ + OsiTMINLPInterface (const OsiTMINLPInterface &); + + /** Virtual copy constructor */ + OsiSolverInterface * clone(bool copyData = true) const; + + /// Assignment operator + OsiTMINLPInterface & operator=(const OsiTMINLPInterface& rhs); + + /// Destructor + virtual ~OsiTMINLPInterface (); + + + /// Read parameter file + void readOptionFile(const std::string & fileName); + + /// Retrieve OsiTMINLPApplication option list + const Ipopt::SmartPtr<Ipopt::OptionsList> options() const; + /// Retrieve OsiTMINLPApplication option list + Ipopt::SmartPtr<Ipopt::OptionsList> options(); + + const char * prefix() const{ + if(!IsValid(app_)) { + messageHandler()->message(ERROR_NO_TNLPSOLVER, messages_)<<CoinMessageEol; + return NULL; + } + else + return app_->prefix(); + } + //@} + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial continuous relaxation + virtual void initialSolve(); + + /// Solve initial continuous relaxation (precising from where) + virtual void initialSolve(const char * whereFrom); + + /** Resolve the continuous relaxation after problem modification. + initialSolve may or may not have been called before this is called. In + any case, this must solve the problem, and speed the process up if it + can reuse any remnants of data that might exist from a previous solve. + */ + virtual void resolve(); + + /** Resolve the continuous relaxation after problem modification. + initialSolve may or may not have been called before this is called. In + any case, this must solve the problem, and speed the process up if it + can reuse any remnants of data that might exist from a previous solve. + */ + virtual void resolve(const char * whereFrom); + + /** Resolve the problem with different random starting points to try to find + a better solution (only makes sense for a non-convex problem.*/ + virtual void resolveForCost(int numretry, bool keepWs); + + /** Method to be called when a problem has failed to be solved. Will try + to resolve it with different settings. + */ + virtual void resolveForRobustness(int numretry); + + /// Nescessary for compatibility with OsiSolverInterface but does nothing. + virtual void branchAndBound() + { + throw SimpleError("Function not implemented for OsiTMINLPInterface","branchAndBound()"); + } + //@} + + + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + + ///Warn solver that branch-and-bound is continuing after a failure + void continuingOnAFailure() + { + hasContinuedAfterNlpFailure_ = true; + } + + + //Added by Claudia + + double getNewCutoffDecr() + { + return newCutoffDecr; + } + + void setNewCutoffDecr(double d) + { + newCutoffDecr = d; + } + + + /// Did we continue on a failure + bool hasContinuedOnAFailure() + { + return hasContinuedAfterNlpFailure_; + } + /// tell to ignore the failures (don't throw, don't fathom, don't report) + void ignoreFailures() + { + pretendFailIsInfeasible_ = 2; + } + /// Force current solution to be infeasible + void forceInfeasible() + { + problem_->set_obj_value(1e200); + } + /// Force current solution to be branched on (make it fractionnal with small objective) + void forceBranchable() + { + problem_->set_obj_value(-1e200); + problem_->force_fractionnal_sol(); + } + //@} + + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the clp algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + + // Get the push values for starting point + inline double getPushFact() const + { + return pushValue_; + } + + //@} + + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + ///get name of variables + const OsiSolverInterface::OsiNameVec& getVarNames() ; + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const; + + /** Get objective function sense (1 for min (default), -1 for max) + * Always minimizes */ + virtual double getObjSense() const + { + return 1; + } + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + + /// Return true if column is binary + virtual bool isBinary(int columnNumber) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int columnNumber) const; + + /// Return true if column is general integer + virtual bool isIntegerNonBinary(int columnNumber) const; + + /// Return true if column is binary and not fixed at either bound + virtual bool isFreeBinary(int columnNumber) const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + + ///Get priorities on integer variables. + const int * getPriorities() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->priorities; + else return NULL; + } + ///get prefered branching directions + const int * getBranchingDirections() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->branchingDirections; + else return NULL; + } + const double * getUpPsCosts() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->upPsCosts; + else return NULL; + } + const double * getDownPsCosts() const + { + const TMINLP::BranchingInfo * branch = tminlp_->branchingInfo(); + if(branch) + return branch->downPsCosts; + else return NULL; + } + + + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. + * \todo Figure out what it could mean for Ipopt. + */ + virtual int getIterationCount() const; + + /** get total number of calls to solve.*/ + int nCallOptimizeTNLP() + { + return nCallOptimizeTNLP_; + } + /** get total time taken to solve NLP's. */ + double totalNlpSolveTime() + { + return totalNlpSolveTime_; + } + /** get total number of iterations */ + int totalIterations() + { + return totalIterations_; + } + + + //@} + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + */ + //@{ + + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set the lower bounds for all columns + array [getNumCols()] is an array of values for the objective. + */ + virtual void setColLower(const double * array); + + /** Set the upper bounds for all columns + array [getNumCols()] is an array of values for the objective. + */ + virtual void setColUpper(const double * array); + + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ); + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + + /** \brief Set the objective function sense (disabled). + * (1 for min (default), -1 for max) + \todo Make it work. + \bug Can not treat maximisation problems. */ + virtual void setObjSense(double s); + + /** Set the primal solution variable values + Set the values for the starting point. + \warning getColSolution will never return this vector (unless it is optimal). + */ + virtual void setColSolution(const double *colsol); + + /** Set dual solution variable values. + set the values for the starting point. + \warning getRowPrice will never return this vector (unless it is optimal). + */ + virtual void setRowPrice(const double * rowprice); + + //@} + + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods (those should really do nothing for the moment)*/ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + virtual CoinWarmStart *getEmptyWarmStart () const; + + /** Get warmstarting information */ + virtual CoinWarmStart* getWarmStart() const; + + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + + void setWarmStartMode(int mode) { + warmStartMode_ = (WarmStartModes) mode; + } + WarmStartModes getWarmStartMode() { + return warmStartMode_; + } + + void randomStartingPoint(); + + //Returns true if a basis is available + virtual bool basisIsAvailable() const + { + // Throw an exception + throw SimpleError("Needs coding for this interface", "basisIsAvailable"); + } + + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + //@} + + //Set numIterationSuspect_ + void setNumIterationSuspect(int value) + { + numIterationSuspect_ = value; + } + + /**@name Dummy functions + * Functions which have to be implemented in an OsiSolverInterface, + * but which do not do anything (but throwing exceptions) here in the case of a + * minlp solved using an nlp solver for continuous relaxations */ + //@{ + + /** Cbc will understand that no matrix exsits if return -1 + */ + virtual int getNumElements() const + { + return -1; + } + + + /** This returns the objective function gradient at the current + * point. It seems to be required for Cbc's pseudo cost + * initialization + */ + virtual const double * getObjCoefficients() const; + + /** We have to keep this but it will return NULL. + */ + virtual const CoinPackedMatrix * getMatrixByRow() const + { + return NULL; + } + + + /** We have to keep this but it will return NULL. + */ + virtual const CoinPackedMatrix * getMatrixByCol() const + { + return NULL; + } + + /** We have to keep this but it will throw an error. + */ + virtual void setObjCoeff( int elementIndex, double elementValue ) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "setObjCoeff"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "addCol"); + } + /** We have to keep this but it will throw an error. + */ + virtual void deleteCols(const int num, const int * colIndices) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "deleteCols"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "addRow"); + } + /** We have to keep this but it will throw an error. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng) + { + throw SimpleError("OsiTMINLPInterface model does not implement this function.", + "addRow"); + } + /** We have to keep this but it will throw an error. + */ + virtual void deleteRows(const int num, const int * rowIndices) + { + if(num) + freeCachedRowRim(); + problem_->removeCuts(num, rowIndices); + } + + + /** We have to keep this but it will throw an error + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "assignProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "assignProblem"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const int numcols, const int numrows, + const int* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual void loadProblem(const int numcols, const int numrows, + const int* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) + { + throw SimpleError("OsiTMINLPInterface model does not implement this function.", + "loadProblem"); + } + + /** We have to keep this but it will throw an error. + */ + virtual int readMps(const char *filename, + const char *extension = "mps") + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "readMps"); + } + + + /** We have to keep this but it will throw an error. + */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "writeMps"); + } + + /** Throws an error */ + virtual std::vector<double*> getDualRays(int maxNumRays, bool fullRay = false) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "getDualRays"); + } + + /** Throws an error */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const + { + throw SimpleError("OsiTMINLPInterface does not implement this function.", + "getPrimalRays"); + } + + //@} + + + + //--------------------------------------------------------------------------- + + + + /**@name Control of Ipopt output + */ + //@{ + void setSolverOutputToDefault(){ + app_->setOutputToDefault();} + void forceSolverOutput(int log_level){ + app_->forceSolverOutput(log_level);} + //@} + + /**@name Sets and Getss */ + //@{ + /// Get objective function value (can't use default) + virtual double getObjValue() const; + + //@} + + /** get pointer to the TMINLP2TNLP adapter */ + const TMINLP2TNLP * problem() const + { + return GetRawPtr(problem_); + } + + TMINLP2TNLP * problem() + { + return GetRawPtr(problem_); + } + + const TMINLP * model() const + { + return GetRawPtr(tminlp_); + } + + Bonmin::TMINLP * model() + { + return GetRawPtr(tminlp_); + } + + const Bonmin::TNLPSolver * solver() const + { + return GetRawPtr(app_); + } + + const std::list<Ipopt::SmartPtr<TNLPSolver> >& debug_apps() const{ + return debug_apps_; + } + + TNLPSolver * solver() + { + return GetRawPtr(app_); + } + /** \name Methods to build outer approximations */ + //@{ + /** \name Methods to build outer approximations */ + //@{ + /** \brief Extract a linear relaxation of the MINLP. + * Use user-provided point to build first-order outer-approximation constraints at the optimum. + * And put it in an OsiSolverInterface. + */ + virtual void extractLinearRelaxation(OsiSolverInterface &si, const double *x, + bool getObj = 1); + + /** Add constraint corresponding to objective function.*/ + virtual void addObjectiveFunction(OsiSolverInterface &si, const double * x); +#if 1 + /** \brief Extract a linear relaxation of the MINLP. + * Solve the continuous relaxation and takes first-order outer-approximation constraints at the optimum. + * The put everything in an OsiSolverInterface. + */ + virtual void extractLinearRelaxation(OsiSolverInterface &si, bool getObj = 1, + bool solveNlp = 1){ + if(solveNlp) + initialSolve("build initial OA"); + extractLinearRelaxation(si, getColSolution(), getObj); + if(solveNlp){ + app_->enableWarmStart(); + setColSolution(problem()->x_sol()); + setRowPrice(problem()->duals_sol()); + } + } +#endif + /** Get the outer approximation constraints at the current optimal point. + If x2 is different from NULL only add cuts violated by x2. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + void getOuterApproximation(OsiCuts &cs, int getObj, const double * x2, bool global) +{ + getOuterApproximation(cs, getColSolution(), getObj, x2, global); +} + + /** Get the outer approximation constraints at provided point. + If x2 is different from NULL only add cuts violated by x2. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + void getOuterApproximation(OsiCuts &cs, const double * x, int getObj, const double * x2, bool global){ + getOuterApproximation(cs, x, getObj, x2, 0., global);} + + /** Get the outer approximation constraints at provided point. + If x2 is different from NULL only add cuts violated by x2 by more than delta. + (Only get outer-approximations of nonlinear constraints of the problem.)*/ + virtual void getOuterApproximation(OsiCuts &cs, const double * x, int getObj, const double * x2, + double theta, bool global); + + /** Get the outer approximation at provided point for given constraint. */ + virtual void getConstraintOuterApproximation(OsiCuts & cs, int constraintNumber, + const double * x, + const double * x2, bool global); + + /** Get the outer approximation at current optimal point for given constraint. */ + void getConstraintOuterApproximation(OsiCuts & cs, int constraintNumber, + const double * x2, bool global){ + getConstraintOuterApproximation(cs, constraintNumber, getColSolution(),x2,global); + } + + +/** Get a benders cut from solution.*/ +void getBendersCut(OsiCuts &cs, bool global); + + /** Given a point x_bar this solves the problem of finding the point which minimize a convex + *combination between the distance to x_bar and the original objective function f(x): + * \f$ min a * (\sum\limits_{i=1}^n ||x_{ind[i]} -\overline{x}_i)||_L) + (1 - a)* s *f(x) \f$ + * \return Distance between feasibility set a x_bar on components in ind + * \param n number of elements in array x_bar and ind + * \param s scaling of the original objective. + * \param a Combination to take between feasibility and original objective (must be between 0 and 1). + * \param L L-norm to use (can be either 1 or 2). + */ + double solveFeasibilityProblem(size_t n, const double * x_bar, const int* ind, double a, double s, int L); + + /** Given a point x_bar this solves the problem of finding the point which minimize + * the distance to x_bar while satisfying the additional cutoff constraint: + * \f$ min \sum\limits_{i=1}^n ||x_{ind[i]} -\overline{x}_i)||_L$ + * \return Distance between feasibility set a x_bar on components in ind + * \param n number of elements in array x_bar and ind + * \param L L-norm to use (can be either 1 or 2). + * \param cutoff objective function value of a known integer feasible solution + */ + double solveFeasibilityProblem(size_t n, const double * x_bar, const int* ind, int L, double cutoff); + + /** Given a point x_bar setup feasibility problem and switch so that every call to initialSolve or resolve will + solve it.*/ + void switchToFeasibilityProblem(size_t n, const double * x_bar, const int* ind, double a, double s, int L); + + /** Given a point x_bar setup feasibility problem and switch so that every call to initialSolve or resolve will + solve it. This is to be used in the local branching heuristic */ + void switchToFeasibilityProblem(size_t n, const double * x_bar, const int* ind, + double rhs_local_branching_constraint); + + /** switch back to solving original problem.*/ + void switchToOriginalProblem(); + + /** round solution and check its feasibility.*/ + void round_and_check(double tolerance, + OsiObject ** objects = 0, int nObjects = -1){ + if(!problem_->check_solution(objects, nObjects)){ + optimizationStatus_ = TNLPSolver::provenInfeasible; + } + } + //@} + + /** \name output for OA cut generation + \todo All OA code here should be moved to a separate class sometime.*/ + //@{ + /** OA Messages types.*/ + enum OaMessagesTypes { + CUT_NOT_VIOLATED_ENOUGH = 0/** Says that one cut has been generarted, where from, which is the violation.*/, + VIOLATED_OA_CUT_GENERATED/** Cut is not violated enough, give violation.*/, + OA_CUT_GENERATED/** Print the cut which has been generated.*/, + OA_MESSAGES_DUMMY_END/** Dummy end.*/}; + /** Class to store OA Messages.*/ + class OaMessages :public CoinMessages{ + public: + /** Default constructor.*/ + OaMessages(); + }; + /** Like a CoinMessageHandler but can print a cut also.*/ + class OaMessageHandler : public CoinMessageHandler{ + public: + /** Default constructor.*/ + OaMessageHandler():CoinMessageHandler(){ + } + /** Constructor to put to file pointer (fp won't be closed).*/ + OaMessageHandler(FILE * fp):CoinMessageHandler(fp){ + } + /** Destructor.*/ + virtual ~OaMessageHandler(){ + } + /** Copy constructor.*/ + OaMessageHandler(const OaMessageHandler &other): + CoinMessageHandler(other){} + /** Constructor from a regular CoinMessageHandler.*/ + OaMessageHandler(const CoinMessageHandler &other): + CoinMessageHandler(other){} + /** Assignment operator.*/ + OaMessageHandler & operator=(const OaMessageHandler &rhs){ + CoinMessageHandler::operator=(rhs); + return *this;} + /** Virtual copy */ + virtual CoinMessageHandler* clone() const{ + return new OaMessageHandler(*this);} + /** print an OsiRowCut.*/ + void print(OsiRowCut &row); + }; + void setOaMessageHandler(const CoinMessageHandler &handler){ + delete oaHandler_; + oaHandler_ = new OaMessageHandler(handler); + } + //@} + + //----------------------------------------------------------------------- + /** Apply a collection of cuts. + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0){ + freeCachedRowRim(); + problem_->addCuts(cs); + ApplyCutsReturnCode rc; + return rc;} + + /** Add a collection of linear cuts to problem formulation.*/ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + + + /** Add a collection of linear cuts to the problem formulation */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts) + { + if(numberCuts) + freeCachedRowRim(); + problem_->addCuts(numberCuts, cuts); + } + + /** Get infinity norm of constraint violation for x. Put into + obj the objective value of x.*/ + double getConstraintsViolation(const double * x, double & obj); + + /** Get infinity norm of constraint violation for x and error in objective + value where obj is the estimated objective value of x.*/ + double getNonLinearitiesViolation(const double *x, const double obj); + +//--------------------------------------------------------------------------- + + void extractInterfaceParams(); + + + /** To set some application specific defaults. */ + virtual void setAppDefaultOptions(Ipopt::SmartPtr<Ipopt::OptionsList> Options); + + /** Register all possible options to Bonmin */ + static void registerOptions (Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + Ipopt::SmartPtr<Bonmin::RegisteredOptions> regOptions(){ + if(IsValid(app_)) + return app_->roptions(); + else + return NULL; + } + + /** @name Methods related to strong branching */ + //@{ + /// Set the strong branching solver + void SetStrongBrachingSolver(Ipopt::SmartPtr<StrongBranchingSolver> strong_branching_solver); + /// Create a hot start snapshot of the optimization process. In our + /// case, we initialize the StrongBrachingSolver. + virtual void markHotStart(); + /// Optimize starting from the hot start snapshot. In our case, we + /// call the StrongBranchingSolver to give us an approximate + /// solution for the current state of the bounds + virtual void solveFromHotStart(); + /// Delete the hot start snapshot. In our case we deactivate the + /// StrongBrachingSolver. + virtual void unmarkHotStart(); + //@} + + /// Get values of tiny_ and very_tiny_ + void get_tolerances(double &tiny, double&very_tiny, double &rhsRelax, double &infty){ + tiny = tiny_; + very_tiny = veryTiny_; + rhsRelax = rhsRelax_; + infty = infty_; + } + + void set_linearizer(Ipopt::SmartPtr<TMINLP2OsiLP> linearizer); + + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer(); +protected: + + //@} + + enum RandomGenerationType{ + uniform =0, perturb=1, perturb_suffix=2}; + /// Initialize data structures for storing the jacobian + int initializeJacobianArrays(); + + ///@name Virtual callbacks for application specific stuff + //@{ + virtual std::string appName() + { + return "bonmin"; + } + //@} + ///@name Protected methods + //@{ + + /** Call Ipopt to solve or resolve the problem and check for errors.*/ + void solveAndCheckErrors(bool doResolve, bool throwOnFailure, + const char * whereFrom); + + + /** Add a linear cut to the problem formulation. + */ + virtual void applyRowCut( const OsiRowCut & rc ) + { + const OsiRowCut * cut = &rc; + problem_->addCuts(1, &cut); + } + /** We have to keep this but it will throw an error. + */ + virtual void applyColCut( const OsiColCut & cc ) + { + throw SimpleError("Ipopt model does not implement this function.", + "applyColCut"); + } + +// /** Read the name of the variables in an ampl .col file. */ +// void readVarNames() const; + + //@} + + /**@name Model and solver */ + //@{ + /** TMINLP model.*/ + Ipopt::SmartPtr<TMINLP> tminlp_; + /** Adapter for a MINLP to a NLP */ + Ipopt::SmartPtr<TMINLP2TNLP> problem_; + /** Problem currently optimized (may be problem_ or feasibilityProblem_)*/ + Ipopt::SmartPtr<Ipopt::TNLP> problem_to_optimize_; + /** Is true if and only if in feasibility mode.*/ + bool feasibility_mode_; + /** Solver for a TMINLP. */ + Ipopt::SmartPtr<TNLPSolver> app_; + + /** Alternate solvers for TMINLP.*/ + std::list<Ipopt::SmartPtr<TNLPSolver> > debug_apps_; + /** Do we use the other solvers?*/ + bool testOthers_; + //@} + + /** Warmstart information for reoptimization */ + CoinWarmStart* warmstart_; + + /**@name Cached information on the problem */ + //@{ + /** Free cached data relative to variables */ + void freeCachedColRim(); + /** Free cached data relative to constraints */ + void freeCachedRowRim(); + /** Free all cached data*/ + void freeCachedData(); + /** Extract rowsense_ vector rhs_ vector and rowrange_ vector from the lower and upper bounds + * on the constraints */ + void extractSenseRhsAndRange() const; + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /// Pointer to dense vector of slack upper bounds for range constraints (undefined for non-range rows) + mutable double *rowrange_; + /** Pointer to dense vector of reduced costs + \warning Always 0. with Ipopt*/ + mutable double *reducedCosts_; + /** DualObjectiveLimit is used to store the cutoff in Cbc*/ + double OsiDualObjectiveLimit_; + /** does the file variable names exists (will check automatically).*/ + mutable bool hasVarNamesFile_; + //@} + /// number of time NLP has been solved + int nCallOptimizeTNLP_; + /// Total solution time of NLP + double totalNlpSolveTime_; + /// toatal number of iterations + int totalIterations_; + /// max radius for random point + double maxRandomRadius_; + /// Method to pick a random starting point. + int randomGenerationType_; + /// Maximum perturbation value + double max_perturbation_; + /// Ipopt value for pushing initial point inside the bounds + double pushValue_; + /// Number of times problem will be resolved in initialSolve (root node) + int numRetryInitial_; + /// Number of times problem will be resolved in resolve + int numRetryResolve_; + /// Number of times infeasible problem will be resolved. + int numRetryInfeasibles_; + /// Number of times problem will be resolved in case of a failure + int numRetryUnsolved_; + /// If infeasibility for a problem is less than this, let's be carrefull. It might be feasible + double infeasibility_epsilon_; + + + //Added by Claudia + /// Dynamic cutOff_ + int dynamicCutOff_; + /// coeff_var_threshold_ + double coeff_var_threshold_; + /// first_perc_for_cutoff_decr_ + double first_perc_for_cutoff_decr_; + /// second_perc_for_cutoff_decr_ + double second_perc_for_cutoff_decr_; + + + /** Messages specific to an OsiTMINLPInterface. */ + Messages messages_; + /** If not 0 when a problem is not solved (failed to be solved) + will pretend that it is infeasible. If == 1 will care + (i.e. record the fact issue messages to user), if ==2 don't care (somebody else will) */ + int pretendFailIsInfeasible_; + + mutable int pretendSucceededNext_; + + /** did we ever continue optimization ignoring a failure. */ + bool hasContinuedAfterNlpFailure_; + /** number iterations above which a problem is considered suspect (-1 is considered \f$+ \infty \f$). + If in a call to solve a problem takes more than that number of iterations it will be output to files.*/ + int numIterationSuspect_ ; + /** Has problem been optimized since last change (include setColSolution). + If yes getColSolution will return Ipopt point, otherwise will return + initial point.*/ + bool hasBeenOptimized_; + /** A fake objective function (all variables to 1) to please Cbc + pseudo costs initialization. AW: I changed this, it will now be + the objective gradient at current point. */ + mutable double * obj_; + /** flag to say wether options have been printed or not.*/ + static bool hasPrintedOptions; + + /** Adapter for TNLP to a feasibility problem */ + Ipopt::SmartPtr<TNLP2FPNLP> feasibilityProblem_; + + /** Adapter for TMINLP to an Osi LP */ + Ipopt::SmartPtr<TMINLP2OsiLP> linearizer_; + + /** \name Arrays to store Jacobian matrix */ + //@{ + /** Row indices.*/ + int * jRow_; + /** Column indices.*/ + int * jCol_; + /** Values */ + double * jValues_; + /** Number of elements.*/ + int nnz_jac; + //@} + + ///Store the types of the constraints (linear and nonlinear). + Ipopt::TNLP::LinearityType * constTypes_; + /** Number of nonlinear constraint + */ + int nNonLinear_; + /** Value for small non-zero element which we will try to remove cleanly in OA cuts.*/ + double tiny_; + /** Value for small non-zero element which we will take the risk to ignore in OA cuts.*/ + double veryTiny_; + /** Amount by which to relax OA constraints RHSes*/ + double rhsRelax_; + /** Value for infinity. */ + double infty_; + /** status of last optimization. */ + TNLPSolver::ReturnStatus optimizationStatus_; + /** Flag indicating if the warm start methods actually do something.*/ + WarmStartModes warmStartMode_; + /** Is it the first solve (for random starting point at root options).*/ + bool firstSolve_; + /** Object for strengthening cuts */ + Ipopt::SmartPtr<CutStrengthener> cutStrengthener_; + + /** \name output for OA cut generation + \todo All OA code here should be moved to a separate class sometime.*/ + //@{ + /** OA Messages.*/ + OaMessages oaMessages_; + /** OA Message handler. */ + OaMessageHandler * oaHandler_; + //@} + + double newCutoffDecr; +protected: + /** Facilitator to create an application. */ + void createApplication(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + ///Constructor without model only for derived classes + OsiTMINLPInterface(Ipopt::SmartPtr<TNLPSolver> app); + + /** Internal set warm start.*/ + bool internal_setWarmStart(const CoinWarmStart* ws); + + /** internal get warm start.*/ + CoinWarmStart* internal_getWarmStart() const; + + /** Procedure that builds a fake basis. Only tries to make basis consistent with constraints activity.*/ + CoinWarmStart* build_fake_basis() const; +private: + + /** solver to be used for all strong branching solves */ + Ipopt::SmartPtr<StrongBranchingSolver> strong_branching_solver_; + /** status of last optimization before hot start was marked. */ + TNLPSolver::ReturnStatus optimizationStatusBeforeHotStart_; +static const char * OPT_SYMB; +static const char * FAILED_SYMB; +static const char * INFEAS_SYMB; +static const char * TIME_SYMB; +static const char * UNBOUND_SYMB; + /** Get status as a char * for log.*/ + const char * statusAsString(TNLPSolver::ReturnStatus r){ + if(r == TNLPSolver::solvedOptimal || r == TNLPSolver::solvedOptimalTol){ + return OPT_SYMB;} + else if(r == TNLPSolver::provenInfeasible){ + return INFEAS_SYMB;} + else if(r == TNLPSolver::unbounded){ + return UNBOUND_SYMB;} + else if(r == TNLPSolver::timeLimit){ + return TIME_SYMB;} + else return FAILED_SYMB; + } + const char * statusAsString(){ + return statusAsString(optimizationStatus_);} +}; +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonOuterApprox.hpp b/thirdparty/linux/include/coin/coin/BonOuterApprox.hpp new file mode 100644 index 0000000..5f24f61 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonOuterApprox.hpp @@ -0,0 +1,123 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/16/2007 +#ifndef BonminOuterApprox_H +#define BonminOuterApprox_H + +#include <cmath> + +namespace Bonmin{ + class OsiTMINLPInterface; + class BabSetupBase; +} +class OsiSolverInterface; +namespace Bonmin { + /** A class to build outer approximations.*/ + class OuterApprox{ + + public: + + /** Default constructor.*/ + OuterApprox(): + tiny_(-0.), + veryTiny_(-0.) + {} + + /** Copy constructor.*/ + OuterApprox(const OuterApprox & other): + tiny_(other.tiny_), + veryTiny_(other.veryTiny_){ + } + + + /** Assignment operator.*/ + OuterApprox & operator=(const OuterApprox& rhs){ + if(this != & rhs){ + tiny_ = rhs.tiny_; + veryTiny_ = rhs.veryTiny_;} + return (*this); + } + + /** Destructor.*/ + ~OuterApprox(){} + + /** Initialize using options.*/ + void initialize(Bonmin::BabSetupBase &b); + + /** Build the Outer approximation in minlp and put it in si.*/ + void extractLinearRelaxation(Bonmin::OsiTMINLPInterface &minlp, + OsiSolverInterface *si, + const double * x, bool getObj); + /** Operator() calls extractLinearRelaxation*/ + void operator()(Bonmin::OsiTMINLPInterface &minlp, + OsiSolverInterface *si, + const double * x, bool getObj){ + extractLinearRelaxation(minlp, si, x, getObj);} + + private: + /** Facilitator to clean up coefficient.*/ + inline bool cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny); + /** If constraint coefficient is below this, we try to remove it.*/ + double tiny_; + /** If constraint coefficient is below this, we neglect it.*/ + double veryTiny_; + /** Count the number of linear outer approximations taken.*/ + static int nTimesCalled; + }; + +//A procedure to try to remove small coefficients in OA cuts (or make it non small +inline +bool +OuterApprox::cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) +{ + if(fabs(value)>= tiny) return 1; + + if(fabs(value)<veryTiny) return 0;//Take the risk? + + //try and remove + double infty = 1e20; + bool colUpBounded = colUpper < 10000; + bool colLoBounded = colLower > -10000; + bool rowNotLoBounded = rowLower <= - infty; + bool rowNotUpBounded = rowUpper >= infty; + bool pos = value > 0; + + if(colLoBounded && pos && rowNotUpBounded) { + lb += value * (colsol - colLower); + return 0; + } + else + if(colLoBounded && !pos && rowNotLoBounded) { + ub += value * (colsol - colLower); + return 0; + } + else + if(colUpBounded && !pos && rowNotUpBounded) { + lb += value * (colsol - colUpper); + return 0; + } + else + if(colUpBounded && pos && rowNotLoBounded) { + ub += value * (colsol - colUpper); + return 0; + } + //can not remove coefficient increase it to smallest non zero + if(pos) value = tiny; + else + value = - tiny; + return 1; +} + +} + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonPseudoCosts.hpp b/thirdparty/linux/include/coin/coin/BonPseudoCosts.hpp new file mode 100644 index 0000000..b7934e5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonPseudoCosts.hpp @@ -0,0 +1,91 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 04/12/2007 + +#ifndef BonPseudoCosts_H +#define BonPseudoCosts_H + +#include "OsiChooseVariable.hpp" +namespace Bonmin +{ + + class PseudoCosts: public OsiPseudoCosts + { + public: + /** Default constructor.*/ + PseudoCosts(); + + /** Copy constructor.*/ + PseudoCosts(const PseudoCosts & rhs); + + /** Assignment operator const version.*/ + PseudoCosts & operator=(const PseudoCosts&rhs); +#if 0 + /** Acces upTotalChange.*/ + inline double * upTotalChange() + { + return upTotalChange_; + } + + /** Acces downTotalChange.*/ + inline double * downTotalChange() + { + return downTotalChange_; + } + + /** Acces upNumber.*/ + inline int * upNumber() + { + return upNumber_; + } + + /** Acces downNumber.*/ + inline int * downNumber() + { + return downNumber_; + } + + /** Acces upTotalChange.*/ + inline const double * upTotalChange() const + { + return upTotalChange_; + } + + /** Acces downTotalChange.*/ + inline const double * downTotalChange() const + { + return downTotalChange_; + } + + /** Acces upNumber.*/ + inline const int * upNumber() const + { + return upNumber_; + } + + /** Acces downNumber.*/ + inline const int * downNumber() const + { + return downNumber_; + } + + /** Access number objects.*/ + inline int numberObjects() const + { + return numberObjects_; + } +#endif + /** Add a pseudo cost information.*/ + void addInfo(int way, double originalObj, double originalInfeas, + double newObj, double newInfeas, int status); + + }; + +}/* End Bonmin namespace.*/ + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonPumpForMinlp.hpp b/thirdparty/linux/include/coin/coin/BonPumpForMinlp.hpp new file mode 100644 index 0000000..e2b7cb1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonPumpForMinlp.hpp @@ -0,0 +1,45 @@ +// (C) Copyright CNRS +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, LIF Université de la Méditérannée-CNRS +// +// Date : 02/18/2009 + +#ifndef BonPumpForMinlp_H +#define BonPumpForMinlp_H +#include "BonLocalSolverBasedHeuristic.hpp" + +namespace Bonmin { + class PumpForMinlp:public LocalSolverBasedHeuristic { + public: + /** Default constructor*/ + PumpForMinlp(); + /** Constructor with setup.*/ + PumpForMinlp(BonminSetup * setup); + + /** Copy constructor.*/ + PumpForMinlp(const PumpForMinlp &other); + /** Virtual constructor.*/ + virtual CbcHeuristic * clone() const{ + return new PumpForMinlp(*this); + } + + /** Destructor*/ + virtual ~PumpForMinlp(); + + /** Runs heuristic*/ + int solution(double & objectiveValue, + double * newSolution); + /** Register the options common to all local search based heuristics.*/ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + + /** Setup the defaults.*/ + virtual void setupDefaults(Ipopt::SmartPtr<Ipopt::OptionsList> options); + /** Initiaize using passed options.*/ + void Initialize(Ipopt::SmartPtr<Ipopt::OptionsList> options); + }; + +}/* Ends Bonmin namepace.*/ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonQuadCut.hpp b/thirdparty/linux/include/coin/coin/BonQuadCut.hpp new file mode 100644 index 0000000..8cbf0c8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonQuadCut.hpp @@ -0,0 +1,217 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonQuadCut_H +#define BonQuadCut_H + +#include "CoinPackedMatrix.hpp" +#include "OsiRowCut.hpp" +#include "OsiCuts.hpp" +#include "BonTypes.hpp" +#include <list> + + +namespace Bonmin { + + enum MatrixStorageType { + Upper /** Stores only the upper triangle of a symetric Q.*/, + Lower /** Stores the lower triangle of a symetric Q.*/, + Full /** Stores the whole matrix of a non-symetric Q.*/}; + +class QuadCut : public OsiRowCut { + public: + + /// Default constructor + QuadCut(); + + /// Copy constructor + QuadCut(const QuadCut & other); + + /// Assignment operator + QuadCut& operator=(const QuadCut & rhs); + + /// Virtual copy + virtual OsiRowCut * clone() const; + + /// Destructor + ~QuadCut(); + + /// Print + void print() const; + + ///Return the matrix stored + CoinPackedMatrix& Q(){ + return Q_; + } + + ///Return the matrix stored + const CoinPackedMatrix& Q() const{ + return Q_; + } + + /// Acces storage type + /// Acces storage type + MatrixStorageType& type(){ + return type_;} + + const MatrixStorageType& type() const{ + return type_;} + + /// Acces the constant + double & c(){return c_;} + + /// Acces the constant + const double & c() const {return c_;} + + /// Compute cut violation + double violated(const double * solution) const; + + private: + /// Stores the constant part of the cut + double c_; + ///Stores quadratic part of cut + CoinPackedMatrix Q_; + ///Storage type + MatrixStorageType type_; + + /** \name Arithmetic operators not implemented.*/ + //@{ + /// add <code>value</code> to every vector entry + void operator+=(double value); + + /// subtract <code>value</code> from every vector entry + void operator-=(double value); + + /// multiply every vector entry by <code>value</code> + void operator*=(double value); + + /// divide every vector entry by <code>value</code> + void operator/=(double value); + //@} + +}; + +/** Generalizes OsiCuts to handle quadratic cuts.*/ +class Cuts : public OsiCuts { + public: + typedef vector<QuadCut *> QuadCutPtrStorage; + /** Default constructor.*/ + Cuts(); + + /** Copy constructor.*/ + Cuts(const Cuts& other); + + /** Assignment operator.*/ + Cuts& operator=(const Cuts & rhs); + + /** Destructor */ + ~Cuts(); + + /** insert a quadratic cut into the collection. */ + inline void insert(const QuadCut& c); + + /** insert a quadratic cut into the collection (take control of the pointer and + put a NULL on return). + \warning c has to have been created with new (no malloc). + */ + inline void insert(QuadCut* &c); + + /** insert a set of Cuts.*/ + inline void insert(const Cuts &cs); + + /** Number of quadratic cuts in the collection.*/ + inline int sizeQuadCuts() const; + + /** Total number of cuts in the collection. */ + inline int sizeCuts() const; + + /** Print all cuts in the collection.*/ + void printCuts() const; + + + /** Access to a quadratic cut by pointer.*/ + inline QuadCut * quadCutPtr(int i); + + /** Access to a quadratic cut by const pointer.*/ + inline const QuadCut * quadCutPtr(int i) const; + + /** Access to a quadratic cut by reference.*/ + inline QuadCut& quadCut(int i); + + + /** Access to a quadratic cut by reference.*/ + inline const QuadCut& quadCut(int i) const; + + /** Erase quadratic cut from the collection.*/ + inline void eraseQuadCut(int i); + + private: + QuadCutPtrStorage quadCuts_; +}; + +void +Cuts::insert(const QuadCut &c){ + quadCuts_.push_back(new QuadCut(c)); +} + +void +Cuts::insert(QuadCut * &c){ + quadCuts_.push_back(c); + c = NULL; +} + +void +Cuts::insert(const Cuts & cs){ + OsiCuts::insert(cs); + for(unsigned int i = 0 ; i < cs.quadCuts_.size() ; i++){ + quadCuts_.push_back(new QuadCut(*cs.quadCuts_[i])); + } +} + +int +Cuts::sizeQuadCuts() const { + return static_cast<int>(quadCuts_.size()); +} + +int +Cuts::sizeCuts() const { + return static_cast<int>(quadCuts_.size()) + OsiCuts::sizeCuts(); +} + +QuadCut * +Cuts::quadCutPtr(int i) { + return quadCuts_[i]; +} + +const QuadCut * +Cuts::quadCutPtr(int i) const { + return quadCuts_[i]; +} + +QuadCut & +Cuts::quadCut(int i) { + return *quadCuts_[i]; +} + +const QuadCut & +Cuts::quadCut(int i) const { + return *quadCuts_[i]; +} + +void +Cuts::eraseQuadCut(int i){ + delete quadCuts_[i]; + quadCuts_.erase(quadCuts_.begin() + i); +} +typedef std::list<QuadCut*> list_QuadCut; + +}// Ends Bonmin namespace +#endif + + diff --git a/thirdparty/linux/include/coin/coin/BonQuadRow.hpp b/thirdparty/linux/include/coin/coin/BonQuadRow.hpp new file mode 100644 index 0000000..2508abd --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonQuadRow.hpp @@ -0,0 +1,122 @@ +/// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonQuadRow_H +#define BonQuadRow_H + +#include "CoinPackedVector.hpp" +#include "BonTMatrix.hpp" +#include "BonQuadCut.hpp" + +namespace Bonmin{ + + /** Store column and row of the entry.*/ + typedef std::pair<int, int> matEntry; + /** Store the number of times entry is used and its index in the matrix.*/ + typedef std::pair<int, int> matIdx; +#if HAS_HASH_MAP + typedef std::has_map<matEntry, matIdx, std::hash< matEntry> > AdjustableMat; +#else + typedef std::map<matEntry, matIdx> AdjustableMat; +#endif + +/** Stores a quadratic row of the form l < c + ax + x^T Q x < u. + Does computation usefull for nlp-solver. + It can only be initialized from a QuadCut.*/ +class QuadRow { + public: + /** Default constructor.*/ + QuadRow(); + + /** Copy constructor.*/ + QuadRow(const QuadRow & other); + + /** Assignment operator.*/ + QuadRow& operator=(const QuadRow& rhs); + + /** Constructor from a quadratic cut.*/ + QuadRow(const QuadCut &cut); + + /** Assignment form a quadrattic &cut.*/ + QuadRow& operator=(const QuadCut & rhs); + + /** Constructor from a linear cut.*/ + QuadRow(const OsiRowCut &cut); + + /** Assignment form a linear &cut.*/ + QuadRow& operator=(const OsiRowCut & rhs); + + /** Evaluate quadratic form.*/ + double eval_f(const double *x, bool new_x); + + /** Get number of non-zeroes in the gradiant.*/ + int nnz_grad(); + /** Get structure of gradiant */ + void gradiant_struct(const int nnz, int * indices, bool offset); + /** Evaluate gradiant of quadratic form.*/ + void eval_grad(const int nnz, const double * x, bool new_x, double * values); + + /** number of non-zeroes in hessian. */ + int nnz_hessian(){ + return Q_.nnz_;} + + /** Says if the constraint is linear.*/ + bool isLinear(){ + return Q_.nnz_ == 0;} + + /** Return hessian value (i.e. Q_).*/ + void eval_hessian(double lambda, double * values); + + /** Add row to a bigger hessian.*/ + void add_to_hessian(AdjustableMat &H, bool offset); + + /** Remove row from a bigger hessian.*/ + void remove_from_hessian(AdjustableMat &H); +/** Print quadratic constraint.*/ +void print(); + + private: + /** Initialize once quadratic form is know.*/ + void initialize(); + + /** Does internal work to evaluate gradiant of this in x.*/ + void internal_eval_grad(const double *x); + + /** lower bound.*/ + double lb_; + /** upper bound.*/ + double ub_; + /** Constant term.*/ + double c_; + /** linear term in sparse storage.*/ + CoinPackedVector a_; + /** Quadratic term.*/ + TMat Q_; + + +#if HAS_HASH_MAP + typedef std::has_map<int, std::pair<double, double >, std::hash<int> > gStore; +#else + typedef std::map<int, std::pair<double, double> > gStore; +#endif + + gStore g_; + /** To have fast access to gradiant entries for a_.*/ + std::vector<gStore::iterator> a_grad_idx_; + /** To have fast access to gradient entries for rows Q_*/ + std::vector<gStore::iterator> Q_row_grad_idx_; + /** To have fast access to gradient entries for cols Q_*/ + std::vector<gStore::iterator> Q_col_grad_idx_; + /** To have fast access to entries in full hessian of Q_*/ + std::vector<AdjustableMat::iterator> Q_hessian_idx_; + /** Flag indicating if gradiant has been evaluated.*/ + bool grad_evaled_; +}; +}//End Bonmin namespace +#endif diff --git a/thirdparty/linux/include/coin/coin/BonRegisteredOptions.hpp b/thirdparty/linux/include/coin/coin/BonRegisteredOptions.hpp new file mode 100644 index 0000000..8679eda --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonRegisteredOptions.hpp @@ -0,0 +1,225 @@ +// (C) Copyright International Business Machines Corporation 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// +// Date : 27/08/2007 + +#ifndef BonRegisteredOptions_H +#define BonRegisteredOptions_H + +#include "IpRegOptions.hpp" +#include "IpException.hpp" +#include "CoinError.hpp" +#include "IpTypes.hpp" +#include <iostream> + +/* Forward declaration, the function will be defined in BonAmplTMINLP.cpp, if ASL is available */ +namespace Ipopt { + class AmplOptionsList; +} + +namespace Bonmin { +/** Class to add a few more information to Ipopt::RegisteredOptions. + In particular, it allows to store code to indicate in which algorithm + option is available. It also allows to table summing up all the options + both in LaTex and html.*/ +class RegisteredOptions: public Ipopt::RegisteredOptions{ + public: + enum ExtraOptInfosBits{ + validInHybrid=0/** Say that option is valid in Hybrid method (1).*/, + validInQG/** Say that option is valid in Quesada Grossmann method (2).*/, + validInOA/**Say that option is valid in outer approximation dec (4).*/, + validInBBB/** Say that option is valid in the pure branch-and-bound (8).*/, + validInEcp/** Say that option is valid in the Ecp (16).*/, + validIniFP/** Say that option is valid in the iFP (32).*/, + validInCbc/** Say that option is valid when using Cbc_Par (64).*/ + }; + + +/* Table of values + * only B-Hyb 1 + * B-Hyb & B-QG 3 + * B-Hyb & B-OA 5 + * B-Hyb & B-QG & B-OA & B-ECP 23 + */ + + + + enum ExtraCategoriesInfo{ + BonminCategory = 0/** Option category is for Bonmin.*/, + IpoptCategory /** Option category for Ipopt.*/, + FilterCategory /** Option category for FilterSqp.*/, + BqpdCategory /** Option category for Bqpd.*/, + CouenneCategory /** Option category for Couenne.*/, + UndocumentedCategory /**For undocumented options.*/ + }; + /** Standard constructor.*/ + RegisteredOptions(): + Ipopt::RegisteredOptions(){ + } + + /** Standard destructor.*/ + ~RegisteredOptions(){ + } + + //DECLARE_STD_EXCEPTION(OPTION_NOT_REGISTERED); + /** Set registering category with extra information.*/ + void SetRegisteringCategory (const std::string ®istering_category, + const ExtraCategoriesInfo extra){ + Ipopt::RegisteredOptions::SetRegisteringCategory(registering_category); + categoriesInfos_[registering_category] = extra;} + + /** throw if option does not exists.*/ + inline void optionExists(const std::string & option){ + if(!IsValid(GetOption(option))){ + std::string msg = "Try to access option: "+option; + msg += "\n Option is not registered.\n"; + throw CoinError("Bonmin::RegisteredOption","optionExists",msg); + } + } + + /**Set extra information for option.*/ + inline void setOptionExtraInfo(const std::string & option, int code){ + optionExists(option); + bonOptInfos_[option] = code; + } + + /** Set that option is valid for hybrid.*/ + inline void optionValidForHybrid(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInHybrid;} + + /** Set that option is valid for QuesadaGrossmann.*/ + inline void optionValidForBQG(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInQG;} + + /** Set that option is valid for Outer approximation.*/ + inline void optionValidForBOA(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInOA;} + + /** Set that option is valid for pure branch-and-bound.*/ + inline void optionValidForBBB(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInBBB;} + + /** Set that option is valid for B-Ecp.*/ + inline void optionValidForBEcp(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInEcp;} + + /** Set that option is valid for B-iFP.*/ + inline void optionValidForBiFP(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validIniFP;} + + /** Set that option is valid for Cbc.*/ + inline void optionValidForCbc(const std::string &option){ + optionExists(option); + bonOptInfos_[option] |= 1 << validInCbc;} + + + /** Say if option is valid for hybrid.*/ + inline bool isValidForHybrid(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInHybrid); + else return true;} + + /** Say if option is valid for QuesadaGrossmann.*/ + inline bool isValidForBQG(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInQG); + else return true;} + + /** Say if option is valid for Outer approximation.*/ + inline bool isValidForBOA(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInOA); + return true;} + + /** Say if option is valid for pure branch-and-bound.*/ + inline bool isValidForBBB(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInBBB); + return true;} + + + /** Say if option is valid for B-Ecp.*/ + inline bool isValidForBEcp(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInEcp); + return true;} + + + /** Say if option is valid for B-iFP.*/ + inline bool isValidForBiFP(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validIniFP); + return true;} + + + /** Say if option is valid for Cbc.*/ + inline bool isValidForCbc(const std::string &option){ + optionExists(option); + std::map<std::string, int>::iterator i = bonOptInfos_.find(option); + if(i != bonOptInfos_.end()) + return (i->second) & (1 << validInCbc); + return true;} + + + /** Output Latex table of options.*/ + void writeLatexOptionsTable(std::ostream &of, ExtraCategoriesInfo which); + + /** Output html table of options.*/ + void writeHtmlOptionsTable(std::ostream &of, ExtraCategoriesInfo which); + + + /** Output Latex/Html ooptions documentation.*/ + void writeLatexHtmlDoc(std::ostream &of, ExtraCategoriesInfo which); + /** Ouptut a bonmin.opt file with options default values and short descriptions.*/ + void writeBonminOpt(std::ostream &os, ExtraCategoriesInfo which); + + /** Get info about what a category is taking care of (e.g., Ipopt, Bonmin, FilterSQP,...) .*/ + ExtraCategoriesInfo categoriesInfo(const std::string &s) + { + std::map<std::string, ExtraCategoriesInfo>::iterator i = categoriesInfos_.find(s); + if(i == categoriesInfos_.end()) + return IpoptCategory; + return i->second; + } + + /* Forward declaration, the function will be defined in BonAmplTMINLP.cpp*/ + void fillAmplOptionList(ExtraCategoriesInfo which, Ipopt::AmplOptionsList * amplOptList); + + private: + /** Output Latex table of options.*/ + void chooseOptions(ExtraCategoriesInfo which, std::list<Ipopt::RegisteredOption *> &options); + /** Output html table of options.*/ + void writeHtmlOptionsTable(std::ostream & os, std::list<Ipopt::RegisteredOption *> &options); + /** Store extra Informations on Bonmin options.*/ + std::map<std::string, int> bonOptInfos_; + /** Store extra Informations on Registering categories + (is bonmin, filterSqp...).*/ + std::map<std::string, ExtraCategoriesInfo> categoriesInfos_; +}; + +}/*Ends namespace Bonmin.*/ +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonStrongBranchingSolver.hpp b/thirdparty/linux/include/coin/coin/BonStrongBranchingSolver.hpp new file mode 100644 index 0000000..087d2e7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonStrongBranchingSolver.hpp @@ -0,0 +1,69 @@ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// +// Author: Andreas Waechter 2007-08-20 IBM +// +#ifndef BonStrongBranchingSolver_H +#define BonStrongBranchingSolver_H + +#include "BonOsiTMINLPInterface.hpp" +#include "BonRegisteredOptions.hpp" +namespace Bonmin { + +/** This class is the base class for a solver that can be used in + * BonOsiSolverInterface to perform the strong branching solves. +*/ + +class StrongBranchingSolver : public Ipopt::ReferencedObject { + +public: + + /// Constructor from solver + StrongBranchingSolver (OsiTMINLPInterface * solver); + + /// Assignment operator + StrongBranchingSolver & operator= (const StrongBranchingSolver& rhs); + /// Copy constructor + StrongBranchingSolver(const StrongBranchingSolver& rhs); + + /// Destructor + virtual ~StrongBranchingSolver (); + + /// Called to initialize solver before a bunch of strong branching + /// solves + virtual void markHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + + /// Called to solve the current TMINLP (with changed bound information) + virtual TNLPSolver::ReturnStatus solveFromHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + + /// Called after all strong branching solves in a node + virtual void unmarkHotStart(OsiTMINLPInterface* tminlp_interface) = 0; + +protected: + + inline Ipopt::SmartPtr<Ipopt::Journalist>& Jnlst() + { + return jnlst_; + } + inline Ipopt::SmartPtr<Ipopt::OptionsList>& Options() + { + return options_; + } + inline Ipopt::SmartPtr<RegisteredOptions>& RegOptions() + { + return reg_options_; + } +private: + /** Default Constructor, forbiden for some reason.*/ + StrongBranchingSolver (); + + Ipopt::SmartPtr<Ipopt::Journalist> jnlst_; + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + Ipopt::SmartPtr<Bonmin::RegisteredOptions> reg_options_; + + int bb_log_level_; + +}; + +} +#endif diff --git a/thirdparty/linux/include/coin/coin/BonSubMipSolver.hpp b/thirdparty/linux/include/coin/coin/BonSubMipSolver.hpp new file mode 100644 index 0000000..d7749c2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonSubMipSolver.hpp @@ -0,0 +1,143 @@ +// (C) Copyright International Business Machines (IBM) 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// P. Bonami, International Business Machines +// +// Date : 12/07/2006 + + +// Code separated from BonOaDecBase to try to clarify OAs +#ifndef BonSubMipSolver_HPP +#define BonSubMipSolver_HPP +#include "IpSmartPtr.hpp" +#include <string> +/* forward declarations.*/ +class OsiSolverInterface; +class OsiClpSolverInterface; +class OsiCpxSolverInterface; +class CbcStrategy; +class CbcStrategyDefault; + +#include "OsiCuts.hpp" + +namespace Bonmin { + class RegisteredOptions; + class BabSetupBase; + /** A very simple class to provide a common interface for solving MIPs with Cplex and Cbc.*/ + class SubMipSolver + { + public: + enum MILP_solve_strategy{ + FindGoodSolution, + GetOptimum}; + /** Constructor */ + SubMipSolver(BabSetupBase &b, const std::string &prefix); + + /** Copy Constructor */ + SubMipSolver(const SubMipSolver ©); + + ~SubMipSolver(); + + /** Assign lp solver. */ + void setLpSolver(OsiSolverInterface * lp); + + /** Assign a strategy. */ + void setStrategy(CbcStrategyDefault * strategy); + + /** get the solution found in last local search (return NULL if no solution). */ + const double * getLastSolution() + { + return integerSolution_; + } + + double getLowerBound() + { + return lowBound_; + } + + void solve(double cutoff, + int loglevel, + double maxTime){ + if(milp_strat_ == FindGoodSolution){ + find_good_sol(cutoff, loglevel, maxTime); + } + else + optimize(cutoff, loglevel, maxTime); + } + + + /** update cutoff and perform a local search to a good solution. */ + void find_good_sol(double cutoff, + int loglevel, + double maxTime); + + /** update cutoff and optimize MIP. */ + void optimize(double cutoff, + int loglevel, + double maxTime); + + /** update cutoff, put OA constraints in cs as lazy constraints and optimize MIP. */ + void optimize_with_lazy_constraints(double cutoff, + int loglevel, + double maxTime, const OsiCuts & cs); + + /** Returns lower bound. */ + inline double lowBound() + { + return lowBound_; + } + + /** returns optimality status. */ + inline bool optimal() + { + return optimal_; + } + + /** Returns number of nodes in last solve.*/ + inline int nodeCount() + { + return nodeCount_; + } + + /** Returns number of simplex iterations in last solve.*/ + inline int iterationCount() + { + return iterationCount_; + } + + + OsiSolverInterface * solver(); + + /** Register options for that Oa based cut generation method. */ + static void registerOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions); + private: + /** If lp solver is clp (then have to use Cbc) (not owned).*/ + OsiClpSolverInterface *clp_; + /** If mip solver is cpx this is it (owned). */ + OsiCpxSolverInterface * cpx_; + /** lower bound obtained */ + double lowBound_; + /** Is optimality proven? */ + bool optimal_; + /** Has an integer solution? then it is here*/ + double * integerSolution_; + /** Strategy for solving sub mips with cbc. */ + CbcStrategyDefault * strategy_; + /** number of nodes in last mip solved.*/ + int nodeCount_; + /** number of simplex iteration in last mip solved.*/ + int iterationCount_; + /** MILP search strategy.*/ + MILP_solve_strategy milp_strat_; + /** setting for gap tolerance.*/ + double gap_tol_; + /** say if owns copy of clp_.*/ + bool ownClp_; + }; + +} + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTMINLP.hpp b/thirdparty/linux/include/coin/coin/BonTMINLP.hpp new file mode 100644 index 0000000..b6d21e1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMINLP.hpp @@ -0,0 +1,420 @@ +// (C) Copyright International Business Machines Corporation and +// Carnegie Mellon University 2004, 2007 +// +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + +#ifndef __TMINLP_HPP__ +#define __TMINLP_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpAlgTypes.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiCuts.hpp" +#include "IpTNLP.hpp" +#include "CoinError.hpp" +#include "CoinHelperFunctions.hpp" + +namespace Bonmin +{ + DECLARE_STD_EXCEPTION(TMINLP_INVALID); + DECLARE_STD_EXCEPTION(TMINLP_INVALID_VARIABLE_BOUNDS); + + /** Base class for all MINLPs that use a standard triplet matrix form + * and dense vectors. + * The class TMINLP2TNLP allows the caller to produce a viable TNLP + * from the MINLP (by relaxing binary and/or integers, or by + * fixing them), which can then be solved by Ipopt. + * + * This interface presents the problem form: + * \f[ + * \begin{array}{rl} + * &min f(x)\\ + * + * \mbox{s.t.}&\\ + * & g^L <= g(x) <= g^U\\ + * + * & x^L <= x <= x^U\\ + * \end{array} + * \f] + * Where each x_i is either a continuous, binary, or integer variable. + * If x_i is binary, the bounds [xL,xU] are assumed to be [0,1]. + * In order to specify an equality constraint, set gL_i = gU_i = + * rhs. The value that indicates "infinity" for the bounds + * (i.e. the variable or constraint has no lower bound (-infinity) + * or upper bound (+infinity)) is set through the option + * nlp_lower_bound_inf and nlp_upper_bound_inf. To indicate that a + * variable has no upper or lower bound, set the bound to + * -ipopt_inf or +ipopt_inf respectively + */ + class TMINLP : public Ipopt::ReferencedObject + { + public: + friend class TMINLP2TNLP; + /** Return statuses of algorithm.*/ + enum SolverReturn{ + SUCCESS, + INFEASIBLE, + CONTINUOUS_UNBOUNDED, + LIMIT_EXCEEDED, + USER_INTERRUPT, + MINLP_ERROR}; + /** Class to store sos constraints for model */ + struct SosInfo + { + /** Number of SOS constraints.*/ + int num; + /** Type of sos. At present Only type '1' SOS are supported by Cbc*/ + char * types; + /** priorities of sos constraints.*/ + int * priorities; + + /** \name Sparse storage of the elements of the SOS constraints.*/ + /** @{ */ + /** Total number of non zeroes in SOS constraints.*/ + int numNz; + /** For 0 <= i < nums, start[i] gives the indice of indices and weights arrays at which the description of constraints i begins..*/ + int * starts; + /** indices of elements belonging to the SOS.*/ + int * indices; + /** weights of the elements of the SOS.*/ + double * weights; + /** @} */ + /** default constructor. */ + SosInfo(); + /** Copy constructor.*/ + SosInfo(const SosInfo & source); + + + /** destructor*/ + ~SosInfo() + { + gutsOfDestructor(); + } + + + /** Reset information */ + void gutsOfDestructor(); + + }; + + /** Stores branching priorities information. */ + struct BranchingInfo + { + /**number of variables*/ + int size; + /** User set priorities on variables. */ + int * priorities; + /** User set preferered branching direction. */ + int * branchingDirections; + /** User set up pseudo costs.*/ + double * upPsCosts; + /** User set down pseudo costs.*/ + double * downPsCosts; + BranchingInfo(): + size(0), + priorities(NULL), + branchingDirections(NULL), + upPsCosts(NULL), + downPsCosts(NULL) + {} + BranchingInfo(const BranchingInfo &other) + { + gutsOfDestructor(); + size = other.size; + priorities = CoinCopyOfArray(other.priorities, size); + branchingDirections = CoinCopyOfArray(other.branchingDirections, size); + upPsCosts = CoinCopyOfArray(other.upPsCosts, size); + downPsCosts = CoinCopyOfArray(other.downPsCosts, size); + } + void gutsOfDestructor() + { + if (priorities != NULL) delete [] priorities; + priorities = NULL; + if (branchingDirections != NULL) delete [] branchingDirections; + branchingDirections = NULL; + if (upPsCosts != NULL) delete [] upPsCosts; + upPsCosts = NULL; + if (downPsCosts != NULL) delete [] downPsCosts; + downPsCosts = NULL; + } + ~BranchingInfo() + { + gutsOfDestructor(); + } + }; + + /** Class to store perturbation radii for variables in the model */ + class PerturbInfo + { + public: + /** default constructor. */ + PerturbInfo() : + perturb_radius_(NULL) + {} + + /** destructor*/ + ~PerturbInfo() + { + delete [] perturb_radius_; + } + + /** Method for setting the perturbation radii. */ + void SetPerturbationArray(Ipopt::Index numvars, const double* perturb_radius); + + /** Method for getting the array for the perturbation radii in + * order to use the values. */ + const double* GetPerturbationArray() const { + return perturb_radius_; + } + + private: + /** Copy constructor.*/ + PerturbInfo(const PerturbInfo & source); + + /** Perturbation radii for all variables. A negative value + * means that the radius has not been given. If the pointer is + * NULL, then no variables have been assigned a perturbation + * radius. */ + double* perturb_radius_; + }; + + /** Type of the variables.*/ + enum VariableType + { + CONTINUOUS, + BINARY, + INTEGER + }; + + /**@name Constructors/Destructors */ + //@{ + TMINLP(); + + /** Default destructor */ + virtual ~TMINLP(); + //@} + + /**@name methods to gather information about the MINLP */ + //@{ + /** overload this method to return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style)=0; + + /** overload this method to return scaling parameters. This is + * only called if the options are set to retrieve user scaling. + * There, use_x_scaling (or use_g_scaling) should get set to true + * only if the variables (or constraints) are to be scaled. This + * method should return true only if the scaling parameters could + * be provided. + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling) + { + return false; + } + + + /** overload this method to provide the variables types. The var_types + * array will be allocated with length n. */ + virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types)=0; + + /** overload this method to provide the variables linearity. + * array should be allocated with length at least n.*/ + virtual bool get_variables_linearity(Ipopt::Index n, + Ipopt::TNLP::LinearityType* var_types) = 0; + + /** overload this method to provide the constraint linearity. + * array should be allocated with length at least m.*/ + virtual bool get_constraints_linearity(Ipopt::Index m, + Ipopt::TNLP::LinearityType* const_types) = 0; + + /** overload this method to return the information about the bound + * on the variables and constraints. The value that indicates + * that a bound does not exist is specified in the parameters + * nlp_lower_bound_inf and nlp_upper_bound_inf. By default, + * nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is + * 1e19. + * An exception will be thrown if x_l and x_u are not 0,1 for binary variables + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)=0; + + /** overload this method to return the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda)=0; + + /** overload this method to return the value of the objective function */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value)=0; + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f)=0; + + /** overload this method to return the vector of constraint values */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g)=0; + + /** overload this method to return the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values)=0; + + /** overload this method to return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values)=0; + /** Compute the value of a single constraint. The constraint + * number is i (starting counting from 0. */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi) + { + std::cerr << "Method eval_gi not overloaded from TMINLP\n"; + throw -1; + } + /** Compute the structure or values of the gradient for one + * constraint. The constraint * number is i (starting counting + * from 0. Other things are like with eval_jac_g. */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values) + { + std::cerr << "Method eval_grad_gi not overloaded from TMINLP\n"; + throw -1; + } + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(TMINLP::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value) =0; + //@} + + virtual const BranchingInfo * branchingInfo() const = 0; + + virtual const SosInfo * sosConstraints() const = 0; + + virtual const PerturbInfo* perturbInfo() const + { + return NULL; + } + + /** Say if has a specific function to compute upper bounds*/ + virtual bool hasUpperBoundingObjective(){ + return false;} + + /** overload this method to return the value of an alternative objective function for + upper bounding (to use it hasUpperBoundingObjective should return true).*/ + virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x, + Ipopt::Number& obj_value){ return false; } + + /** Used to mark constraints of the problem.*/ + enum Convexity { + Convex/** Constraint is convex.*/, + NonConvex/** Constraint is non-convex.*/, + SimpleConcave/** Constraint is concave of the simple form y >= F(x).*/}; + + /** Structure for marked non-convex constraints. With possibility of + storing index of a constraint relaxing the non-convex constraint*/ + struct MarkedNonConvex { + /** Default constructor gives "safe" values.*/ + MarkedNonConvex(): + cIdx(-1), cRelaxIdx(-1){} + /** Index of the nonconvex constraint.*/ + int cIdx; + /** Index of constraint relaxing the nonconvex constraint.*/ + int cRelaxIdx;}; + /** Structure which describes a constraints of the form + $f[ y \gt F(x) \f] + with \f$ F(x) \f$ a concave function.*/ + struct SimpleConcaveConstraint{ + /** Default constructor gives "safe" values.*/ + SimpleConcaveConstraint(): + xIdx(-1), yIdx(-1), cIdx(-1){} + /** Index of the variable x.*/ + int xIdx; + /** Index of the variable y.*/ + int yIdx; + /** Index of the constraint.*/ + int cIdx;}; + /** Get accest to constraint convexities.*/ + virtual bool get_constraint_convexities(int m, TMINLP::Convexity * constraints_convexities)const { + CoinFillN(constraints_convexities, m, TMINLP::Convex); + return true;} + /** Get dimension information on nonconvex constraints.*/ + virtual bool get_number_nonconvex(int & number_non_conv, int & number_concave) const{ + number_non_conv = 0; + number_concave = 0; + return true;} + /** Get array describing the constraints marked nonconvex in the model.*/ + virtual bool get_constraint_convexities(int number_non_conv, MarkedNonConvex * non_convs) const{ + assert(number_non_conv == 0); + return true;} + /** Fill array containing indices of simple concave constraints.*/ + virtual bool get_simple_concave_constraints(int number_concave, SimpleConcaveConstraint * simple_concave) const{ + assert(number_concave == 0); + return true;} + + /** Say if problem has a linear objective (for OA) */ + virtual bool hasLinearObjective(){return false;} + + /** Say if problem has general integer variables.*/ + bool hasGeneralInteger(); + + /** Access array describing constraint to which perspectives should be applied.*/ + virtual const int * get_const_xtra_id() const{ + return NULL; + } + protected: + /** Copy constructor */ + //@{ + /** Copy Constructor */ + TMINLP(const TMINLP&); + + /** Overloaded Equals Operator */ + void operator=(const TMINLP&); + //@} + + private: + }; + +} // namespace Ipopt + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTMINLP2OsiLP.hpp b/thirdparty/linux/include/coin/coin/BonTMINLP2OsiLP.hpp new file mode 100644 index 0000000..09fb186 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMINLP2OsiLP.hpp @@ -0,0 +1,164 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/16/2007 +#ifndef BonminTMINLP2OsiLP_H +#define BonminTMINLP2OsiLP_H + +#include <cmath> +#include <cstdio> +#include "IpSmartPtr.hpp" +#include "IpTNLP.hpp" +#include "BonTypes.hpp" + +class OsiSolverInterface; +class OsiCuts; + +namespace Bonmin { + class TMINLP2TNLP; + class BabSetupBase; + + /** A transformer class to build outer approximations i.e. transfomrs nonlinear programs into linear programs.*/ + class TMINLP2OsiLP: public Ipopt::ReferencedObject { + + public: + + /** Default constructor.*/ + TMINLP2OsiLP(): + tiny_(-0.), + very_tiny_(-0.) + {} + + /** Copy constructor.*/ + TMINLP2OsiLP(const TMINLP2OsiLP & other): + tiny_(other.tiny_), + very_tiny_(other.very_tiny_), + model_(other.model_){ + } + + /** virtual copy constructor*/ + virtual TMINLP2OsiLP * clone() const = 0; + + void set_tols(double tiny, double very_tiny, double rhs_relax, double infty){ + tiny_ = tiny; + very_tiny_ = very_tiny; + rhs_relax_ = rhs_relax; + infty_ = infty; + } + + void set_model(Bonmin::TMINLP2TNLP * model){ + model_ = model; + initialize_jac_storage(); + } + + /** Assignment operator.*/ + TMINLP2OsiLP & operator=(const TMINLP2OsiLP& rhs){ + if(this != & rhs){ + tiny_ = rhs.tiny_; + very_tiny_ = rhs.very_tiny_; + model_ = rhs.model_; + } + return (*this); + } + + /** Destructor.*/ + ~TMINLP2OsiLP(){} + + /** Build the Outer approximation of model_ in x and put it in si.*/ + virtual void extract(OsiSolverInterface *si, + const double * x, bool getObj) = 0; + + +/** Get OAs of nonlinear constraints in x.*/ + virtual void get_refined_oa(OsiCuts & cs + ) const = 0; + +/** Get OAs of nonlinear constraints in x.*/ + virtual void get_oas(OsiCuts & cs, + const double * x, bool getObj, bool global) const = 0; + + + + protected: + /** Facilitator to clean up coefficient.*/ + inline bool cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) const; + /** If constraint coefficient is below this, we try to remove it.*/ + double tiny_; + /** If constraint coefficient is below this, we neglect it.*/ + double very_tiny_; + /** Amount by which to relax OA constraints RHSes*/ + double rhs_relax_; + /** infinity.*/ + double infty_; + /** Count the number of linear outer approximations taken.*/ + static int nTimesCalled; + + /** Cache Jacobian matrix*/ + /** Columns of jacobian.*/ + mutable vector<int> jCol_; + /** Rows of jacobian.*/ + mutable vector<int> iRow_; + /** Values of jacobian.*/ + mutable vector<double> value_; + + vector<Ipopt::TNLP::LinearityType> const_types_; + + void initialize_jac_storage(); + + Ipopt::SmartPtr<Bonmin::TMINLP2TNLP> model_; + }; + +//A procedure to try to remove small coefficients in OA cuts (or make it non small +inline +bool +TMINLP2OsiLP::cleanNnz(double &value, double colLower, double colUpper, + double rowLower, double rowUpper, double colsol, + double & lb, double &ub, double tiny, double veryTiny) const +{ + if(fabs(value)>= tiny) return 1; + //fprintf(stderr, "Warning: small coefficient %g\n", tiny); + + if(fabs(value)<veryTiny) return 0;//Take the risk? + + //try and remove + double infty = 1e20; + bool colUpBounded = colUpper < 10000; + bool colLoBounded = colLower > -10000; + bool rowNotLoBounded = rowLower <= - infty; + bool rowNotUpBounded = rowUpper >= infty; + bool pos = value > 0; + + if(colLoBounded && !pos && rowNotUpBounded) { + lb += value * (colsol - colLower); + return 0; + } + else + if(colLoBounded && pos && rowNotLoBounded) { + ub += value * (colsol - colLower); + return 0; + } + else + if(colUpBounded && pos && rowNotUpBounded) { + lb += value * (colsol - colUpper); + return 0; + } + else + if(colUpBounded && !pos && rowNotLoBounded) { + ub += value * (colsol - colUpper); + return 0; + } + //can not remove coefficient + return 1; +} + + +} + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTMINLP2Quad.hpp b/thirdparty/linux/include/coin/coin/BonTMINLP2Quad.hpp new file mode 100644 index 0000000..4d7f0c6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMINLP2Quad.hpp @@ -0,0 +1,191 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef __TMINLPQuad_HPP__ +#define __TMINLPQuad_HPP__ + +#include "BonTMINLP2TNLP.hpp" +#include "BonQuadRow.hpp" + +namespace Bonmin +{ + + + /** This is a derived class fro TMINLP2TNLP to handle adding quadratic cuts. + */ + class TMINLP2TNLPQuadCuts : public Bonmin::TMINLP2TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + TMINLP2TNLPQuadCuts(const Ipopt::SmartPtr<Bonmin::TMINLP> tminlp +#ifdef WARM_STARTER + , + const OptionsList& options +#endif + ); + + + /** Copy Constructor + * \warning source and copy point to the same tminlp_. + */ + TMINLP2TNLPQuadCuts(const TMINLP2TNLPQuadCuts&); + + /** Virtual copy.*/ + virtual Bonmin::TMINLP2TNLP * clone() const{ + printf("Cloning TMINLP2TNLPQuadCuts.\n"); + return new TMINLP2TNLPQuadCuts(*this);} + + /** Destructor */ + virtual ~TMINLP2TNLPQuadCuts(); + //@} + /**@name methods to gather information about the NLP */ + //@{ + /** This call is just passed onto parent class and add number of quadratic + cuts*/ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, + Ipopt::TNLP::IndexStyleEnum& index_style); + + /** This call is just passed onto parent class and add bounds of quadratic + cuts*/ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + virtual bool get_constraints_linearity(Ipopt::Index m, Ipopt::TNLP::LinearityType* const_types); + + /** This call is just passed onto parent class and add + lambda for quadratic cuts*/ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method that returns scaling parameters (passed to parent all quadratic + not scaled). + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x (appends constraint values for quadratics).*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + /** compute the value of a single constraint */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** compute the structure or values of the gradient for one + constraint */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + + /** \name Cuts management. */ + //@{ + + + /** Add some linear or quadratic cuts to the problem formulation + if some of the OsiRowCuts are quadratic they will be well understood as long as safe is true.*/ + void addCuts(const Cuts& cuts, bool safe); + + + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + void addCuts(const OsiCuts &cuts); + + /** Add some linear cuts to the problem formulation.*/ + virtual void addCuts(unsigned int numberCuts, const OsiRowCut ** cuts); + + + /** Remove some cuts from the formulation */ + void removeCuts(unsigned int number ,const int * toRemove); + + //@} + // + /** Change objective to a linear one whith given objective function.*/ + void set_linear_objective(int n_var, const double * obj, double c_0); + + /** Reset objective to original one */ + void reset_objective(){ + obj_.clear(); + } + + protected: + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + void addRowCuts(const OsiCuts &cuts, bool safe); + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TMINLP2TNLPQuadCuts(); + + /** Overloaded Equals Operator */ + TMINLP2TNLPQuadCuts& operator=(const TMINLP2TNLP&); + //@} + + private: + /** Some storage for quadratic cuts.*/ + vector<QuadRow *> quadRows_; + + /** Storage for the original hessian of the problem.*/ + AdjustableMat H_; + + /** print H_ for debug.*/ + void printH(); + /** Current umber of entries in the jacobian.*/ + int curr_nnz_jac_; + + /** Store user passed linear objective.*/ + vector<double> obj_; + /** constant term in objective function.*/ + double c_; + }; + +} // namespace Ipopt + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTMINLP2TNLP.hpp b/thirdparty/linux/include/coin/coin/BonTMINLP2TNLP.hpp new file mode 100644 index 0000000..7523fc1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMINLP2TNLP.hpp @@ -0,0 +1,509 @@ +// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2004, 2006 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, Carnegie Mellon University, +// Carl D. Laird, Carnegie Mellon University, +// Andreas Waechter, International Business Machines Corporation +// +// Date : 12/01/2004 + +#ifndef __TMINLP2TNLP_HPP__ +#define __TMINLP2TNLP_HPP__ + +#include "IpTNLP.hpp" +#include "BonTMINLP.hpp" +#include "IpSmartPtr.hpp" +#include "IpIpoptApplication.hpp" +#include "IpOptionsList.hpp" +#include "BonTypes.hpp" + +namespace Bonmin +{ + class IpoptInteriorWarmStarter; + + /** This is an adapter class that converts a TMINLP to + * a TNLP to be solved by Ipopt. It allows an external + * caller to modify the bounds of variables, allowing + * the treatment of binary and integer variables as + * relaxed, or fixed + */ + class TMINLP2TNLP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + TMINLP2TNLP(const Ipopt::SmartPtr<TMINLP> tminlp +#ifdef WARM_STARTER + , + const OptionsList& options +#endif + ); + + /** Copy Constructor + * \warning source and copy point to the same tminlp_. + */ + TMINLP2TNLP(const TMINLP2TNLP&); + + /** virtual copy .*/ + virtual TMINLP2TNLP * clone() const{ + return new TMINLP2TNLP(*this);} + + /** Default destructor */ + virtual ~TMINLP2TNLP(); + //@} + + /**@name Methods to modify the MINLP and form the NLP */ + //@{ + + /** Get the number of variables */ + inline Ipopt::Index num_variables() const + { + assert(x_l_.size() == x_u_.size()); + return static_cast<int>(x_l_.size()); + } + + /** Get the number of constraints */ + inline Ipopt::Index num_constraints() const + { + assert(g_l_.size() == g_u_.size()); + return static_cast<int>(g_l_.size()); + } + /** Get the nomber of nz in hessian */ + Ipopt::Index nnz_h_lag() + { + return nnz_h_lag_; + } + /** Get the variable types */ + const TMINLP::VariableType* var_types() + { + return &var_types_[0]; + } + + /** Get the current values for the lower bounds */ + const Ipopt::Number* x_l() + { + return &x_l_[0]; + } + /** Get the current values for the upper bounds */ + const Ipopt::Number* x_u() + { + return &x_u_[0]; + } + + /** Get the original values for the lower bounds */ + const Ipopt::Number* orig_x_l() const + { + return &orig_x_l_[0]; + } + /** Get the original values for the upper bounds */ + const Ipopt::Number* orig_x_u() const + { + return orig_x_u_(); + } + + /** Get the current values for constraints lower bounds */ + const Ipopt::Number* g_l() + { + return g_l_(); + } + /** Get the current values for constraints upper bounds */ + const Ipopt::Number* g_u() + { + return g_u_(); + } + + /** get the starting primal point */ + const Ipopt::Number * x_init() const + { + return x_init_(); + } + + /** get the user provided starting primal point */ + const Ipopt::Number * x_init_user() const + { + return x_init_user_(); + } + + /** get the starting dual point */ + const Ipopt::Number * duals_init() const + { + return duals_init_; + } + + /** get the solution values */ + const Ipopt::Number* x_sol() const + { + return x_sol_(); + } + + /** get the g solution (activities) */ + const Ipopt::Number* g_sol() const + { + return g_sol_(); + } + + /** get the dual values */ + const Ipopt::Number* duals_sol() const + { + return duals_sol_(); + } + + /** Get Optimization status */ + Ipopt::SolverReturn optimization_status() const + { + return return_status_; + } + + /** Get the objective value */ + Ipopt::Number obj_value() const + { + return obj_value_; + } + + /** Manually set objective value. */ + void set_obj_value(Ipopt::Number value) + { + obj_value_ = value; + } + + /** force solution to be fractionnal.*/ + void force_fractionnal_sol(); + + /** Change the bounds on the variables */ + void SetVariablesBounds(Ipopt::Index n, + const Ipopt::Number * x_l, + const Ipopt::Number * x_u); + + /** Change the lower bound on the variables */ + void SetVariablesLowerBounds(Ipopt::Index n, + const Ipopt::Number * x_l); + + /** Change the upper bound on the variable */ + void SetVariablesUpperBounds(Ipopt::Index n, + const Ipopt::Number * x_u); + + /** Change the bounds on the variable */ + void SetVariableBounds(Ipopt::Index var_no, Ipopt::Number x_l, Ipopt::Number x_u); + + /** Change the lower bound on the variable */ + void SetVariableLowerBound(Ipopt::Index var_no, Ipopt::Number x_l); + + /** Change the upper bound on the variable */ + void SetVariableUpperBound(Ipopt::Index var_no, Ipopt::Number x_u); + + /** reset the starting point to original one. */ + void resetStartingPoint(); + + /** set the starting point to x_init */ + void setxInit(Ipopt::Index n,const Ipopt::Number* x_init); + + /** set the dual starting point to duals_init */ + void setDualsInit(Ipopt::Index n, const Ipopt::Number* duals_init); + + /** xInit has been set? + * \return 0 if not, 1 if only primal 2 if primal dual.*/ + int has_x_init(){ + if(x_init_.empty()) return 0; + if(duals_init_) return 2; + return 1; + } + /** Set the contiuous solution */ + void Set_x_sol(Ipopt::Index n, const Ipopt::Number* x_sol); + + /** Set the contiuous dual solution */ + void Set_dual_sol(Ipopt::Index n, const Ipopt::Number* dual_sol); + + /** Change the type of the variable */ + void SetVariableType(Ipopt::Index n, TMINLP::VariableType type); + //@} + /** Procedure to ouptut relevant informations to reproduce a sub-problem. + Compare the current problem to the problem to solve + and writes files with bounds which have changed and current starting point. + */ + void outputDiffs(const std::string& probName, const std::string* varNames); + + /**@name methods to gather information about the NLP */ + //@{ + /** This call is just passed onto the TMINLP object */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, + TNLP::IndexStyleEnum& index_style); + + /** The caller is allowed to modify the bounds, so this + * method returns the internal bounds information + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Returns the constraint linearity. + * array should be alocated with length at least m..*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types) + { + return tminlp_->get_constraints_linearity(m, const_types); + } + + /** Returns the variables linearity. + * array should be alocated with length at least n..*/ + virtual bool get_variables_linearity(Ipopt::Index n, LinearityType* var_types) + { + return tminlp_->get_variables_linearity(n, var_types); + } + + /** returns true if objective is linear.*/ + virtual bool hasLinearObjective(){return tminlp_->hasLinearObjective();} + /** Method called by Ipopt to get the starting point. The bools + * init_x and init_lambda are both inputs and outputs. As inputs, + * they indicate whether or not the algorithm wants you to + * initialize x and lambda respectively. If, for some reason, the + * algorithm wants you to initialize these and you cannot, set + * the respective bool to false. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Method that returns scaling parameters. + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Methat that returns an Ipopt IteratesVector that has the + * starting point for all internal varibles. */ + virtual bool get_warm_start_iterate(Ipopt::IteratesVector& warm_start_iterate); + + /** Returns the value of the objective function in x*/ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** Returns the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** Returns the vector of constraint values in x*/ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Returns the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** compute the value of a single constraint */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** compute the structure or values of the gradient for one + constraint */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + + /** Return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only */ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + /** Intermediate Callback method for the user. Providing dummy + * default implementation. For details see IntermediateCallBack + * in IpNLP.hpp. */ + virtual bool intermediate_callback(Ipopt::AlgorithmMode mode, + Ipopt::Index iter, Ipopt::Number obj_value, + Ipopt::Number inf_pr, Ipopt::Number inf_du, + Ipopt::Number mu, Ipopt::Number d_norm, + Ipopt::Number regularization_size, + Ipopt::Number alpha_du, Ipopt::Number alpha_pr, + Ipopt::Index ls_trials, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method called to check wether a problem has still some variable not fixed. If there are no more + unfixed vars, checks wether the solution given by the bounds is feasible.*/ + + /** @name Methods for setting and getting the warm starter */ + //@{ + void SetWarmStarter(Ipopt::SmartPtr<IpoptInteriorWarmStarter> warm_starter); + + Ipopt::SmartPtr<IpoptInteriorWarmStarter> GetWarmStarter(); + + //@} + + /** Say if has a specific function to compute upper bounds*/ + virtual bool hasUpperBoundingObjective(){ + return tminlp_->hasUpperBoundingObjective();} + + /** Evaluate the upper bounding function at given point and store the result.*/ + double evaluateUpperBoundingFunction(const double * x); + + /** \name Cuts management. */ + /** Methods are not implemented at this point. But I need the interface.*/ + //@{ + + + /** Add some linear cuts to the problem formulation (not implemented yet in base class).*/ + virtual void addCuts(unsigned int numberCuts, const OsiRowCut ** cuts){ + if(numberCuts > 0) + throw CoinError("BonTMINLP2TNLP", "addCuts", "Not implemented");} + + + /** Add some cuts to the problem formulaiton (handles Quadratics).*/ + virtual void addCuts(const OsiCuts &cuts){ + if(cuts.sizeRowCuts() > 0 || cuts.sizeColCuts() > 0) + throw CoinError("BonTMINLP2TNLP", "addCuts", "Not implemented");} + + /** Remove some cuts to the formulation */ + virtual void removeCuts(unsigned int number ,const int * toRemove){ + if(number > 0) + throw CoinError("BonTMINLP2TNLP", "removeCuts", "Not implemented");} + + //@} + + + /** Access array describing constraint to which perspectives should be applied.*/ + virtual const int * get_const_xtra_id() const{ + return tminlp_->get_const_xtra_id(); + } + + /** Round and check the current solution, return norm inf of constraint violation.*/ + double check_solution(OsiObject ** objects = 0, int nObjects = -1); + protected: + /** \name These should be modified in derived class to always maintain there correctness. + They are directly queried by OsiTMINLPInterface without virtual function for + speed.*/ + /** @{ */ + /// Types of the variable (TMINLP::CONTINUOUS, TMINLP::INTEGER, TMINLP::BINARY). + vector<TMINLP::VariableType> var_types_; + /// Current lower bounds on variables + vector<Ipopt::Number> x_l_; + /// Current upper bounds on variables + vector<Ipopt::Number> x_u_; + /// Original lower bounds on variables + vector<Ipopt::Number> orig_x_l_; + /// Original upper bounds on variables + vector<Ipopt::Number> orig_x_u_; + /// Lower bounds on constraints values + vector<Ipopt::Number> g_l_; + /// Upper bounds on constraints values + vector<Ipopt::Number> g_u_; + /// Initial primal point + vector<Ipopt::Number> x_init_; + /** Initial values for all dual multipliers (constraints then lower bounds then upper bounds) */ + Ipopt::Number * duals_init_; + /// User-provideed initial prmal point + vector<Ipopt::Number> x_init_user_; + /// Optimal solution + vector<Ipopt::Number> x_sol_; + /// Activities of constraint g( x_sol_) + vector<Ipopt::Number> g_sol_; + /** Dual multipliers of constraints and bounds*/ + vector<Ipopt::Number> duals_sol_; + /** @} */ + + /** Access number of entries in tminlp_ hessian*/ + Ipopt::Index nnz_h_lag() const{ + return nnz_h_lag_;} + /** Access number of entries in tminlp_ hessian*/ + Ipopt::Index nnz_jac_g() const{ + return nnz_jac_g_;} + + /** Acces index_style.*/ + TNLP::IndexStyleEnum index_style() const{ + return index_style_;} + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TMINLP2TNLP(); + + /** Overloaded Equals Operator */ + TMINLP2TNLP& operator=(const TMINLP2TNLP&); + //@} + + /** pointer to the tminlp that is being adapted */ + Ipopt::SmartPtr<TMINLP> tminlp_; + + /** @name Internal copies of data allowing caller to modify the MINLP */ + //@{ + /// Number of non-zeroes in the constraints jacobian. + Ipopt::Index nnz_jac_g_; + /// Number of non-zeroes in the lagrangian hessian + Ipopt::Index nnz_h_lag_; + /**index style (fortran or C)*/ + TNLP::IndexStyleEnum index_style_; + + /** Return status of the optimization process*/ + Ipopt::SolverReturn return_status_; + /** Value of the optimal solution found by Ipopt */ + Ipopt::Number obj_value_; + //@} + + /** @name Warmstart object and related data */ + //@{ + /** Pointer to object that holds warmstart information */ + Ipopt::SmartPtr<IpoptInteriorWarmStarter> curr_warm_starter_; + /** Value for a lower bound that denotes -infinity */ + Ipopt::Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Ipopt::Number nlp_upper_bound_inf_; + /** Option from Ipopt - we currently use it to see if we want to + * use some clever warm start or just the last iterate from the + * previous run */ + bool warm_start_entire_iterate_; + /** Do we need a new warm starter object */ + bool need_new_warm_starter_; + //@} + + + /** Private method that throws an exception if the variable bounds + * are not consistent with the variable type */ + void throw_exception_on_bad_variable_bound(Ipopt::Index i); + + private: + // Delete all arrays + void gutsOfDelete(); + + /** Copies all the arrays. + \warning this and other should be two instances of the same problem + \warning AW: I am trying to mimic a copy construction for Cbc + use with great care not safe. + */ + void gutsOfCopy(const TMINLP2TNLP &source); + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/BonTMINLPLinObj.hpp b/thirdparty/linux/include/coin/coin/BonTMINLPLinObj.hpp new file mode 100644 index 0000000..819bc57 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMINLPLinObj.hpp @@ -0,0 +1,216 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 08/16/2007 + + +#ifndef TMINLPLinObj_H +#define TMINLPLinObj_H + +#include "BonTMINLP.hpp" + +namespace Bonmin { +/** From a TMINLP, this class adapts to another TMINLP where the original objective is transformed into a constraint + by adding an extra variable which is minimized. + + More precisely + \f[ + \begin{array}{l} + \min f(x)\\ + s.t\\ + g_l \leq g(x) \leq g_u\\ + x_l \leq x \leq u + \end{array} + \f] + is transformed ino + \begin{array}{l} + \min \eta\\ + s.t\\ + -\infty \leq f(x) - \eta \leq 0\\ + g_l \leq g(x) \leq g_u\\ + x_l \leq x \leq u + \end{array} + \f] + The objective is put as first constraint of the problem and the extra variable is the last one. + .*/ +class TMINLPLinObj: public Bonmin::TMINLP { + public: + /** Default constructor*/ + TMINLPLinObj(); + + /** destructor.*/ + virtual ~TMINLPLinObj(); + + /** set reference TMINLP */ + void setTminlp(Ipopt::SmartPtr<TMINLP> tminlp); + + /**@name methods to gather information about the MINLP */ + //@{ + /** Return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. Call tminlp_ one but number of constraints and non-zeroes in the jacobian is stored internally.*/ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + /** Return scaling parameters. If tminlp_ method returns true, translate + * constraint scaling (if asked). + */ + virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling, + bool& use_x_scaling, Ipopt::Index n, + Ipopt::Number* x_scaling, + bool& use_g_scaling, Ipopt::Index m, + Ipopt::Number* g_scaling); + + + /** Get the variable type. Just call tminlp_'s method;. */ + virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types){ + assert(IsValid(tminlp_)); + assert(n == n_); + var_types[n-1] = TMINLP::CONTINUOUS; + return tminlp_->get_variables_types(n - 1, var_types); + } + + /** Return the constraints linearity. Call tminlp_'s method and translate. + */ + virtual bool get_constraints_linearity(Ipopt::Index m, + Ipopt::TNLP::LinearityType* const_types); + + /** Return the information about the bound + * on the variables and constraints. Call tminlp_'s method and translate + * constraints bounds.*/ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Return the starting point. + Have to translate z_L and z_U. + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda); + + /** Return the value of the objective function. + * Just call tminlp_ method. */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value){ + assert(n == n_); + obj_value = x[n-1]; + return true;} + + /** Return the vector of the gradient of + * the objective w.r.t. x. Just call tminlp_ method. */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f){ + assert(IsValid(tminlp_)); + assert(n == n_); + n--; + for(int i = 0 ; i < n ; i++){ + grad_f[i] = 0;} + grad_f[n] = 1; + return true;} + + /** Return the vector of constraint values. + * Use tminlp_ functions and use mapping to get the needed values. */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** Return the jacobian of the constraints. + * In first call nothing to change. In later just fix the values for the simple concaves + * and remove entries corresponding to nonConvex constraints. */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** \brief Return the hessian of the lagrangian. + * Here we just put lambda in the correct format and call + * tminlp_'s function.*/ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + /** Compute the value of a single constraint. The constraint + * number is i (starting counting from 0. */ + virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Number& gi); + /** Compute the structure or values of the gradient for one + * constraint. The constraint * number is i (starting counting + * from 0. Other things are like with eval_jac_g. */ + virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol, + Ipopt::Number* values); + //@} + + virtual bool get_variables_linearity(Ipopt::Index n, Ipopt::TNLP::LinearityType* c){ + assert(IsValid(tminlp_)); + assert(n == n_); + bool r_val = tminlp_->get_variables_linearity(n-1, c); + c[n - 1] = Ipopt::TNLP::LINEAR; + return r_val; + } + + + /** @name Solution Methods */ + //@{ + /** Use tminlp_ function.*/ + virtual void finalize_solution(TMINLP::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value){ + return tminlp_->finalize_solution(status, n - 1, x, + obj_value); + } + //@} + + /** Use tminlp_ function.*/ + virtual const BranchingInfo * branchingInfo() const{ + return tminlp_->branchingInfo(); + } + + /** Use tminlp_ function. + \bug Has to translate sos information.*/ + virtual const SosInfo * sosConstraints() const{ + return tminlp_->sosConstraints(); + } + /** Use tminlp_ function.*/ + virtual const PerturbInfo* perturbInfo() const + { + return tminlp_->perturbInfo(); + } + + /** Use tminlp_ function.*/ + virtual bool hasUpperBoundingObjective(){ + assert(IsValid(tminlp_)); + return tminlp_->hasUpperBoundingObjective();} + + /** Use tminlp_ function.*/ + virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x, + Ipopt::Number& obj_value){ + assert(IsValid(tminlp_)); + return tminlp_->eval_upper_bound_f(n - 1, x, obj_value); } + + /** Say if problem has a linear objective (for OA) */ + virtual bool hasLinearObjective(){return true;} + /** return pointer to tminlp_.*/ + Ipopt::SmartPtr<TMINLP> tminlp(){return tminlp_;} + private: + /** Reset all data.*/ + void gutsOfDestructor(); + + /** Reference TMINLP which is to be relaxed.*/ + Ipopt::SmartPtr<TMINLP> tminlp_; + /** Ipopt::Number of constraints in the transformed MINLP.*/ + int m_; + /** Ipopt::Number of variables in the transformed MINLP.*/ + int n_; + /** number of non-zeroes in the jacobian of the transformed MINLP.*/ + int nnz_jac_; + /** offset for jacobian.*/ + int offset_; + +}; + + +}/* Ends Bonmin namepsace.*/ + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTMatrix.hpp b/thirdparty/linux/include/coin/coin/BonTMatrix.hpp new file mode 100644 index 0000000..2aa6316 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTMatrix.hpp @@ -0,0 +1,167 @@ +// (C) Copyright International Business Machines Corporation 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, International Business Machines Corporation +// +// Date : 10/06/2007 + +#ifndef BonTMatrix_H +#define BonTMatrix_H + +#include "CoinPackedMatrix.hpp" +#include "BonArraysHelpers.hpp" +#include <vector> +#include <list> +#include <algorithm> +#include "BonQuadCut.hpp" + +namespace Bonmin { + +struct TMat{ + int * iRow_; + int * jCol_; + double * value_; + int nnz_; + int capacity_; + + + /** Storage for non empty rows. + first is row number and second is first element in row.*/ + typedef vector< std::pair< int, int> > RowS; + + /** Default constructor.*/ + TMat(): iRow_(NULL), jCol_(NULL), value_(NULL), nnz_(0), + capacity_(0) + {} + + + void freeSpace(){ + delete [] iRow_; + delete [] jCol_; + delete [] value_; + } + + /** Copy constructor.*/ + TMat(const TMat &other); + + /** Construct from a CoinPackedMatrix*/ + TMat(const CoinPackedMatrix &M, MatrixStorageType T); + + /** Assignment operator.*/ + TMat& operator=(const TMat &rhs); + + /** Assignment from a CoinPackedMatrix.*/ + TMat & operator=(const CoinPackedMatrix &M); + + void resize(int nnz){ + Bonmin::resizeAndCopyArray(iRow_, nnz_, nnz); + Bonmin::resizeAndCopyArray(jCol_, nnz_, nnz); + Bonmin::resizeAndCopyArray(value_, nnz_, nnz); + nnz_ = nnz; + } + + ~TMat(); + + /** Get number of non empty rows.*/ + int numNonEmptyRows(); + + /** Get the list of non empty row.*/ + const RowS & nonEmptyRows() const { + return nonEmptyRows_;} + + /** Get number of non empty cols.*/ + int numNonEmptyCols(); + + /** Get the list of non empty row.*/ + const RowS & nonEmptyCols() const { + return nonEmptyCols_;} + + private: + /** Structure for ordering matrix.*/ + struct TMatOrdering{ + TMat * M_; + TMatOrdering(TMat *M): + M_(M){} + }; + + /** Structure for ordering matrix by columns.*/ + struct ColumnOrder : public TMatOrdering { + ColumnOrder(TMat *M): + TMatOrdering(M){} + + bool operator()(const int& i, const int& j){ + if (M_->jCol_[i] < M_->jCol_[j]) + return true; + if (M_->jCol_[i] == M_->jCol_[j] && M_->iRow_[i] < M_->iRow_[j]) + return true; + return false; + } + }; + + + /** Structure for ordering matrix by columns.*/ + struct RowOrder : public TMatOrdering { + RowOrder(TMat *M): + TMatOrdering(M){} + bool operator()(const int& i, const int& j){ + if (M_->iRow_[i]< M_->iRow_[j]) + return true; + if (M_->iRow_[i] == M_->iRow_[j] && M_->jCol_[i] < M_->jCol_[j]) + return true; + return false; + } + }; + public: + /** Orders current matrix by columns. */ + const vector<int>& orderByColumns(){ + resizeOrdering(columnOrdering_, nnz_); + std::sort(columnOrdering_.begin(), columnOrdering_.end(),ColumnOrder(this)); + return columnOrdering_; + } + /** Orders current matrix by rows.*/ + const vector<int>& orderByRows(){ + resizeOrdering(rowOrdering_, nnz_); + std::sort(rowOrdering_.begin(), rowOrdering_.end(), RowOrder(this)); + return rowOrdering_; + } + + /** Remove the duplicated entries.*/ + void removeDuplicates(); + + /** Assuming that this is representing a quadratic form. Produce equivalent + quadratic form with only upper triange stored.*/ + void makeQuadUpperDiag(); + + void resizeOrdering(vector<int> &ordering, unsigned int newSize){ + size_t oldSize = ordering.size(); + ordering.resize(newSize); + for(size_t i = oldSize ; i < newSize ; i++) + ordering[i] = static_cast<int>(i); + } + + /** Create the TMat from M.*/ + void create(const CoinPackedMatrix &M); + + vector<int> columnOrdering_; + + vector<int> rowOrdering_; + + void make_upper_triangular(const MatrixStorageType &T); + + void make_lower_to_be_upper(); + + void make_full_upper_triangular(); + + // Stores non empty rows for computing jacobian structure + RowS nonEmptyRows_; + + // Stores non empty cols for computing jacobian structure + RowS nonEmptyCols_; + }; + +}//Ends Bonmin namespace + +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonTNLP2FPNLP.hpp b/thirdparty/linux/include/coin/coin/BonTNLP2FPNLP.hpp new file mode 100644 index 0000000..82137c9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTNLP2FPNLP.hpp @@ -0,0 +1,264 @@ +// Copyright (C) 2004, International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// +// Authors: Pierre Bonami 06/10/2005 + +#ifndef _TNLP2FPNLP_HPP_ +#define _TNLP2FPNLP_HPP_ + +#include "IpTNLP.hpp" +#include "BonTMINLP.hpp" +#include "IpSmartPtr.hpp" +#include "BonTypes.hpp" + +namespace Bonmin +{ + /** This is an adapter class to convert an NLP to a Feasibility Pump NLP + * by changing the objective function to the (2-norm) distance to a point. + * The extra function is set_dist_to_point_obj(size_t n, const double *, const int *) + */ + class TNLP2FPNLP : public Ipopt::TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Build using tnlp as source problem.*/ + TNLP2FPNLP(const Ipopt::SmartPtr<Ipopt::TNLP> tnlp, double objectiveScalingFactor = 100); + + /** Build using tnlp as source problem and using other for all other parameters..*/ + TNLP2FPNLP(const Ipopt::SmartPtr<TNLP> tnlp, const Ipopt::SmartPtr<TNLP2FPNLP> other); + + /** Default destructor */ + virtual ~TNLP2FPNLP(); + //@} + void use(Ipopt::SmartPtr<TNLP> tnlp){ + tnlp_ = GetRawPtr(tnlp);} + /**@name Methods to select the objective function and extra constraints*/ + //@{ + /// Flag to indicate that we want to use the feasibility pump objective + void set_use_feasibility_pump_objective(bool use_feasibility_pump_objective) + { use_feasibility_pump_objective_ = use_feasibility_pump_objective; } + + /** Flag to indicate that we want to use a cutoff constraint + * This constraint has the form f(x) <= (1-epsilon) f(x') */ + void set_use_cutoff_constraint(bool use_cutoff_constraint) + { use_cutoff_constraint_ = use_cutoff_constraint; } + + /// Flag to indicate that we want to use a local branching constraint + void set_use_local_branching_constraint(bool use_local_branching_constraint) + { use_local_branching_constraint_ = use_local_branching_constraint; } + //@} + + /**@name Methods to provide the rhs of the extra constraints*/ + //@{ + /// Set the cutoff value to use in the cutoff constraint + void set_cutoff(Ipopt::Number cutoff); + + /// Set the rhs of the local branching constraint + void set_rhs_local_branching_constraint(double rhs_local_branching_constraint) + { assert(rhs_local_branching_constraint >= 0); + rhs_local_branching_constraint_ = rhs_local_branching_constraint; } + //@} + + /**@name Methods to change the objective function*/ + //@{ + /** \brief Set the point to which distance is minimized. + * The distance is minimize in a subspace define by a subset of coordinates + * \param n number of coordinates on which distance is minimized + * \param inds indices of the coordinates on which distance is minimized + * \param vals values of the point for coordinates in ind + */ + void set_dist_to_point_obj(size_t n, const Ipopt::Number * vals, const Ipopt::Index * inds); + + /** Set the value for sigma */ + void setSigma(double sigma){ + assert(sigma >= 0.); + sigma_ = sigma;} + /** Set the value for lambda*/ + void setLambda(double lambda){ + assert(lambda >= 0. && lambda <= 1.); + lambda_ = lambda;} + /** Set the value for simgma */ + void setNorm(int norm){ + assert(norm >0 && norm < 3); + norm_ = norm;} + //@} + + /**@name methods to gather information about the NLP */ + //@{ + /** get info from nlp_ and add hessian information */ + virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g, + Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style); + + /** This call is just passed onto tnlp_ + */ + virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u, + Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u); + + /** Passed onto tnlp_ + */ + virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x, + bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U, + Ipopt::Index m, bool init_lambda, + Ipopt::Number* lambda) + { + int m2 = m; + if(use_cutoff_constraint_) { + m2--; + if(lambda!=NULL)lambda[m2] = 0; + } + if(use_local_branching_constraint_) { + m2--; + if(lambda!= NULL)lambda[m2] = 0; + } + int ret_code = tnlp_->get_starting_point(n, init_x, x, + init_z, z_L, z_U, m2, init_lambda, lambda); + return ret_code; + } + + /** overloaded to return the value of the objective function */ + virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number& obj_value); + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number* grad_f); + + /** overload to return the values of the left-hand side of the + constraints */ + virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Number* g); + + /** overload to return the jacobian of g */ + virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, + Ipopt::Index *jCol, Ipopt::Number* values); + + /** Evaluate the modified Hessian of the Lagrangian*/ + virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x, + Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda, + bool new_lambda, Ipopt::Index nele_hess, + Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values); + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(Ipopt::SolverReturn status, + Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U, + Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda, + Ipopt::Number obj_value, + const Ipopt::IpoptData* ip_data, + Ipopt::IpoptCalculatedQuantities* ip_cq); + //@} + + virtual bool get_variables_linearity(Ipopt::Index n, LinearityType* var_types) + { + return tnlp_->get_variables_linearity(n, var_types);; + } + + /** overload this method to return the constraint linearity. + * array should be alocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_constraints_linearity(Ipopt::Index m, LinearityType* const_types) + { + int m2 = m; + if(use_cutoff_constraint_) { + m2--; + const_types[m2] = Ipopt::TNLP::NON_LINEAR; + } + if(use_local_branching_constraint_) { + m2--; + const_types[m2] = Ipopt::TNLP::LINEAR; + } + return tnlp_->get_constraints_linearity(m2, const_types); + } + /** @name Scaling of the objective function */ + //@{ + void setObjectiveScaling(double value) + { + objectiveScalingFactor_ = value; + } + double getObjectiveScaling() const + { + return objectiveScalingFactor_; + } + + private: + /** @name Internal methods to help compute the distance, its gradient and hessian */ + //@{ + /** Compute the norm-2 distance to the current point to which distance is minimized. */ + double dist_to_point(const Ipopt::Number *x); + //@} + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TNLP2FPNLP(); + + /** Copy Constructor */ + TNLP2FPNLP(const TNLP2FPNLP&); + + /** Overloaded Equals Operator */ + void operator=(const TNLP2FPNLP&); + //@} + + /** pointer to the tminlp that is being adapted */ + Ipopt::SmartPtr<TNLP> tnlp_; + + /** @name Data for storing the point the distance to which is minimized */ + //@{ + /// Indices of the variables for which distance is minimized (i.e. indices of integer variables in a feasibility pump setting) + vector<Ipopt::Index> inds_; + /// Values of the point to which we separate (if x is the point vals_[i] should be x[inds_[i]] ) + vector<Ipopt::Number> vals_; + /** value for the convex combination to take between original objective and distance function. + * ( take lambda_ * distance + (1-lambda) sigma f(x).*/ + double lambda_; + /** Scaling for the original objective.*/ + double sigma_; + /** Norm to use (L_1 or L_2).*/ + int norm_; + //@} + + /// Scaling factor for the objective + double objectiveScalingFactor_; + + /**@name Flags to select the objective function and extra constraints*/ + //@{ + /// Flag to indicate that we want to use the feasibility pump objective + bool use_feasibility_pump_objective_; + + /** Flag to indicate that we want to use a cutoff constraint + * This constraint has the form f(x) <= (1-epsilon) f(x') */ + bool use_cutoff_constraint_; + + /// Flag to indicate that we want to use a local branching constraint + bool use_local_branching_constraint_; + //@} + + /**@name Data for storing the rhs of the extra constraints*/ + //@{ + /// Value of best solution known + double cutoff_; + + /// RHS of local branching constraint + double rhs_local_branching_constraint_; + //@} + + /// Ipopt::Index style (C++ or Fortran) + Ipopt::TNLP::IndexStyleEnum index_style_; + + }; + +} // namespace Ipopt + +#endif /*_TNLP2FPNLP_HPP_*/ diff --git a/thirdparty/linux/include/coin/coin/BonTNLPSolver.hpp b/thirdparty/linux/include/coin/coin/BonTNLPSolver.hpp new file mode 100644 index 0000000..195fbad --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTNLPSolver.hpp @@ -0,0 +1,241 @@ +// (C) Copyright International Business Machines (IBM) 2006, 2007 +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// Authors : +// Pierre Bonami, IBM +// +// Date : 26/09/2006 + + +#ifndef TNLPSolver_H +#define TNLPSolver_H +#include "IpTNLP.hpp" +#include "BonTMINLP2TNLP.hpp" + +//Some declarations +#include "IpOptionsList.hpp" +#include "CoinWarmStart.hpp" +#include "BonRegisteredOptions.hpp" +#include "CoinTime.hpp" +namespace Bonmin { +/** This is a generic class for calling an NLP solver to solve a TNLP. + A TNLPSolver is able to solve and resolve a problem, it has some options (stored + with Ipopt OptionList structure and registeredOptions) it produces some statistics (in SolveStatisctics and sometimes some errorCodes. +*/ +class TNLPSolver: public Ipopt::ReferencedObject{ + public: + + enum ReturnStatus /** Standard return statuses for a solver*/{ + iterationLimit = -3/** Solver reached iteration limit. */, + timeLimit = 5/** Solver reached iteration limit. */, + doesNotConverge = -8/** Algorithm does not converge.*/, + computationError = -2/** Some error was made in the computations. */, + notEnoughFreedom = -1/** not enough degrees of freedom.*/, + illDefinedProblem = -4/** The solver finds that the problem is not well defined. */, + illegalOption =-5/** An option is not valid. */, + externalException =-6/** Some unrecovered exception occured in an external tool used by the solver. */, + exception =-7/** Some unrocevered exception */, + solvedOptimal = 1/** Problem solved to an optimal solution.*/, + solvedOptimalTol =2/** Problem solved to "acceptable level of tolerance. */, + provenInfeasible =3/** Infeasibility Proven. */, + unbounded = 4/** Problem is unbounded.*/, + numReturnCodes/**Fake member to know size*/ + }; + + + +//############################################################################# + + /** We will throw this error when a problem is not solved. + Eventually store the error code from solver*/ + class UnsolvedError + { + public: + /** Constructor */ + UnsolvedError(int errorNum = -10000, + Ipopt::SmartPtr<TMINLP2TNLP> model = NULL, + std::string name="") + : + errorNum_(errorNum), + model_(model), + name_(name) + {if(name_=="") +{ +#ifndef NDEBUG + std::cerr<<"FIXME"<<std::endl; +#endif +}} + /** Print error message.*/ + void printError(std::ostream & os); + /** Get the string corresponding to error.*/ + virtual const std::string& errorName() const = 0; + /** Return the name of the solver. */ + virtual const std::string& solverName() const = 0; + /** Return error number. */ + int errorNum() const{ + return errorNum_;} + /** destructor. */ + virtual ~UnsolvedError(){} + /** write files with differences between input model and + this one */ + void writeDiffFiles(const std::string prefix=std::string()) const; + private: + /** Error code (solver dependent). */ + int errorNum_; + + /** model_ on which error occured*/ + Ipopt::SmartPtr< TMINLP2TNLP > model_; + + /** name of the model on which error occured. */ + std::string name_; + } + ; + + virtual UnsolvedError * newUnsolvedError(int num, + Ipopt::SmartPtr<TMINLP2TNLP> problem, + std::string name) = 0; + + + + /// default Constructor + TNLPSolver(); + + ///Constructor with options initialization +TNLPSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions, + Ipopt::SmartPtr<Ipopt::OptionsList> options, + Ipopt::SmartPtr<Ipopt::Journalist> journalist, + const std::string & prefix); + + ///virtual copy constructor + virtual Ipopt::SmartPtr<TNLPSolver> clone() = 0; + + /// Virtual destructor + virtual ~TNLPSolver(); + + /** Initialize the TNLPSolver (read options from params_file) + */ + virtual bool Initialize(std::string params_file) = 0; + + /** Initialize the TNLPSolver (read options from istream is) + */ + virtual bool Initialize(std::istream& is) = 0; + + /** @name Solve methods */ + //@{ + /// Solves a problem expresses as a TNLP + virtual ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0; + + /// Resolves a problem expresses as a TNLP + virtual ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0; + + /// Set the warm start in the solver + virtual bool setWarmStart(const CoinWarmStart * warm, + Ipopt::SmartPtr<TMINLP2TNLP> tnlp) = 0; + +/// Get warm start used in last optimization + virtual CoinWarmStart * getUsedWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0; + + /// Get the warm start form the solver + virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0; + + virtual CoinWarmStart * getEmptyWarmStart() const = 0; + + /** Check that warm start object is valid.*/ + virtual bool warmStartIsValid(const CoinWarmStart * ws) const = 0; + + /// Enable the warm start options in the solver + virtual void enableWarmStart() = 0; + + /// Disable the warm start options in the solver + virtual void disableWarmStart() = 0; + //@} + + ///Get a pointer to a journalist + Ipopt::SmartPtr<Ipopt::Journalist> journalist(){ + return journalist_;} + + ///Get a pointer to RegisteredOptions (generally used to add new ones) + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions(){ + return roptions_;} + + /// Get the options (for getting their values). + Ipopt::SmartPtr<const Ipopt::OptionsList> options() const { + return ConstPtr(options_);} + + /// Get the options (for getting and setting their values). + Ipopt::SmartPtr<Ipopt::OptionsList> options() { + return options_;} + + /// Get the prefix + const char * prefix(){ + return prefix_.c_str(); + } + /// Register this solver options into passed roptions +static void RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){} + + /// Get the CpuTime of the last optimization. + virtual double CPUTime() = 0; + + /// Get the iteration count of the last optimization. + virtual int IterationCount() = 0; + + + /// turn off all output from the solver + virtual void setOutputToDefault() = 0 ; + /// turn on all output from the solver + virtual void forceSolverOutput(int log_level) = 0; + /// Get the solver name + virtual std::string & solverName() = 0; + + /** Say if an optimization status for a problem which failed is recoverable + (problem may be solvable).*/ + bool isRecoverable(ReturnStatus &r); + + /** Setup for a global time limit for solver.*/ + void setup_global_time_limit(double time_limit){ + time_limit_ = time_limit + 5; + start_time_ = CoinCpuTime(); + } + + /** Say if return status is an error.*/ + bool isError(ReturnStatus &r){ + return r < 0;} + /** Error code (solver specific).*/ +virtual int errorCode() const = 0; +protected: + /** Determine if problem is of dimension zero and if it is check if solution + is feasible.*/ + bool zeroDimension(const Ipopt::SmartPtr<Ipopt::TNLP> &tnlp, + ReturnStatus &optimization_status); + + /** Initializes options and journalist.*/ + void initializeOptionsAndJournalist(); + + /** Storage of Journalist for output */ + Ipopt::SmartPtr<Ipopt::Journalist> journalist_; + + /** List of Options */ + Ipopt::SmartPtr<Ipopt::OptionsList> options_; + + /** Registered Options */ + Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions_; + + /** Prefix to use for reading bonmin's options.*/ + std::string prefix_; + /** Global start time.*/ + double start_time_; + + /** Global time limit.*/ + double time_limit_; + + /** To record default log level.*/ + int default_log_level_; + /// Copy Constructor + TNLPSolver(const TNLPSolver & other); + +}; +} +#endif + + diff --git a/thirdparty/linux/include/coin/coin/BonTypes.hpp b/thirdparty/linux/include/coin/coin/BonTypes.hpp new file mode 100644 index 0000000..2924dfa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonTypes.hpp @@ -0,0 +1,102 @@ +#ifndef __BonTypes_H_ +#define __BonTypes_H_ +#include<vector> +#include "CoinSmartPtr.hpp" + +namespace Bonmin { +/** A small wrap around std::vector to give easy access to array for interfacing with fortran code.*/ +template<typename T> +class vector : public std::vector<T>{ +public: + /** Default constructor.*/ + vector(): std::vector<T>(){} + /** Constructor with initialization.*/ + vector(size_t n, const T& v): std::vector<T>(n,v){} + /** Copy constructor.*/ + vector(const vector<T>& other): std::vector<T>(other){} + /** Copy constructor.*/ + vector(const std::vector<T>& other): std::vector<T>(other){} + /** constructor with size.*/ + vector(size_t n): std::vector<T>(n){} + /** Assignment.*/ + vector<T>& operator=(const vector<T>& other){ + std::vector<T>::operator=(other); + return (*this);} + /** Assignment.*/ + vector<T>& operator=(const std::vector<T>& other){ + return std::vector<T>::operator=(other); + return (*this);} + +/** Access pointer to first element of storage.*/ +inline T* operator()(){ +#if defined(_MSC_VER) + if (std::vector<T>::size() == 0) + return NULL; +#endif +return &std::vector<T>::front();} +/** Access pointer to first element of storage.*/ +inline const T* operator()() const { +#if defined(_MSC_VER) + if (std::vector<T>::size() == 0) + return NULL; +#endif +return &std::vector<T>::front(); +} +}; + +//structure to store an object of class X in a Coin::ReferencedObject +template<class X> +struct SimpleReferenced : public Coin::ReferencedObject { + /** The object.*/ + X object; + + const X& operator()() const{ + return object;} + + X& operator()() { + return object;} + +}; +//structure to store a pointer to an object of class X in a +// Coin::ReferencedObject +template<class X> +struct SimpleReferencedPtr : public Coin::ReferencedObject { + /** The object.*/ + X * object; + + SimpleReferencedPtr(): + object(NULL){} + + ~SimpleReferencedPtr(){ + delete object;} + + const X& operator()() const{ + return *object;} + + X& operator()() { + return *object;} + + const X* ptr() const{ + return object;} + + X* ptr(){ + return object;} +}; + +template <class X> +SimpleReferenced<X> * make_referenced(X other){ + SimpleReferenced<X> * ret_val = new SimpleReferenced<X>; + ret_val->object = other; + return ret_val; +} +template <class X> +SimpleReferencedPtr<X> * make_referenced(X* other){ + SimpleReferencedPtr <X> * ret_val = new SimpleReferencedPtr<X>; + ret_val->object = other; + return ret_val; +} + + +} +#endif + diff --git a/thirdparty/linux/include/coin/coin/BonminConfig.h b/thirdparty/linux/include/coin/coin/BonminConfig.h new file mode 100644 index 0000000..1878f14 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/BonminConfig.h @@ -0,0 +1,19 @@ +/* src/Interfaces/config_bonmin.h. Generated by configure. */ +/* src/Interfaces/config_bonmin.h.in. */ + +#ifndef __CONFIG_BONMIN_H__ +#define __CONFIG_BONMIN_H__ + +/* Version number of project */ +#define BONMIN_VERSION "1.8.4" + +/* Major Version number of project */ +#define BONMIN_VERSION_MAJOR 1 + +/* Minor Version number of project */ +#define BONMIN_VERSION_MINOR 8 + +/* Release Version number of project */ +#define BONMIN_VERSION_RELEASE 4 + +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcBranchActual.hpp b/thirdparty/linux/include/coin/coin/CbcBranchActual.hpp new file mode 100644 index 0000000..709883c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchActual.hpp @@ -0,0 +1,24 @@ +/* $Id: CbcBranchActual.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchActual_H +#define CbcBranchActual_H + +#include "CbcBranchBase.hpp" +#include "CoinPackedMatrix.hpp" +#include "CbcClique.hpp" +#include "CbcSOS.hpp" +#include "CbcSimpleInteger.hpp" +#include "CbcNWay.hpp" +#include "CbcSimpleIntegerPseudoCost.hpp" +#include "CbcBranchDefaultDecision.hpp" +#include "CbcFollowOn.hpp" +#include "CbcFixVariable.hpp" +#include "CbcDummyBranchingObject.hpp" +#include "CbcGeneral.hpp" +#include "CbcGeneralDepth.hpp" +#include "CbcSubProblem.hpp" +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchAllDifferent.hpp b/thirdparty/linux/include/coin/coin/CbcBranchAllDifferent.hpp new file mode 100644 index 0000000..a380945 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchAllDifferent.hpp @@ -0,0 +1,62 @@ +// $Id: CbcBranchAllDifferent.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/13/2009-- carved out of CbcBranchCut + +#ifndef CbcBranchAllDifferent_H +#define CbcBranchAllDifferent_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" +#include "CbcBranchCut.hpp" + +/** Define a branch class that branches so that it is only satsified if all + members have different values + So cut is x <= y-1 or x >= y+1 +*/ + + +class CbcBranchAllDifferent : public CbcBranchCut { + +public: + + // Default Constructor + CbcBranchAllDifferent (); + + /** Useful constructor - passed set of integer variables which must all be different + */ + CbcBranchAllDifferent (CbcModel * model, int number, const int * which); + + // Copy constructor + CbcBranchAllDifferent ( const CbcBranchAllDifferent &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchAllDifferent & operator=( const CbcBranchAllDifferent& rhs); + + // Destructor + ~CbcBranchAllDifferent (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + +protected: + /// data + + /// Number of entries + int numberInSet_; + /// Which variables + int * which_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchBase.hpp b/thirdparty/linux/include/coin/coin/CbcBranchBase.hpp new file mode 100644 index 0000000..56c4261 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchBase.hpp @@ -0,0 +1,78 @@ +/* $Id: CbcBranchBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchBase_H +#define CbcBranchBase_H + +#include <string> +#include <vector> +#include "OsiBranchingObject.hpp" + +enum CbcRangeCompare { + CbcRangeSame, + CbcRangeDisjoint, + CbcRangeSubset, + CbcRangeSuperset, + CbcRangeOverlap +}; + +#include "CbcObject.hpp" +#include "CbcBranchingObject.hpp" +#include "CbcBranchDecision.hpp" +#include "CbcConsequence.hpp" +#include "CbcObjectUpdateData.hpp" + +//############################################################################## + +/** Compare two ranges. The two bounds arrays are both of size two and + describe closed intervals. Return the appropriate CbcRangeCompare value + (first argument being the sub/superset if that's the case). In case of + overlap (and if \c replaceIfOverlap is true) replace the content of thisBd + with the intersection of the ranges. +*/ +static inline CbcRangeCompare +CbcCompareRanges(double* thisBd, const double* otherBd, + const bool replaceIfOverlap) +{ + const double lbDiff = thisBd[0] - otherBd[0]; + if (lbDiff < 0) { // lb of this < lb of other + if (thisBd[1] >= otherBd[1]) { // ub of this >= ub of other + return CbcRangeSuperset; + } else if (thisBd[1] < otherBd[0]) { + return CbcRangeDisjoint; + } else { + // overlap + if (replaceIfOverlap) { + thisBd[0] = otherBd[0]; + } + return CbcRangeOverlap; + } + } else if (lbDiff > 0) { // lb of this > lb of other + if (thisBd[1] <= otherBd[1]) { // ub of this <= ub of other + return CbcRangeSubset; + } else if (thisBd[0] > otherBd[1]) { + return CbcRangeDisjoint; + } else { + // overlap + if (replaceIfOverlap) { + thisBd[1] = otherBd[1]; + } + return CbcRangeOverlap; + } + } else { // lb of this == lb of other + if (thisBd[1] == otherBd[1]) { + return CbcRangeSame; + } + return thisBd[1] < otherBd[1] ? CbcRangeSubset : CbcRangeSuperset; + } + + return CbcRangeSame; // fake return + +} + +//############################################################################# + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchCut.hpp b/thirdparty/linux/include/coin/coin/CbcBranchCut.hpp new file mode 100644 index 0000000..0fdc940 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchCut.hpp @@ -0,0 +1,183 @@ +/* $Id: CbcBranchCut.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchCut_H +#define CbcBranchCut_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a cut branching class. + At present empty - all stuff in descendants +*/ + +class CbcBranchCut : public CbcObject { + +public: + + // Default Constructor + CbcBranchCut (); + + /** In to maintain normal methods + */ + CbcBranchCut (CbcModel * model); + // Copy constructor + CbcBranchCut ( const CbcBranchCut &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchCut & operator=( const CbcBranchCut& rhs); + + // Destructor + ~CbcBranchCut (); + + /// Infeasibility + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. + + At present this will do nothing + */ + virtual void feasibleRegion(); + + /** \brief Return true if branch created by object should fix variables + */ + virtual bool boundBranch() const ; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in the good direction. + + The preferred branching object will force the variable to be +/-1 from + its current value, depending on the reduced cost and objective sense. If + movement in the direction which improves the objective is impossible due + to bounds on the variable, the branching object will move in the other + direction. If no movement is possible, the method returns NULL. + + Only the bounds on this variable are considered when determining if the new + point is feasible. + + At present this does nothing + */ + virtual CbcBranchingObject * preferredNewFeasible() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + As for preferredNewFeasible(), but the preferred branching object will + force movement in a direction that degrades the objective. + + At present this does nothing + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const ; + + using CbcObject::resetBounds ; + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(); + + +protected: + /// data + +}; +/** Cut branching object + + This object can specify a two-way branch in terms of two cuts +*/ + +class CbcCutBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcCutBranchingObject (); + + /** Create a cut branching object + + Cut down will applied on way=-1, up on way==1 + Assumed down will be first so way_ set to -1 + */ + CbcCutBranchingObject (CbcModel * model, OsiRowCut & down, OsiRowCut &up, bool canFix); + + /// Copy constructor + CbcCutBranchingObject ( const CbcCutBranchingObject &); + + /// Assignment operator + CbcCutBranchingObject & operator= (const CbcCutBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcCutBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for variables or adds a cut depending on the + current arm of the branch and advances the object state to the next arm. + Returns change in guessed objective on next branch + */ + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** \brief Return true if branch should fix variables + */ + virtual bool boundBranch() const; + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return CutBranchingObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Cut for the down arm (way_ = -1) + OsiRowCut down_; + /// Cut for the up arm (way_ = 1) + OsiRowCut up_; + /// True if one way can fix variables + bool canFix_; +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcBranchDecision.hpp b/thirdparty/linux/include/coin/coin/CbcBranchDecision.hpp new file mode 100644 index 0000000..538fe8c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchDecision.hpp @@ -0,0 +1,129 @@ +// $Id: CbcBranchDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcBranchDecision_H +#define CbcBranchDecision_H + +#include "CbcBranchBase.hpp" + +/** Abstract branching decision base class + + In the abstract, an CbcBranchDecision object is expected to be able to + compare two possible branching choices. + + The #betterBranch() method is the crucial routine. It is expected to be able + to compare two \link CbcBranchingObject CbcBranchingObjects \endlink. + + See CbcObject for an overview of the three classes (CbcObject, + CbcBranchingObject, and CbcBranchDecision) which make up cbc's branching + model. +*/ +class CbcModel; +class OsiChooseVariable; + +class CbcBranchDecision { +public: + /// Default Constructor + CbcBranchDecision (); + + // Copy constructor + CbcBranchDecision ( const CbcBranchDecision &); + + /// Destructor + virtual ~CbcBranchDecision(); + +/// Clone + virtual CbcBranchDecision * clone() const = 0; + + /// Initialize <i>e.g.</i> before starting to choose a branch at a node + virtual void initialize(CbcModel * model) = 0; + + /** \brief Compare two branching objects. Return nonzero if branching + using \p thisOne is better than branching using \p bestSoFar. + + If \p bestSoFar is NULL, the routine should return a nonzero value. + This routine is used only after strong branching. + Either this or bestBranch is used depending which user wants. + + */ + + virtual int + betterBranch (CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numberInfeasibilitiesUp, + double changeDown, int numberInfeasibilitiesDown) = 0 ; + + /** \brief Compare N branching objects. Return index of best + and sets way of branching in chosen object. + + Either this or betterBranch is used depending which user wants. + */ + + virtual int + bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied, + double * changeUp, int * numberInfeasibilitiesUp, + double * changeDown, int * numberInfeasibilitiesDown, + double objectiveValue) ; + + /** Says whether this method can handle both methods - + 1 better, 2 best, 3 both */ + virtual int whichMethod() { + return 2; + } + + /** Saves a clone of current branching object. Can be used to update + information on object causing branch - after branch */ + virtual void saveBranchingObject(OsiBranchingObject * ) {} + /** Pass in information on branch just done. + assumes object can get information from solver */ + virtual void updateInformation(OsiSolverInterface * , + const CbcNode * ) {} + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double ) {} + virtual double getBestCriterion() const { + return 0.0; + } + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /// Model + inline CbcModel * cbcModel() const { + return model_; + } + /* If chooseMethod_ id non-null then the rest is fairly pointless + as choosemethod_ will be doing all work + This comment makes more sense if you realise that there's a conversion in + process from the Cbc branching classes to Osi branching classes. The test + for use of the Osi branching classes is CbcModel::branchingMethod_ + non-null (i.e., it points to one of these CbcBranchDecision objects) and + that branch decision object has an OsiChooseVariable method set. In which + case, we'll use it, rather than the choose[*]Variable methods defined in + CbcNode. + */ + + OsiChooseVariable * chooseMethod() const { + return chooseMethod_; + } + /// Set (clone) chooseMethod + void setChooseMethod(const OsiChooseVariable & method); + +protected: + + // Clone of branching object + CbcBranchingObject * object_; + /// Pointer to model + CbcModel * model_; + /* If chooseMethod_ id non-null then the rest is fairly pointless + as choosemethod_ will be doing all work + */ + OsiChooseVariable * chooseMethod_; +private: + /// Assignment is illegal + CbcBranchDecision & operator=(const CbcBranchDecision& rhs); + +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchDefaultDecision.hpp b/thirdparty/linux/include/coin/coin/CbcBranchDefaultDecision.hpp new file mode 100644 index 0000000..d45035e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchDefaultDecision.hpp @@ -0,0 +1,100 @@ +// $Id: CbcBranchDefaultDecision.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcBranchDefaultDecision_H +#define CbcBranchDefaultDecision_H + +#include "CbcBranchBase.hpp" +/** Branching decision default class + + This class implements a simple default algorithm + (betterBranch()) for choosing a branching variable. +*/ + +class CbcBranchDefaultDecision : public CbcBranchDecision { +public: + // Default Constructor + CbcBranchDefaultDecision (); + + // Copy constructor + CbcBranchDefaultDecision ( const CbcBranchDefaultDecision &); + + virtual ~CbcBranchDefaultDecision(); + + /// Clone + virtual CbcBranchDecision * clone() const; + + /// Initialize, <i>e.g.</i> before the start of branch selection at a node + virtual void initialize(CbcModel * model); + + /** \brief Compare two branching objects. Return nonzero if \p thisOne is + better than \p bestSoFar. + + The routine compares branches using the values supplied in \p numInfUp and + \p numInfDn until a solution is found by search, after which it uses the + values supplied in \p changeUp and \p changeDn. The best branching object + seen so far and the associated parameter values are remembered in the + \c CbcBranchDefaultDecision object. The nonzero return value is +1 if the + up branch is preferred, -1 if the down branch is preferred. + + As the names imply, the assumption is that the values supplied for + \p numInfUp and \p numInfDn will be the number of infeasibilities reported + by the branching object, and \p changeUp and \p changeDn will be the + estimated change in objective. Other measures can be used if desired. + + Because an \c CbcBranchDefaultDecision object remembers the current best + branching candidate (#bestObject_) as well as the values used in the + comparison, the parameter \p bestSoFar is redundant, hence unused. + */ + virtual int betterBranch(CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numInfUp, + double changeDn, int numInfDn); + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double value); + virtual double getBestCriterion() const; + + /** \brief Compare N branching objects. Return index of best + and sets way of branching in chosen object. + + This routine is used only after strong branching. + */ + + virtual int + bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied, + double * changeUp, int * numberInfeasibilitiesUp, + double * changeDown, int * numberInfeasibilitiesDown, + double objectiveValue) ; +private: + + /// Illegal Assignment operator + CbcBranchDefaultDecision & operator=(const CbcBranchDefaultDecision& rhs); + + /// data + + /// "best" so far + double bestCriterion_; + + /// Change up for best + double bestChangeUp_; + + /// Number of infeasibilities for up + int bestNumberUp_; + + /// Change down for best + double bestChangeDown_; + + /// Pointer to best branching object + CbcBranchingObject * bestObject_; + + /// Number of infeasibilities for down + int bestNumberDown_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchDynamic.hpp b/thirdparty/linux/include/coin/coin/CbcBranchDynamic.hpp new file mode 100644 index 0000000..ffc5c34 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchDynamic.hpp @@ -0,0 +1,206 @@ +/* $Id: CbcBranchDynamic.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchDynamic_H +#define CbcBranchDynamic_H + +#include "CoinPackedMatrix.hpp" +#include "CbcSimpleIntegerDynamicPseudoCost.hpp" +#include "CbcBranchActual.hpp" + +/** Branching decision dynamic class + + This class implements a simple algorithm + (betterBranch()) for choosing a branching variable when dynamic pseudo costs. +*/ + +class CbcBranchDynamicDecision : public CbcBranchDecision { +public: + // Default Constructor + CbcBranchDynamicDecision (); + + // Copy constructor + CbcBranchDynamicDecision ( const CbcBranchDynamicDecision &); + + virtual ~CbcBranchDynamicDecision(); + + /// Clone + virtual CbcBranchDecision * clone() const; + + /// Initialize, <i>e.g.</i> before the start of branch selection at a node + virtual void initialize(CbcModel * model); + + /** \brief Compare two branching objects. Return nonzero if \p thisOne is + better than \p bestSoFar. + + The routine compares branches using the values supplied in \p numInfUp and + \p numInfDn until a solution is found by search, after which it uses the + values supplied in \p changeUp and \p changeDn. The best branching object + seen so far and the associated parameter values are remembered in the + \c CbcBranchDynamicDecision object. The nonzero return value is +1 if the + up branch is preferred, -1 if the down branch is preferred. + + As the names imply, the assumption is that the values supplied for + \p numInfUp and \p numInfDn will be the number of infeasibilities reported + by the branching object, and \p changeUp and \p changeDn will be the + estimated change in objective. Other measures can be used if desired. + + Because an \c CbcBranchDynamicDecision object remembers the current best + branching candidate (#bestObject_) as well as the values used in the + comparison, the parameter \p bestSoFar is redundant, hence unused. + */ + virtual int betterBranch(CbcBranchingObject * thisOne, + CbcBranchingObject * bestSoFar, + double changeUp, int numInfUp, + double changeDn, int numInfDn); + /** Sets or gets best criterion so far */ + virtual void setBestCriterion(double value); + virtual double getBestCriterion() const; + /** Says whether this method can handle both methods - + 1 better, 2 best, 3 both */ + virtual int whichMethod() { + return 3; + } + + /** Saves a clone of current branching object. Can be used to update + information on object causing branch - after branch */ + virtual void saveBranchingObject(OsiBranchingObject * object) ; + /** Pass in information on branch just done. + assumes object can get information from solver */ + virtual void updateInformation(OsiSolverInterface * solver, + const CbcNode * node); + + +private: + + /// Illegal Assignment operator + CbcBranchDynamicDecision & operator=(const CbcBranchDynamicDecision& rhs); + + /// data + + /// "best" so far + double bestCriterion_; + + /// Change up for best + double bestChangeUp_; + + /// Number of infeasibilities for up + int bestNumberUp_; + + /// Change down for best + double bestChangeDown_; + + /// Number of infeasibilities for down + int bestNumberDown_; + + /// Pointer to best branching object + CbcBranchingObject * bestObject_; +}; +/** Simple branching object for an integer variable with pseudo costs + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcDynamicPseudoCostBranchingObject : public CbcIntegerBranchingObject { + +public: + + /// Default constructor + CbcDynamicPseudoCostBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, + int way , double value, + CbcSimpleIntegerDynamicPseudoCost * object) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcDynamicPseudoCostBranchingObject ( const CbcDynamicPseudoCostBranchingObject &); + + /// Assignment operator + CbcDynamicPseudoCostBranchingObject & operator= (const CbcDynamicPseudoCostBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcDynamicPseudoCostBranchingObject (); + + /// Does part of constructor + void fillPart (int variable, + int way , double value, + CbcSimpleIntegerDynamicPseudoCost * object) ; + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + This version also changes guessed objective value + */ + virtual double branch(); + + /** Some branchingObjects may claim to be able to skip + strong branching. If so they have to fill in CbcStrongInfo. + The object mention in incoming CbcStrongInfo must match. + Returns nonzero if skip is wanted */ + virtual int fillStrongInfo( CbcStrongInfo & info); + + /// Change in guessed + inline double changeInGuessed() const { + return changeInGuessed_; + } + /// Set change in guessed + inline void setChangeInGuessed(double value) { + changeInGuessed_ = value; + } + /// Return object + inline CbcSimpleIntegerDynamicPseudoCost * object() const { + return object_; + } + /// Set object + inline void setObject(CbcSimpleIntegerDynamicPseudoCost * object) { + object_ = object; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return DynamicPseudoCostBranchObj; + } + + // LL: compareOriginalObject and compareBranchingObject are inherited from + // CbcIntegerBranchingObject thus need not be declared/defined here. After + // all, this kind of branching object is simply using pseudocosts to make + // decisions, but once the decisions are made they are the same kind as in + // the underlying class. + +protected: + /// Change in guessed objective value for next branch + double changeInGuessed_; + /// Pointer back to object + CbcSimpleIntegerDynamicPseudoCost * object_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchLotsize.hpp b/thirdparty/linux/include/coin/coin/CbcBranchLotsize.hpp new file mode 100644 index 0000000..4ba6510 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchLotsize.hpp @@ -0,0 +1,242 @@ +/* $Id: CbcBranchLotsize.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcBranchLotsize_H +#define CbcBranchLotsize_H + +#include "CbcBranchBase.hpp" +/** Lotsize class */ + + +class CbcLotsize : public CbcObject { + +public: + + // Default Constructor + CbcLotsize (); + + /* Useful constructor - passed model index. + Also passed valid values - if range then pairs + */ + CbcLotsize (CbcModel * model, int iColumn, + int numberPoints, const double * points, bool range = false); + + // Copy constructor + CbcLotsize ( const CbcLotsize &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcLotsize & operator=( const CbcLotsize& rhs); + + // Destructor + ~CbcLotsize (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. + */ + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in the good direction. + + The preferred branching object will force the variable to be +/-1 from + its current value, depending on the reduced cost and objective sense. If + movement in the direction which improves the objective is impossible due + to bounds on the variable, the branching object will move in the other + direction. If no movement is possible, the method returns NULL. + + Only the bounds on this variable are considered when determining if the new + point is feasible. + */ + virtual CbcBranchingObject * preferredNewFeasible() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + As for preferredNewFeasible(), but the preferred branching object will + force movement in a direction that degrades the objective. + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const ; + + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(const OsiSolverInterface * solver); + + /** Finds range of interest so value is feasible in range range_ or infeasible + between hi[range_] and lo[range_+1]. Returns true if feasible. + */ + bool findRange(double value) const; + + /** Returns floor and ceiling + */ + virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value, + double tolerance) const; + + /// Model column number + inline int modelSequence() const { + return columnNumber_; + } + /// Set model column number + inline void setModelSequence(int value) { + columnNumber_ = value; + } + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /// Original variable bounds + inline double originalLowerBound() const { + return bound_[0]; + } + inline double originalUpperBound() const { + return bound_[rangeType_*numberRanges_-1]; + } + /// Type - 1 points, 2 ranges + inline int rangeType() const { + return rangeType_; + } + /// Number of points + inline int numberRanges() const { + return numberRanges_; + } + /// Ranges + inline double * bound() const { + return bound_; + } + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + +private: + /// Just for debug (CBC_PRINT defined in CbcBranchLotsize.cpp) + void printLotsize(double value, bool condition, int type) const; + +private: + /// data + + /// Column number in model + int columnNumber_; + /// Type - 1 points, 2 ranges + int rangeType_; + /// Number of points + int numberRanges_; + // largest gap + double largestGap_; + /// Ranges + double * bound_; + /// Current range + mutable int range_; +}; + +/** Lotsize branching object + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcLotsizeBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcLotsizeBranchingObject (); + + /** Create a lotsize floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= valid range below(x*), the other valid range above(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcLotsizeBranchingObject (CbcModel *model, int variable, + int way , double value, const CbcLotsize * lotsize) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix in valid range + */ + + CbcLotsizeBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcLotsizeBranchingObject ( const CbcLotsizeBranchingObject &); + + /// Assignment operator + CbcLotsizeBranchingObject & operator= (const CbcLotsizeBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcLotsizeBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + */ + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return LotsizeBranchObj; + } + + // LL: compareOriginalObject can be inherited from the CbcBranchingObject + // since variable_ uniquely defines the lot sizing object. + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchToFixLots.hpp b/thirdparty/linux/include/coin/coin/CbcBranchToFixLots.hpp new file mode 100644 index 0000000..3b0a9ea --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchToFixLots.hpp @@ -0,0 +1,94 @@ +// $Id: CbcBranchToFixLots.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/13/2009-- carved out of CbcBranchCut + +#ifndef CbcBranchToFixLots_H +#define CbcBranchToFixLots_H + +#include "CbcBranchCut.hpp" +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a branch class that branches so that one way variables are fixed + while the other way cuts off that solution. + a) On reduced cost + b) When enough ==1 or <=1 rows have been satisfied (not fixed - satisfied) +*/ + + +class CbcBranchToFixLots : public CbcBranchCut { + +public: + + // Default Constructor + CbcBranchToFixLots (); + + /** Useful constructor - passed reduced cost tolerance and fraction we would like fixed. + Also depth level to do at. + Also passed number of 1 rows which when clean triggers fix + Always does if all 1 rows cleaned up and number>0 or if fraction columns reached + Also whether to create branch if can't reach fraction. + */ + CbcBranchToFixLots (CbcModel * model, double djTolerance, + double fractionFixed, int depth, + int numberClean = 0, + const char * mark = NULL, + bool alwaysCreate = false); + + // Copy constructor + CbcBranchToFixLots ( const CbcBranchToFixLots &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcBranchToFixLots & operator=( const CbcBranchToFixLots& rhs); + + // Destructor + ~CbcBranchToFixLots (); + + /** Does a lot of the work, + Returns 0 if no good, 1 if dj, 2 if clean, 3 if both + FIXME: should use enum or equivalent to make these numbers clearer. + */ + int shallWe() const; + + /// Infeasibility for an integer variable - large is 0.5, but also can be infinity when known infeasible. + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return true; + } + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + + +protected: + /// data + + /// Reduced cost tolerance i.e. dj has to be >= this before fixed + double djTolerance_; + /// We only need to make sure this fraction fixed + double fractionFixed_; + /// Never fix ones marked here + char * mark_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Do if depth multiple of this + int depth_; + /// number of ==1 rows which need to be clean + int numberClean_; + /// If true then always create branch + bool alwaysCreate_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcBranchingObject.hpp b/thirdparty/linux/include/coin/coin/CbcBranchingObject.hpp new file mode 100644 index 0000000..803108d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcBranchingObject.hpp @@ -0,0 +1,236 @@ +// $Id: CbcBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcBranchingObject_H +#define CbcBranchingObject_H + +#include <string> +#include <vector> +#include "CbcBranchBase.hpp" +#include "OsiBranchingObject.hpp" + + +// The types of objects that will be derived from this class. +enum CbcBranchObjType + { + SimpleIntegerBranchObj = 100, + SimpleIntegerDynamicPseudoCostBranchObj = 101, + CliqueBranchObj = 102, + LongCliqueBranchObj = 103, + SoSBranchObj = 104, + NWayBranchObj = 105, + FollowOnBranchObj = 106, + DummyBranchObj = 107, + GeneralDepthBranchObj = 108, + OneGeneralBranchingObj = 110, + CutBranchingObj = 200, + LotsizeBranchObj = 300, + DynamicPseudoCostBranchObj = 400 + }; + +/** \brief Abstract branching object base class + Now just difference with OsiBranchingObject + + In the abstract, an CbcBranchingObject contains instructions for how to + branch. We want an abstract class so that we can describe how to branch on + simple objects (<i>e.g.</i>, integers) and more exotic objects + (<i>e.g.</i>, cliques or hyperplanes). + + The #branch() method is the crucial routine: it is expected to be able to + step through a set of branch arms, executing the actions required to create + each subproblem in turn. The base class is primarily virtual to allow for + a wide range of problem modifications. + + See CbcObject for an overview of the three classes (CbcObject, + CbcBranchingObject, and CbcBranchDecision) which make up cbc's branching + model. +*/ + +class CbcBranchingObject : public OsiBranchingObject { + +public: + + /// Default Constructor + CbcBranchingObject (); + + /// Constructor + CbcBranchingObject (CbcModel * model, int variable, int way , double value); + + /// Copy constructor + CbcBranchingObject ( const CbcBranchingObject &); + + /// Assignment operator + CbcBranchingObject & operator=( const CbcBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const = 0; + + /// Destructor + virtual ~CbcBranchingObject (); + + /** Some branchingObjects may claim to be able to skip + strong branching. If so they have to fill in CbcStrongInfo. + The object mention in incoming CbcStrongInfo must match. + Returns nonzero if skip is wanted */ + virtual int fillStrongInfo( CbcStrongInfo & ) { + return 0; + } + /// Reset number of branches left to original + inline void resetNumberBranchesLeft() { + branchIndex_ = 0; + } + /// Set number of branches to do + inline void setNumberBranches(int value) { + branchIndex_ = 0; + numberBranches_ = value; + } + + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. Mainly for diagnostics, whether it is true branch or + strong branching is also passed. + Returns change in guessed objective on next branch + */ + virtual double branch() = 0; + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. Mainly for diagnostics, whether it is true branch or + strong branching is also passed. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * ) { + return branch(); + } + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * , + double * , double * , + int ) const {} + + /** Change (tighten) bounds in object to reflect bounds in solver. + Return true if now fixed */ + virtual bool tighten(OsiSolverInterface * ) {return false;} + + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch() { + assert(branchIndex_ > 0); + branchIndex_--; + way_ = -way_; + } + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print() const {} + + /** \brief Index identifying the associated CbcObject within its class. + + The name is misleading, and typically the index will <i>not</i> refer + directly to a variable. + Rather, it identifies an CbcObject within the class of similar + CbcObjects + + <i>E.g.</i>, for an CbcSimpleInteger, variable() is the index of the + integer variable in the set of integer variables (<i>not</i> the index of + the variable in the set of all variables). + */ + inline int variable() const { + return variable_; + } + + /** Get the state of the branching object + + Returns a code indicating the active arm of the branching object. + The precise meaning is defined in the derived class. + + \sa #way_ + */ + inline int way() const { + return way_; + } + + /** Set the state of the branching object. + + See #way() + */ + inline void way(int way) { + way_ = way; + } + + /// update model + inline void setModel(CbcModel * model) { + model_ = model; + } + /// Return model + inline CbcModel * model() const { + return model_; + } + + /// Return pointer back to object which created + inline CbcObject * object() const { + return originalCbcObject_; + } + /// Set pointer back to object which created + inline void setOriginalObject(CbcObject * object) { + originalCbcObject_ = object; + } + + // Methods used in heuristics + + /** Return the type (an integer identifier) of \c this. + See definition of CbcBranchObjType above for possibilities + */ + + virtual CbcBranchObjType type() const = 0; + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const { + const CbcBranchingObject* br = dynamic_cast<const CbcBranchingObject*>(brObj); + return variable() - br->variable(); + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be of the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false) = 0; + +protected: + + /// The model that owns this branching object + CbcModel * model_; + /// Pointer back to object which created + CbcObject * originalCbcObject_; + + /// Branching variable (0 is first integer) + int variable_; + // was - Way to branch - -1 down (first), 1 up, -2 down (second), 2 up (second) + /** The state of the branching object. + + Specifies the active arm of the branching object. Coded as -1 to take + the `down' arm, +1 for the `up' arm. `Down' and `up' are defined based on + the natural meaning (floor and ceiling, respectively) for a simple integer. + The precise meaning is defined in the derived class. + */ + int way_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcClique.hpp b/thirdparty/linux/include/coin/coin/CbcClique.hpp new file mode 100644 index 0000000..e21e027 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcClique.hpp @@ -0,0 +1,303 @@ +// $Id: CbcClique.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcClique_H +#define CbcClique_H + +/** \brief Branching object for cliques + + A clique is defined to be a set of binary variables where fixing any one + variable to its `strong' value fixes all other variables. An example is the + most common SOS1 construction: a set of binary variables x_j s.t. SUM{j} + x_j = 1. Setting any one variable to 1 forces all other variables to 0. + (See comments for CbcSOS below.) + + Other configurations are possible, however: Consider x1-x2+x3 <= 0. + Setting x1 (x3) to 1 forces x2 to 1 and x3 (x1) to 0. Setting x2 to 0 + forces x1 and x3 to 0. + + The proper point of view to take when interpreting CbcClique is + `generalisation of SOS1 on binary variables.' To get into the proper frame + of mind, here's an example. + + Consider the following sequence, where x_j = (1-y_j): + \verbatim + x1 + x2 + x3 <= 1 all strong at 1 + x1 - y2 + x3 <= 0 y2 strong at 0; x1, x3 strong at 1 + -y1 - y2 + x3 <= -1 y1, y2 strong at 0, x3 strong at 1 + -y1 - y2 - y3 <= -2 all strong at 0 + \endverbatim + The first line is a standard SOS1 on binary variables. + + Variables with +1 coefficients are `SOS-style' and variables with -1 + coefficients are `non-SOS-style'. So #numberNonSOSMembers_ simply tells you + how many variables have -1 coefficients. The implicit rhs for a clique is + 1-numberNonSOSMembers_. +*/ +class CbcClique : public CbcObject { + +public: + + /// Default Constructor + CbcClique (); + + /** Useful constructor (which are integer indices) slack can denote a slack + in set. If type == NULL then as if 1 + */ + CbcClique (CbcModel * model, int cliqueType, int numberMembers, + const int * which, const char * type, + int identifier, int slack = -1); + + /// Copy constructor + CbcClique ( const CbcClique &); + + /// Clone + virtual CbcObject * clone() const; + + /// Assignment operator + CbcClique & operator=( const CbcClique& rhs); + + /// Destructor + virtual ~CbcClique (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + /** \brief Number of variables with -1 coefficient + + Number of non-SOS members, i.e., fixing to zero is strong. + See comments at head of class, and comments for #type_. + */ + inline int numberNonSOSMembers() const { + return numberNonSOSMembers_; + } + + /// Members (indices in range 0 ... numberIntegers_-1) + inline const int * members() const { + return members_; + } + + /*! \brief Type of each member, i.e., which way is strong. + + This also specifies whether a variable has a +1 or -1 coefficient. + - 0 => -1 coefficient, 0 is strong value + - 1 => +1 coefficient, 1 is strong value + If unspecified, all coefficients are assumed to be positive. + + Indexed as 0 .. numberMembers_-1 + */ + inline char type(int index) const { + if (type_) return type_[index]; + else return 1; + } + + /// Clique type: 0 is <=, 1 is == + inline int cliqueType() const { + return cliqueType_; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Number of members + int numberMembers_; + + /// Number of Non SOS members i.e. fixing to zero is strong + int numberNonSOSMembers_; + + /// Members (indices in range 0 ... numberIntegers_-1) + int * members_; + + /** \brief Strong value for each member. + + This also specifies whether a variable has a +1 or -1 coefficient. + - 0 => -1 coefficient, 0 is strong value + - 1 => +1 coefficient, 1 is strong value + If unspecified, all coefficients are assumed to be positive. + + Indexed as 0 .. numberMembers_-1 + */ + char * type_; + + /** \brief Clique type + + 0 defines a <= relation, 1 an equality. The assumed value of the rhs is + numberNonSOSMembers_+1. (See comments for the class.) + */ + int cliqueType_; + + /** \brief Slack variable for the clique + + Identifies the slack variable for the clique (typically added to convert + a <= relation to an equality). Value is sequence number within clique + menbers. + */ + int slack_; +}; + +/** Branching object for unordered cliques + + Intended for cliques which are long enough to make it worthwhile + but <= 64 members. There will also be ones for long cliques. + + Variable_ is the clique id number (redundant, as the object also holds a + pointer to the clique. + */ +class CbcCliqueBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcCliqueBranchingObject (); + + // Useful constructor + CbcCliqueBranchingObject (CbcModel * model, const CbcClique * clique, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcCliqueBranchingObject ( const CbcCliqueBranchingObject &); + + // Assignment operator + CbcCliqueBranchingObject & operator=( const CbcCliqueBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcCliqueBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return CliqueBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be of the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + const CbcClique * clique_; + /// downMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int downMask_[2]; + /// upMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int upMask_[2]; +}; + +/** Unordered Clique Branching Object class. + These are for cliques which are > 64 members + Variable is number of clique. + */ +class CbcLongCliqueBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcLongCliqueBranchingObject (); + + // Useful constructor + CbcLongCliqueBranchingObject (CbcModel * model, const CbcClique * clique, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcLongCliqueBranchingObject ( const CbcLongCliqueBranchingObject &); + + // Assignment operator + CbcLongCliqueBranchingObject & operator=( const CbcLongCliqueBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcLongCliqueBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return LongCliqueBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + const CbcClique * clique_; + /// downMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int * downMask_; + /// upMask - bit set to fix to weak bounds, not set to leave unfixed + unsigned int * upMask_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCompare.hpp b/thirdparty/linux/include/coin/coin/CbcCompare.hpp new file mode 100644 index 0000000..fadc866 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompare.hpp @@ -0,0 +1,39 @@ +/* $Id: CbcCompare.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompare_H +#define CbcCompare_H + +class CbcCompareBase; + +class CbcCompare { +public: + CbcCompareBase * test_; + // Default Constructor + CbcCompare () { + test_ = NULL; + } + + virtual ~CbcCompare() {} + + bool operator() (CbcNode * x, CbcNode * y) { + return test_->test(x, y); + } + bool compareNodes (CbcNode * x, CbcNode * y) { + return test_->test(x, y); + } + /// This is alternate test function + inline bool alternateTest (CbcNode * x, CbcNode * y) { + return test_->alternateTest(x, y); + } + + /// return comparison object + inline CbcCompareBase * comparisonObject() const { + return test_; + } +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareActual.hpp b/thirdparty/linux/include/coin/coin/CbcCompareActual.hpp new file mode 100644 index 0000000..60417c8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareActual.hpp @@ -0,0 +1,14 @@ +/* $Id: CbcCompareActual.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompareActual_H +#define CbcCompareActual_H +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +#include "CbcCompareDepth.hpp" +#include "CbcCompareDefault.hpp" +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareBase.hpp b/thirdparty/linux/include/coin/coin/CbcCompareBase.hpp new file mode 100644 index 0000000..1242f6d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareBase.hpp @@ -0,0 +1,142 @@ +/* $Id: CbcCompareBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCompareBase_H +#define CbcCompareBase_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + + This is rather inflexible so if the comparison functions wants + it can signal to use alternative criterion on a complete pass + throgh tree. + +*/ +#include "CbcNode.hpp" +#include "CbcConfig.h" + +class CbcModel; +class CbcTree; +class CbcCompareBase { +public: + // Default Constructor + CbcCompareBase () { + test_ = NULL; + threaded_ = false; + } + + /*! \brief Reconsider behaviour after discovering a new solution. + + This allows any method to change its behaviour. It is called + after each solution. + + The method should return true if changes are made which will + alter the evaluation criteria applied to a node. (So that in + cases where the search tree is sorted, it can be properly + rebuilt.) + */ + virtual bool newSolution(CbcModel * ) { return (false) ; } + + /*! \brief Reconsider behaviour after discovering a new solution. + + This allows any method to change its behaviour. It is called + after each solution. + + The method should return true if changes are made which will + alter the evaluation criteria applied to a node. (So that in + cases where the search tree is sorted, it can be properly + rebuilt.) + */ + virtual bool newSolution(CbcModel * , + double , + int ) { return (false) ; } + + // This allows any method to change behavior as it is called + // after every 1000 nodes. + // Return true if want tree re-sorted + virtual bool every1000Nodes(CbcModel * , int ) { + return false; + } + + /** Returns true if wants code to do scan with alternate criterion + NOTE - this is temporarily disabled + */ + virtual bool fullScan() const { + return false; + } + + virtual ~CbcCompareBase() {} + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + // Copy constructor + CbcCompareBase ( const CbcCompareBase & rhs) { + test_ = rhs.test_; + threaded_ = rhs.threaded_; + } + + // Assignment operator + CbcCompareBase & operator=( const CbcCompareBase& rhs) { + if (this != &rhs) { + test_ = rhs.test_; + threaded_ = rhs.threaded_; + } + return *this; + } + + /// Clone + virtual CbcCompareBase * clone() const { + abort(); + return NULL; + } + + /// This is test function + virtual bool test (CbcNode * , CbcNode * ) { + return true; + } + + /// This is alternate test function + virtual bool alternateTest (CbcNode * x, CbcNode * y) { + return test(x, y); + } + + bool operator() (CbcNode * x, CbcNode * y) { + return test(x, y); + } + /// Further test if everything else equal + inline bool equalityTest (CbcNode * x, CbcNode * y) const { + assert (x); + assert (y); + if (!threaded_) { + CbcNodeInfo * infoX = x->nodeInfo(); + assert (infoX); + int nodeNumberX = infoX->nodeNumber(); + CbcNodeInfo * infoY = y->nodeInfo(); + assert (infoY); + int nodeNumberY = infoY->nodeNumber(); + assert (nodeNumberX != nodeNumberY); + return (nodeNumberX > nodeNumberY); + } else { + assert (x->nodeNumber() != y->nodeNumber()); + return (x->nodeNumber() > y->nodeNumber()); + } + } + /// Say threaded + inline void sayThreaded() { + threaded_ = true; + } +protected: + CbcCompareBase * test_; + // If not threaded we can use better way to break ties + bool threaded_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareDefault.hpp b/thirdparty/linux/include/coin/coin/CbcCompareDefault.hpp new file mode 100644 index 0000000..2d1ce8e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareDefault.hpp @@ -0,0 +1,120 @@ +// $Id: CbcCompareDefault.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareDefault_H +#define CbcCompareDefault_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" + +class CbcModel; + +/* This is an example of a more complex rule with data + It is default after first solution + If weight is 0.0 then it is computed to hit first solution + less 5% +*/ +class CbcCompareDefault : public CbcCompareBase { +public: + /// Default Constructor + CbcCompareDefault () ; + /// Constructor with weight + CbcCompareDefault (double weight); + + /// Copy constructor + CbcCompareDefault ( const CbcCompareDefault &rhs); + + /// Assignment operator + CbcCompareDefault & operator=( const CbcCompareDefault& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + ~CbcCompareDefault() ; + /* This returns true if weighted value of node y is less than + weighted value of node x */ + virtual bool test (CbcNode * x, CbcNode * y) ; + + using CbcCompareBase::newSolution ; + /// This allows method to change behavior as it is called + /// after each solution + virtual bool newSolution(CbcModel * model, + double objectiveAtContinuous, + int numberInfeasibilitiesAtContinuous) ; + /// This allows method to change behavior + /// Return true if want tree re-sorted + virtual bool every1000Nodes(CbcModel * model, int numberNodes); + + /* if weight == -1.0 then fewest infeasibilities (before solution) + if -2.0 then do breadth first just for first 1000 nodes + if -3.0 then depth first before solution + */ + inline double getWeight() const { + return weight_; + } + inline void setWeight(double weight) { + weight_ = weight; + } + /// Cutoff + inline double getCutoff() const { + return cutoff_; + } + inline void setCutoff(double cutoff) { + cutoff_ = cutoff; + } + /// Best possible solution + inline double getBestPossible() const { + return bestPossible_; + } + inline void setBestPossible(double bestPossible) { + bestPossible_ = bestPossible; + } + /// Depth above which want to explore first + inline void setBreadthDepth(int value) { + breadthDepth_ = value; + } + /// Start dive + void startDive(CbcModel * model); + /// Clean up diving (i.e. switch off or prepare) + void cleanDive(); +protected: + /// Weight for each infeasibility + double weight_; + /// Weight for each infeasibility - computed from solution + double saveWeight_; + /// Cutoff + double cutoff_; + /// Best possible solution + double bestPossible_; + /// Number of solutions + int numberSolutions_; + /// Tree size (at last check) + int treeSize_; + /// Depth above which want to explore first + int breadthDepth_; + /// Chosen node from estimated (-1 is off) + int startNodeNumber_; + /// Node number when dive started + int afterNodeNumber_; + /// Indicates doing setup for diving + bool setupForDiving_ ; +}; + +#endif //CbcCompareDefault_H + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareDepth.hpp b/thirdparty/linux/include/coin/coin/CbcCompareDepth.hpp new file mode 100644 index 0000000..5fe5073 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareDepth.hpp @@ -0,0 +1,47 @@ +// $Id: CbcCompareDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/24/09 carved out of CbcCompareActual + +#ifndef CbcCompareDepth_H +#define CbcCompareDepth_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +class CbcModel; +// This is default before first solution +class CbcCompareDepth : public CbcCompareBase { +public: + // Default Constructor + CbcCompareDepth () ; + + ~CbcCompareDepth(); + // Copy constructor + CbcCompareDepth ( const CbcCompareDepth &rhs); + + // Assignment operator + CbcCompareDepth & operator=( const CbcCompareDepth& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + // This returns true if the depth of node y is greater than depth of node x + virtual bool test (CbcNode * x, CbcNode * y); +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareEstimate.hpp b/thirdparty/linux/include/coin/coin/CbcCompareEstimate.hpp new file mode 100644 index 0000000..8f6c056 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareEstimate.hpp @@ -0,0 +1,48 @@ +// $Id: CbcCompareEstimate.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareEstimate_H +#define CbcCompareEstimate_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" +class CbcModel; + +/* This is when rounding is being done +*/ +class CbcCompareEstimate : public CbcCompareBase { +public: + // Default Constructor + CbcCompareEstimate () ; + ~CbcCompareEstimate() ; + // Copy constructor + CbcCompareEstimate ( const CbcCompareEstimate &rhs); + + // Assignment operator + CbcCompareEstimate & operator=( const CbcCompareEstimate& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + virtual bool test (CbcNode * x, CbcNode * y) ; +}; + + +#endif //CbcCompareEstimate_H + diff --git a/thirdparty/linux/include/coin/coin/CbcCompareObjective.hpp b/thirdparty/linux/include/coin/coin/CbcCompareObjective.hpp new file mode 100644 index 0000000..a3f6613 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCompareObjective.hpp @@ -0,0 +1,49 @@ +// $Id: CbcCompareObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCompareActual + +#ifndef CbcCompareObjective_H +#define CbcCompareObjective_H + + +//############################################################################# +/* These are alternative strategies for node traversal. + They can take data etc for fine tuning + + At present the node list is stored as a heap and the "test" + comparison function returns true if node y is better than node x. + +*/ +#include "CbcNode.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCompare.hpp" + +class CbcModel; + +class CbcCompareObjective : public CbcCompareBase { +public: + // Default Constructor + CbcCompareObjective (); + + virtual ~CbcCompareObjective(); + // Copy constructor + CbcCompareObjective ( const CbcCompareObjective &rhs); + + // Assignment operator + CbcCompareObjective & operator=( const CbcCompareObjective& rhs); + + /// Clone + virtual CbcCompareBase * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp); + + /* This returns true if objective value of node y is less than + objective value of node x */ + virtual bool test (CbcNode * x, CbcNode * y); +}; + +#endif //CbcCompareObjective_H + diff --git a/thirdparty/linux/include/coin/coin/CbcConfig.h b/thirdparty/linux/include/coin/coin/CbcConfig.h new file mode 100644 index 0000000..75e4b08 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcConfig.h @@ -0,0 +1,14 @@ +/* src/config_cbc.h. Generated by configure. */ +/* src/config_cbc.h.in. */ + +/* Version number of project */ +#define CBC_VERSION "2.9.7" + +/* Major Version number of project */ +#define CBC_VERSION_MAJOR 2 + +/* Minor Version number of project */ +#define CBC_VERSION_MINOR 9 + +/* Release Version number of project */ +#define CBC_VERSION_RELEASE 7 diff --git a/thirdparty/linux/include/coin/coin/CbcConsequence.hpp b/thirdparty/linux/include/coin/coin/CbcConsequence.hpp new file mode 100644 index 0000000..f64a8bc --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcConsequence.hpp @@ -0,0 +1,49 @@ +// $Id: CbcConsequence.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcConsequence_H +#define CbcConsequence_H + +class OsiSolverInterface; + +/** Abstract base class for consequent bounds. + When a variable is branched on it normally interacts with other variables by + means of equations. There are cases where we want to step outside LP and do something + more directly e.g. fix bounds. This class is for that. + + At present it need not be virtual as only instance is CbcFixVariable, but ... + + */ + +class CbcConsequence { + +public: + + // Default Constructor + CbcConsequence (); + + // Copy constructor + CbcConsequence ( const CbcConsequence & rhs); + + // Assignment operator + CbcConsequence & operator=( const CbcConsequence & rhs); + + /// Clone + virtual CbcConsequence * clone() const = 0; + + /// Destructor + virtual ~CbcConsequence (); + + /** Apply to an LP solver. Action depends on state + */ + virtual void applyToSolver(OsiSolverInterface * solver, int state) const = 0; + +protected: +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCountRowCut.hpp b/thirdparty/linux/include/coin/coin/CbcCountRowCut.hpp new file mode 100644 index 0000000..73eac08 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCountRowCut.hpp @@ -0,0 +1,168 @@ +/* $Id: CbcCountRowCut.hpp 2094 2014-11-18 11:15:36Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCountRowCut_H +#define CbcCountRowCut_H + + +class OsiCuts; +class OsiRowCut; +class CbcNodeInfo; + +//############################################################################# +/** \brief OsiRowCut augmented with bookkeeping + + CbcCountRowCut is an OsiRowCut object augmented with bookkeeping + information: a reference count and information that specifies the + the generator that created the cut and the node to which it's associated. + + The general principles for handling the reference count are as follows: + <ul> + <li> Once it's determined how the node will branch, increment the + reference count under the assumption that all children will use + all cuts currently tight at the node and will survive to be placed + in the search tree. + <li> As this assumption is proven incorrect (a cut becomes loose, or a + child is fathomed), decrement the reference count accordingly. + </ul> + When all possible uses of a cut have been demonstrated to be unnecessary, + the reference count (#numberPointingToThis_) will fall to zero. The + CbcCountRowCut object (and its included OsiRowCut object) are then deleted. +*/ + +class CbcCountRowCut : public OsiRowCut { + +public: + + /** @name Constructors & destructors */ + //@{ + + /// Default Constructor + CbcCountRowCut (); + + /// `Copy' constructor using an OsiRowCut + CbcCountRowCut ( const OsiRowCut &); + + /// `Copy' constructor using an OsiRowCut and an CbcNodeInfo + CbcCountRowCut(const OsiRowCut &, CbcNodeInfo *, int whichOne, + int whichGenerator = -1, int numberPointingToThis = 0); + + /** Destructor + + \note The destructor will reach out (via #owner_) and NULL the + reference to the cut in the owner's + \link CbcNodeInfo::cuts_ cuts_ \endlink list. + */ + virtual ~CbcCountRowCut (); + //@} + + /// Increment the number of references + void increment(int change = 1); + + /// Decrement the number of references and return the number left. + int decrement(int change = 1); + + /** \brief Set the information associating this cut with a node + + An CbcNodeInfo object and an index in the cut set of the node. + For locally valid cuts, the node will be the search tree node where the + cut was generated. For globally valid cuts, it's the node where the cut + was activated. + */ + void setInfo(CbcNodeInfo *, int whichOne); + + /// Number of other CbcNodeInfo objects pointing to this row cut + inline int numberPointingToThis() { + return numberPointingToThis_; + } + + /// Which generator for cuts - as user order + inline int whichCutGenerator() const { + return whichCutGenerator_; + } + + /// Returns true if can drop cut if slack basic + bool canDropCut(const OsiSolverInterface * solver, int row) const; + +#ifdef CHECK_CUT_COUNTS + // Just for printing sanity checks + int tempNumber_; +#endif + +private: + + /// Standard copy is illegal (reference counts would be incorrect) + CbcCountRowCut(const CbcCountRowCut &); + + /// Standard assignment is illegal (reference counts would be incorrect) + CbcCountRowCut & operator=(const CbcCountRowCut& rhs); + + /// Backward pointer to owning CbcNodeInfo + CbcNodeInfo * owner_; + + /// Index of cut in owner's cut set + /// (\link CbcNodeInfo::cuts_ cuts_ \endlink). + int ownerCut_; + + /// Number of other CbcNodeInfo objects pointing to this cut + int numberPointingToThis_; + + /** Which generator created this cut + (add 10000 if globally valid) + if -1 then from global cut pool + -2 cut branch + -3 unknown + */ + int whichCutGenerator_; + +}; +/** + Really for Conflict cuts to - + a) stop duplicates + b) allow half baked cuts + The whichRow_ field in OsiRowCut2 is used for a type + 0 - normal + 1 - processed cut (conflict) + 2 - unprocessed cut i.e. dual ray computation +*/ +// for hashing +typedef struct { + int index, next; +} CoinHashLink; +class CbcRowCuts { +public: + + CbcRowCuts(int initialMaxSize=0, int hashMultiplier=4 ); + ~CbcRowCuts(); + CbcRowCuts(const CbcRowCuts& rhs); + CbcRowCuts& operator=(const CbcRowCuts& rhs); + inline OsiRowCut2 * cut(int sequence) const + { return rowCut_[sequence];} + inline int numberCuts() const + { return numberCuts_;} + inline int sizeRowCuts() const + { return numberCuts_;} + inline OsiRowCut * rowCutPtr(int sequence) + { return rowCut_[sequence];} + void eraseRowCut(int sequence); + // Return 0 if added, 1 if not, -1 if not added because of space + int addCutIfNotDuplicate(const OsiRowCut & cut,int whichType=0); + // Return 0 if added, 1 if not, -1 if not added because of space + int addCutIfNotDuplicateWhenGreedy(const OsiRowCut & cut,int whichType=0); + // Add in cuts as normal cuts (and delete) + void addCuts(OsiCuts & cs); + // Truncate + void truncate(int numberAfter); +private: + OsiRowCut2 ** rowCut_; + /// Hash table + CoinHashLink *hash_; + int size_; + int hashMultiplier_; + int numberCuts_; + int lastHash_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCutGenerator.hpp b/thirdparty/linux/include/coin/coin/CbcCutGenerator.hpp new file mode 100644 index 0000000..f07142e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCutGenerator.hpp @@ -0,0 +1,482 @@ +/* $Id: CbcCutGenerator.hpp 2081 2014-09-25 11:31:17Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcCutGenerator_H +#define CbcCutGenerator_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" +#include "CbcCutModifier.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; + +//############################################################################# + +/** Interface between Cbc and Cut Generation Library. + + \c CbcCutGenerator is intended to provide an intelligent interface between + Cbc and the cutting plane algorithms in the CGL. A \c CbcCutGenerator is + bound to a \c CglCutGenerator and to an \c CbcModel. It contains parameters + which control when and how the \c generateCuts method of the + \c CglCutGenerator will be called. + + The builtin decision criteria available to use when deciding whether to + generate cuts are limited: every <i>X</i> nodes, when a solution is found, + and when a subproblem is found to be infeasible. The idea is that the class + will grow more intelligent with time. + + \todo Add a pointer to function member which will allow a client to install + their own decision algorithm to decide whether or not to call the CGL + \p generateCuts method. Create a default decision method that looks + at the builtin criteria. + + \todo It strikes me as not good that generateCuts contains code specific to + individual CGL algorithms. Another set of pointer to function members, + so that the client can specify the cut generation method as well as + pre- and post-generation methods? Taken a bit further, should this + class contain a bunch of pointer to function members, one for each + of the places where the cut generator might be referenced? + Initialization, root node, search tree node, discovery of solution, + and termination all come to mind. Initialization and termination would + also be useful for instrumenting cbc. +*/ + +class CbcCutGenerator { + +public: + + /** \name Generate Cuts */ + //@{ + /** Generate cuts for the client model. + + Evaluate the state of the client model and decide whether to generate cuts. + The generated cuts are inserted into and returned in the collection of cuts + \p cs. + + If \p fullScan is !=0, the generator is obliged to call the CGL + \c generateCuts routine. Otherwise, it is free to make a local decision. + Negative fullScan says things like at integer solution + The current implementation uses \c whenCutGenerator_ to decide. + + The routine returns true if reoptimisation is needed (because the state of + the solver interface has been modified). + + If node then can find out depth + */ + bool generateCuts( OsiCuts &cs, int fullScan, OsiSolverInterface * solver, + CbcNode * node); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CbcCutGenerator (); + + /// Normal constructor + CbcCutGenerator(CbcModel * model, CglCutGenerator * generator, + int howOften = 1, const char * name = NULL, + bool normal = true, bool atSolution = false, + bool infeasible = false, int howOftenInsub = -100, + int whatDepth = -1, int whatDepthInSub = -1, int switchOffIfLessThan = 0); + + /// Copy constructor + CbcCutGenerator (const CbcCutGenerator &); + + /// Assignment operator + CbcCutGenerator & operator=(const CbcCutGenerator& rhs); + + /// Destructor + ~CbcCutGenerator (); + //@} + + /**@name Gets and sets */ + //@{ + /** Set the client model. + + In addition to setting the client model, refreshModel also calls + the \c refreshSolver method of the CglCutGenerator object. + */ + void refreshModel(CbcModel * model); + + /// return name of generator + inline const char * cutGeneratorName() const { + return generatorName_; + } + + /// Create C++ lines to show how to tune + void generateTuning( FILE * fp); + /** Set the cut generation interval + + Set the number of nodes evaluated between calls to the Cgl object's + \p generateCuts routine. + + If \p value is positive, cuts will always be generated at the specified + interval. + If \p value is negative, cuts will initially be generated at the specified + interval, but Cbc may adjust the value depending on the success of cuts + produced by this generator. + + A value of -100 disables the generator, while a value of -99 means + just at root. + */ + void setHowOften(int value) ; + + /// Get the cut generation interval. + inline int howOften() const { + return whenCutGenerator_; + } + /// Get the cut generation interval.in sub tree + inline int howOftenInSub() const { + return whenCutGeneratorInSub_; + } + /// Get level of cut inaccuracy (0 means exact e.g. cliques) + inline int inaccuracy() const { + return inaccuracy_; + } + /// Set level of cut inaccuracy (0 means exact e.g. cliques) + inline void setInaccuracy(int level) { + inaccuracy_ = level; + } + + /** Set the cut generation depth + + Set the depth criterion for calls to the Cgl object's + \p generateCuts routine. Only active if > 0. + + If whenCutGenerator is positive and this is positive then this overrides. + If whenCutGenerator is -1 then this is used as criterion if any cuts + were generated at root node. + If whenCutGenerator is anything else this is ignored. + */ + void setWhatDepth(int value) ; + /// Set the cut generation depth in sub tree + void setWhatDepthInSub(int value) ; + /// Get the cut generation depth criterion. + inline int whatDepth() const { + return depthCutGenerator_; + } + /// Get the cut generation depth criterion.in sub tree + inline int whatDepthInSub() const { + return depthCutGeneratorInSub_; + } + /// Set maximum number of times to enter + inline void setMaximumTries(int value) + { maximumTries_ = value;} + /// Get maximum number of times to enter + inline int maximumTries() const + { return maximumTries_;} + + /// Get switches + inline int switches() const { + return switches_; + } + /// Set switches (for copying from virgin state) + inline void setSwitches(int value) { + switches_ = value; + } + /// Get whether the cut generator should be called in the normal place + inline bool normal() const { + return (switches_&1) != 0; + } + /// Set whether the cut generator should be called in the normal place + inline void setNormal(bool value) { + switches_ &= ~1; + switches_ |= value ? 1 : 0; + } + /// Get whether the cut generator should be called when a solution is found + inline bool atSolution() const { + return (switches_&2) != 0; + } + /// Set whether the cut generator should be called when a solution is found + inline void setAtSolution(bool value) { + switches_ &= ~2; + switches_ |= value ? 2 : 0; + } + /** Get whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline bool whenInfeasible() const { + return (switches_&4) != 0; + } + /** Set whether the cut generator should be called when the subproblem is + found to be infeasible. + */ + inline void setWhenInfeasible(bool value) { + switches_ &= ~4; + switches_ |= value ? 4 : 0; + } + /// Get whether the cut generator is being timed + inline bool timing() const { + return (switches_&64) != 0; + } + /// Set whether the cut generator is being timed + inline void setTiming(bool value) { + switches_ &= ~64; + switches_ |= value ? 64 : 0; + timeInCutGenerator_ = 0.0; + } + /// Return time taken in cut generator + inline double timeInCutGenerator() const { + return timeInCutGenerator_; + } + inline void incrementTimeInCutGenerator(double value) { + timeInCutGenerator_ += value; + } + /// Get the \c CglCutGenerator corresponding to this \c CbcCutGenerator. + inline CglCutGenerator * generator() const { + return generator_; + } + /// Number times cut generator entered + inline int numberTimesEntered() const { + return numberTimes_; + } + inline void setNumberTimesEntered(int value) { + numberTimes_ = value; + } + inline void incrementNumberTimesEntered(int value = 1) { + numberTimes_ += value; + } + /// Total number of cuts added + inline int numberCutsInTotal() const { + return numberCuts_; + } + inline void setNumberCutsInTotal(int value) { + numberCuts_ = value; + } + inline void incrementNumberCutsInTotal(int value = 1) { + numberCuts_ += value; + } + /// Total number of elements added + inline int numberElementsInTotal() const { + return numberElements_; + } + inline void setNumberElementsInTotal(int value) { + numberElements_ = value; + } + inline void incrementNumberElementsInTotal(int value = 1) { + numberElements_ += value; + } + /// Total number of column cuts + inline int numberColumnCuts() const { + return numberColumnCuts_; + } + inline void setNumberColumnCuts(int value) { + numberColumnCuts_ = value; + } + inline void incrementNumberColumnCuts(int value = 1) { + numberColumnCuts_ += value; + } + /// Total number of cuts active after (at end of n cut passes at each node) + inline int numberCutsActive() const { + return numberCutsActive_; + } + inline void setNumberCutsActive(int value) { + numberCutsActive_ = value; + } + inline void incrementNumberCutsActive(int value = 1) { + numberCutsActive_ += value; + } + inline void setSwitchOffIfLessThan(int value) { + switchOffIfLessThan_ = value; + } + inline int switchOffIfLessThan() const { + return switchOffIfLessThan_; + } + /// Say if optimal basis needed + inline bool needsOptimalBasis() const { + return (switches_&128) != 0; + } + /// Set if optimal basis needed + inline void setNeedsOptimalBasis(bool yesNo) { + switches_ &= ~128; + switches_ |= yesNo ? 128 : 0; + } + /// Whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline bool mustCallAgain() const { + return (switches_&8) != 0; + } + /// Set whether generator MUST be called again if any cuts (i.e. ignore break from loop) + inline void setMustCallAgain(bool yesNo) { + switches_ &= ~8; + switches_ |= yesNo ? 8 : 0; + } + /// Whether generator switched off for moment + inline bool switchedOff() const { + return (switches_&16) != 0; + } + /// Set whether generator switched off for moment + inline void setSwitchedOff(bool yesNo) { + switches_ &= ~16; + switches_ |= yesNo ? 16 : 0; + } + /// Whether last round of cuts did little + inline bool ineffectualCuts() const { + return (switches_&512) != 0; + } + /// Set whether last round of cuts did little + inline void setIneffectualCuts(bool yesNo) { + switches_ &= ~512; + switches_ |= yesNo ? 512 : 0; + } + /// Whether to use if any cuts generated + inline bool whetherToUse() const { + return (switches_&1024) != 0; + } + /// Set whether to use if any cuts generated + inline void setWhetherToUse(bool yesNo) { + switches_ &= ~1024; + switches_ |= yesNo ? 1024 : 0; + } + /// Whether in must call again mode (or after others) + inline bool whetherInMustCallAgainMode() const { + return (switches_&2048) != 0; + } + /// Set whether in must call again mode (or after others) + inline void setWhetherInMustCallAgainMode(bool yesNo) { + switches_ &= ~2048; + switches_ |= yesNo ? 2048 : 0; + } + /// Whether to call at end + inline bool whetherCallAtEnd() const { + return (switches_&4096) != 0; + } + /// Set whether to call at end + inline void setWhetherCallAtEnd(bool yesNo) { + switches_ &= ~4096; + switches_ |= yesNo ? 4096 : 0; + } + /// Whether needs refresh on copy + inline bool needsRefresh() const { + return (switches_&8192) != 0; + } + /// Set whether needs refresh on copy + inline void setNeedsRefresh(bool yesNo) { + switches_ &= ~8192; + switches_ |= yesNo ? 8192 : 0; + } + /// Number of cuts generated at root + inline int numberCutsAtRoot() const { + return numberCutsAtRoot_; + } + inline void setNumberCutsAtRoot(int value) { + numberCutsAtRoot_ = value; + } + /// Number of cuts active at root + inline int numberActiveCutsAtRoot() const { + return numberActiveCutsAtRoot_; + } + inline void setNumberActiveCutsAtRoot(int value) { + numberActiveCutsAtRoot_ = value; + } + /// Number of short cuts at root + inline int numberShortCutsAtRoot() const { + return numberShortCutsAtRoot_; + } + inline void setNumberShortCutsAtRoot(int value) { + numberShortCutsAtRoot_ = value; + } + /// Set model + inline void setModel(CbcModel * model) { + model_ = model; + } + /// Whether global cuts at root + inline bool globalCutsAtRoot() const { + return (switches_&32) != 0; + } + /// Set whether global cuts at root + inline void setGlobalCutsAtRoot(bool yesNo) { + switches_ &= ~32; + switches_ |= yesNo ? 32 : 0; + } + /// Whether global cuts + inline bool globalCuts() const { + return (switches_&256) != 0; + } + /// Set whether global cuts + inline void setGlobalCuts(bool yesNo) { + switches_ &= ~256; + switches_ |= yesNo ? 256 : 0; + } + /// Add in statistics from other + void addStatistics(const CbcCutGenerator * other); + /// Scale back statistics by factor + void scaleBackStatistics(int factor); + //@} + +private: + /**@name Private gets and sets */ + //@{ + //@} + /// Saved cuts + OsiCuts savedCuts_; + /// Time in cut generator + double timeInCutGenerator_; + /// The client model + CbcModel *model_; + + // The CglCutGenerator object + CglCutGenerator * generator_; + + /// Name of generator + char * generatorName_; + + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine. + */ + int whenCutGenerator_; + /** Number of nodes between calls to the CglCutGenerator::generateCuts + routine in sub tree. + */ + int whenCutGeneratorInSub_; + /** If first pass at root produces fewer than this cuts then switch off + */ + int switchOffIfLessThan_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + */ + int depthCutGenerator_; + + /** Depth at which to call the CglCutGenerator::generateCuts + routine (If >0 then overrides when and is called if depth%depthCutGenerator==0). + In sub tree. + */ + int depthCutGeneratorInSub_; + + /// Level of cut inaccuracy (0 means exact e.g. cliques) + int inaccuracy_; + /// Number times cut generator entered + int numberTimes_; + /// Total number of cuts added + int numberCuts_; + /// Total number of elements added + int numberElements_; + /// Total number of column cuts added + int numberColumnCuts_; + /// Total number of cuts active after (at end of n cut passes at each node) + int numberCutsActive_; + /// Number of cuts generated at root + int numberCutsAtRoot_; + /// Number of cuts active at root + int numberActiveCutsAtRoot_; + /// Number of short cuts at root + int numberShortCutsAtRoot_; + /// Switches - see gets and sets + int switches_; + /// Maximum number of times to enter + int maximumTries_; +}; + +// How often to do if mostly switched off (A) +# define SCANCUTS 1000 +// How often to do if mostly switched off (probing B) +# define SCANCUTS_PROBING 1000 + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcCutModifier.hpp b/thirdparty/linux/include/coin/coin/CbcCutModifier.hpp new file mode 100644 index 0000000..726d615 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCutModifier.hpp @@ -0,0 +1,57 @@ +// $Id: CbcCutModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCutGenerator + +#ifndef CbcCutModifier_H +#define CbcCutModifier_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; +/** Abstract cut modifier base class + + In exotic circumstances - cuts may need to be modified + a) strengthened - changed + b) weakened - changed + c) deleted - set to NULL + d) unchanged +*/ + +class CbcCutModifier { +public: + /// Default Constructor + CbcCutModifier (); + + // Copy constructor + CbcCutModifier ( const CbcCutModifier &); + + /// Destructor + virtual ~CbcCutModifier(); + + /// Assignment + CbcCutModifier & operator=(const CbcCutModifier& rhs); +/// Clone + virtual CbcCutModifier * clone() const = 0; + + /** Returns + 0 unchanged + 1 strengthened + 2 weakened + 3 deleted + */ + virtual int modify(const OsiSolverInterface * solver, OsiRowCut & cut) = 0; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} +protected: + +}; + +#endif //CbcCutModifier_H + diff --git a/thirdparty/linux/include/coin/coin/CbcCutSubsetModifier.hpp b/thirdparty/linux/include/coin/coin/CbcCutSubsetModifier.hpp new file mode 100644 index 0000000..593fa62 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcCutSubsetModifier.hpp @@ -0,0 +1,66 @@ +// $Id: CbcCutSubsetModifier.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +//Edwin 11/25/09 carved out of CbcCutGenerator + +#ifndef CbcCutSubsetModifier_H +#define CbcCutSubsetModifier_H + +#include "OsiSolverInterface.hpp" +#include "OsiCuts.hpp" +#include "CglCutGenerator.hpp" +#include "CbcCutModifier.hpp" + +class CbcModel; +class OsiRowCut; +class OsiRowCutDebugger; +/** Simple cut modifier base class + + In exotic circumstances - cuts may need to be modified + a) strengthened - changed + b) weakened - changed + c) deleted - set to NULL + d) unchanged + + initially get rid of cuts with variables >= k + could weaken +*/ + +class CbcCutSubsetModifier : public CbcCutModifier { +public: + /// Default Constructor + CbcCutSubsetModifier (); + + /// Useful Constructor + CbcCutSubsetModifier (int firstOdd); + + // Copy constructor + CbcCutSubsetModifier ( const CbcCutSubsetModifier &); + + /// Destructor + virtual ~CbcCutSubsetModifier(); + + /// Assignment + CbcCutSubsetModifier & operator=(const CbcCutSubsetModifier& rhs); +/// Clone + virtual CbcCutModifier * clone() const ; + + /** Returns + 0 unchanged + 1 strengthened + 2 weakened + 3 deleted + */ + virtual int modify(const OsiSolverInterface * solver, OsiRowCut & cut) ; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} +protected: + /// data + /// First odd variable + int firstOdd_; +}; + +#endif //CbcCutSubsetModifier_H + diff --git a/thirdparty/linux/include/coin/coin/CbcDummyBranchingObject.hpp b/thirdparty/linux/include/coin/coin/CbcDummyBranchingObject.hpp new file mode 100644 index 0000000..b7e15c5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcDummyBranchingObject.hpp @@ -0,0 +1,83 @@ +// $Id: CbcDummyBranchingObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcDummyBranchingObject_H +#define CbcDummyBranchingObject_H + +#include "CbcBranchBase.hpp" +/** Dummy branching object + + This object specifies a one-way dummy branch. + This is so one can carry on branching even when it looks feasible +*/ + +class CbcDummyBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcDummyBranchingObject (CbcModel * model = NULL); + + /// Copy constructor + CbcDummyBranchingObject ( const CbcDummyBranchingObject &); + + /// Assignment operator + CbcDummyBranchingObject & operator= (const CbcDummyBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcDummyBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Dummy branch + */ + virtual double branch(); + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return DummyBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcEventHandler.hpp b/thirdparty/linux/include/coin/coin/CbcEventHandler.hpp new file mode 100644 index 0000000..cedc4b8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcEventHandler.hpp @@ -0,0 +1,245 @@ +/* + Copyright (C) 2006, International Business Machines Corporation and others. + All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). + + $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ +*/ + +#ifndef CbcEventHandler_H +#define CbcEventHandler_H + +/*! \file CbcEventHandler.hpp + \brief Event handling for cbc + + This file contains the declaration of CbcEventHandler, used for event + handling in cbc. + + The central method is CbcEventHandler::event(). The default semantics of + this call are `ask for the action to take in reponse to this event'. The + call is made at the point in the code where the event occurs (<i>e.g.</i>, + when a solution is found, or when a node is added to or removed from the + search tree). The return value specifies the action to perform in response + to the event (<i>e.g.</i>, continue, or stop). + + This is a lazy class. Initially, it knows nothing about specific events, + and returns dfltAction_ for any event. This makes for a trivial constructor + and fast startup. The only place where the list of known events or actions + is hardwired is in the enum definitions for CbcEvent and CbcAction, + respectively. + + At the first call to setAction, a map is created to hold (Event,Action) + pairs, and this map will be consulted ever after. Events not in the map + will still return the default value. + + For serious extensions, derive a subclass and replace event() with a + function that suits you better. The function has access to the CbcModel + via a pointer held in the CbcEventHandler object, and can do as much + thinking as it likes before returning an answer. You can also print as + much information as you want. The model is held as a const, however, so + you can't alter reality. + + The design of the class deliberately matches ClpEventHandler, so that other + solvers can participate in cbc without breaking the patterns set by + clp-specific code. + +*/ + +#include <cstddef> +#include <map> + +/* May well already be declared, but can't hurt. */ + +class CbcModel ; + +/* + cvs/svn: $Id: CbcEventHandler.hpp 1987 2013-11-29 17:27:29Z forrest $ +*/ + +/*! \class CbcEventHandler + \brief Base class for Cbc event handling. + + Up front: We're not talking about unanticipated events here. We're talking + about anticipated events, in the sense that the code is going to make a call + to event() and is prepared to obey the return value that it receives. + + The general pattern for usage is as follows: + <ol> + <li> Create a CbcEventHandler object. This will be initialised with a set + of default actions for every recognised event. + + <li> Attach the event handler to the CbcModel object. + + <li> When execution reaches the point where an event occurs, call the + event handler as CbcEventHandler::event(the event). The return value + will specify what the code should do in response to the event. + </ol> + + The return value associated with an event can be changed at any time. +*/ + +class CbcEventHandler { + +public: + + /*! \brief Events known to cbc */ + + enum CbcEvent { /*! Processing of the current node is complete. */ + node = 200, + /*! A tree status interval has arrived. */ + treeStatus, + /*! A solution has been found. */ + solution, + /*! A heuristic solution has been found. */ + heuristicSolution, + /*! A solution will be found unless user takes action (first check). */ + beforeSolution1, + /*! A solution will be found unless user takes action (thorough check). */ + beforeSolution2, + /*! After failed heuristic. */ + afterHeuristic, + /*! On entry to small branch and bound. */ + smallBranchAndBound, + /*! After a pass of heuristic. */ + heuristicPass, + /*! When converting constraints to cuts. */ + convertToCuts, + /*! End of search. */ + endSearch + } ; + + /*! \brief Action codes returned by the event handler. + + Specific values are chosen to match ClpEventHandler return codes. + */ + + enum CbcAction { /*! Continue --- no action required. */ + noAction = -1, + /*! Stop --- abort the current run at the next opportunity. */ + stop = 0, + /*! Restart --- restart branch-and-cut search; do not undo root node + processing. + */ + restart, + /*! RestartRoot --- undo root node and start branch-and-cut afresh. */ + restartRoot, + /*! Add special cuts. */ + addCuts, + /*! Pretend solution never happened. */ + killSolution, + /*! Take action on modified data. */ + takeAction + + } ; + + /*! \brief Data type for event/action pairs */ + + typedef std::map<CbcEvent, CbcAction> eaMapPair ; + + + /*! \name Event Processing */ + //@{ + + /*! \brief Return the action to be taken for an event. + + Return the action that should be taken in response to the event passed as + the parameter. The default implementation simply reads a return code + from a map. + */ + virtual CbcAction event(CbcEvent whichEvent) ; + + /*! \brief Return the action to be taken for an event - and modify data. + + Return the action that should be taken in response to the event passed as + the parameter. The default implementation simply reads a return code + from a map. + */ + virtual CbcAction event(CbcEvent whichEvent, void * data) ; + + //@} + + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor. */ + + CbcEventHandler(CbcModel *model = 0 /* was NULL but 4.6 complains */) ; + + /*! \brief Copy constructor. */ + + CbcEventHandler(const CbcEventHandler &orig) ; + + /*! \brief Assignment. */ + + CbcEventHandler& operator=(const CbcEventHandler &rhs) ; + + /*! \brief Clone (virtual) constructor. */ + + virtual CbcEventHandler* clone() const ; + + /*! \brief Destructor. */ + + virtual ~CbcEventHandler() ; + + //@} + + /*! \name Set/Get methods */ + //@{ + + /*! \brief Set model. */ + + inline void setModel(CbcModel *model) { + model_ = model ; + } + + /*! \brief Get model. */ + + inline const CbcModel* getModel() const { + return model_ ; + } + + /*! \brief Set the default action */ + + inline void setDfltAction(CbcAction action) { + dfltAction_ = action ; + } + + /*! \brief Set the action code associated with an event */ + + inline void setAction(CbcEvent event, CbcAction action) { + if (eaMap_ == 0) { + eaMap_ = new eaMapPair ; + } + (*eaMap_)[event] = action ; + } + + //@} + + +protected: + + /*! \name Data members + + Protected (as opposed to private) to allow access by derived classes. + */ + //@{ + + /*! \brief Pointer to associated CbcModel */ + + CbcModel *model_ ; + + /*! \brief Default action */ + + CbcAction dfltAction_ ; + + /*! \brief Pointer to a map that holds non-default event/action pairs */ + + eaMapPair *eaMap_ ; + + //@} +} ; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcFathom.hpp b/thirdparty/linux/include/coin/coin/CbcFathom.hpp new file mode 100644 index 0000000..8f934c9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFathom.hpp @@ -0,0 +1,137 @@ +/* $Id: CbcFathom.hpp 1889 2013-04-07 13:46:46Z stefan $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFathom_H +#define CbcFathom_H +#include "CbcConfig.h" + +/* + This file contains two classes, CbcFathom and CbcOsiSolver. It's unclear why + they're in the same file. CbcOsiSolver is a base class for CbcLinked. + + --lh, 071031 -- +*/ + + +class CbcModel; + +//############################################################################# +/** Fathom base class. + + The idea is that after some branching the problem will be effectively smaller than + the original problem and maybe there will be a more specialized technique which can completely + fathom this branch quickly. + + One method is to presolve the problem to give a much smaller new problem and then do branch + and cut on that. Another might be dynamic programming. + + */ + +class CbcFathom { +public: + // Default Constructor + CbcFathom (); + + // Constructor with model - assumed before cuts + CbcFathom (CbcModel & model); + + virtual ~CbcFathom(); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Clone + virtual CbcFathom * clone() const = 0; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model) = 0; + + /** returns 0 if no fathoming attempted, 1 fully fathomed, + 2 incomplete search, 3 incomplete search but treat as complete. + If solution then newSolution will not be NULL and + will be freed by CbcModel. It is expected that the solution is better + than best so far but CbcModel will double check. + + If returns 3 then of course there is no guarantee of global optimum + */ + virtual int fathom(double *& newSolution) = 0; + + // Is this method possible + inline bool possible() const { + return possible_; + } + +protected: + + /// Model + CbcModel * model_; + /// Possible - if this method of fathoming can be used + bool possible_; +private: + + /// Illegal Assignment operator + CbcFathom & operator=(const CbcFathom& rhs); + +}; + +#include "OsiClpSolverInterface.hpp" + +//############################################################################# + +/** + +This is for codes where solver needs to know about CbcModel + Seems to provide only one value-added feature, a CbcModel object. + +*/ + +class CbcOsiSolver : public OsiClpSolverInterface { + +public: + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + CbcOsiSolver (); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + CbcOsiSolver (const CbcOsiSolver &); + + /// Assignment operator + CbcOsiSolver & operator=(const CbcOsiSolver& rhs); + + /// Destructor + virtual ~CbcOsiSolver (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Set Cbc Model + inline void setCbcModel(CbcModel * model) { + cbcModel_ = model; + } + /// Return Cbc Model + inline CbcModel * cbcModel() const { + return cbcModel_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name Private member data */ + //@{ + /// Pointer back to CbcModel + CbcModel * cbcModel_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcFathomDynamicProgramming.hpp b/thirdparty/linux/include/coin/coin/CbcFathomDynamicProgramming.hpp new file mode 100644 index 0000000..7f38987 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFathomDynamicProgramming.hpp @@ -0,0 +1,169 @@ +/* $Id: CbcFathomDynamicProgramming.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFathomDynamicProgramming_H +#define CbcFathomDynamicProgramming_H + +#include "CbcFathom.hpp" + +//############################################################################# +/** FathomDynamicProgramming class. + + The idea is that after some branching the problem will be effectively smaller than + the original problem and maybe there will be a more specialized technique which can completely + fathom this branch quickly. + + This is a dynamic programming implementation which is very fast for some + specialized problems. It expects small integral rhs, an all integer problem + and positive integral coefficients. At present it can not do general set covering + problems just set partitioning. It can find multiple optima for various rhs + combinations. + + The main limiting factor is size of state space. Each 1 rhs doubles the size of the problem. + 2 or 3 rhs quadruples, 4,5,6,7 by 8 etc. + */ + +class CbcFathomDynamicProgramming : public CbcFathom { +public: + // Default Constructor + CbcFathomDynamicProgramming (); + + // Constructor with model - assumed before cuts + CbcFathomDynamicProgramming (CbcModel & model); + // Copy constructor + CbcFathomDynamicProgramming(const CbcFathomDynamicProgramming & rhs); + + virtual ~CbcFathomDynamicProgramming(); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Clone + virtual CbcFathom * clone() const; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /** returns 0 if no fathoming attempted, 1 fully fathomed , + 2 incomplete search, 3 incomplete search but treat as complete. + If solution then newSolution will not be NULL and + will be freed by CbcModel. It is expected that the solution is better + than best so far but CbcModel will double check. + + If returns 3 then of course there is no guarantee of global optimum + */ + virtual int fathom(double *& newSolution); + + /// Maximum size allowed + inline int maximumSize() const { + return maximumSizeAllowed_; + } + inline void setMaximumSize(int value) { + maximumSizeAllowed_ = value; + } + /// Returns type of algorithm and sets up arrays + int checkPossible(int allowableSize = 0); + // set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /** Tries a column + returns true if was used in making any changes. + */ + bool tryColumn(int numberElements, const int * rows, + const double * coefficients, double cost, + int upper = COIN_INT_MAX); + /// Returns cost array + inline const double * cost() const { + return cost_; + } + /// Returns back array + inline const int * back() const { + return back_; + } + /// Gets bit pattern for target result + inline int target() const { + return target_; + } + /// Sets bit pattern for target result + inline void setTarget(int value) { + target_ = value; + } +private: + /// Does deleteions + void gutsOfDelete(); + + /** Adds one attempt of one column of type 0, + returns true if was used in making any changes + */ + bool addOneColumn0(int numberElements, const int * rows, + double cost); + /** Adds one attempt of one column of type 1, + returns true if was used in making any changes. + At present the user has to call it once for each possible value + */ + bool addOneColumn1(int numberElements, const int * rows, + const int * coefficients, double cost); + /** Adds one attempt of one column of type 1, + returns true if was used in making any changes. + At present the user has to call it once for each possible value. + This version is when there are enough 1 rhs to do faster + */ + bool addOneColumn1A(int numberElements, const int * rows, + const int * coefficients, double cost); + /// Gets bit pattern from original column + int bitPattern(int numberElements, const int * rows, + const int * coefficients); + /// Gets bit pattern from original column + int bitPattern(int numberElements, const int * rows, + const double * coefficients); + /// Fills in original column (dense) from bit pattern - returning number nonzero + int decodeBitPattern(int bitPattern, int * values, int numberRows); + +protected: + + /// Size of states (power of 2 unless just one constraint) + int size_; + /** Type - 0 coefficients and rhs all 1, + 1 - coefficients > 1 or rhs > 1 + */ + int type_; + /// Space for states + double * cost_; + /// Which state produced this cheapest one + int * back_; + /// Some rows may be satisified so we need a lookup + int * lookup_; + /// Space for sorted indices + int * indices_; + /// Number of active rows + int numberActive_; + /// Maximum size allowed + int maximumSizeAllowed_; + /// Start bit for each active row + int * startBit_; + /// Number bits for each active row + int * numberBits_; + /// Effective rhs + int * rhs_; + /// Space for sorted coefficients + int * coefficients_; + /// Target pattern + int target_; + /// Number of Non 1 rhs + int numberNonOne_; + /// Current bit pattern + int bitPattern_; + /// Current algorithm + int algorithm_; +private: + + /// Illegal Assignment operator + CbcFathomDynamicProgramming & operator=(const CbcFathomDynamicProgramming& rhs); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcFeasibilityBase.hpp b/thirdparty/linux/include/coin/coin/CbcFeasibilityBase.hpp new file mode 100644 index 0000000..fe8181f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFeasibilityBase.hpp @@ -0,0 +1,56 @@ +/* $Id: CbcFeasibilityBase.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcFeasibilityBase_H +#define CbcFeasibilityBase_H + + +//############################################################################# +/* There are cases where the user wants to control how CBC sees the problems feasibility. + The user may want to examine the problem and say : + a) The default looks OK + b) Pretend this problem is Integer feasible + c) Pretend this problem is infeasible even though it looks feasible + + This simple class allows user to do that. + +*/ + +class CbcModel; +class CbcFeasibilityBase { +public: + // Default Constructor + CbcFeasibilityBase () {} + + /** + On input mode: + 0 - called after a solve but before any cuts + -1 - called after strong branching + Returns : + 0 - no opinion + -1 pretend infeasible + 1 pretend integer solution + */ + virtual int feasible(CbcModel * , int ) { + return 0; + } + + virtual ~CbcFeasibilityBase() {} + + // Copy constructor + CbcFeasibilityBase ( const CbcFeasibilityBase & ) {} + + // Assignment operator + CbcFeasibilityBase & operator=( const CbcFeasibilityBase& ) { + return *this; + } + + /// Clone + virtual CbcFeasibilityBase * clone() const { + return new CbcFeasibilityBase(*this); + } +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcFixVariable.hpp b/thirdparty/linux/include/coin/coin/CbcFixVariable.hpp new file mode 100644 index 0000000..aa33509 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFixVariable.hpp @@ -0,0 +1,67 @@ +// $Id: CbcFixVariable.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcFixVariable_H +#define CbcFixVariable_H + +#include "CbcBranchBase.hpp" +/** Class for consequent bounds. + When a variable is branched on it normally interacts with other variables by + means of equations. There are cases where we want to step outside LP and do something + more directly e.g. fix bounds. This class is for that. + + A state of -9999 means at LB, +9999 means at UB, + others mean if fixed to that value. + + */ + +class CbcFixVariable : public CbcConsequence { + +public: + + // Default Constructor + CbcFixVariable (); + + // One useful Constructor + CbcFixVariable (int numberStates, const int * states, const int * numberNewLower, const int ** newLowerValue, + const int ** lowerColumn, + const int * numberNewUpper, const int ** newUpperValue, + const int ** upperColumn); + + // Copy constructor + CbcFixVariable ( const CbcFixVariable & rhs); + + // Assignment operator + CbcFixVariable & operator=( const CbcFixVariable & rhs); + + /// Clone + virtual CbcConsequence * clone() const; + + /// Destructor + virtual ~CbcFixVariable (); + + /** Apply to an LP solver. Action depends on state + */ + virtual void applyToSolver(OsiSolverInterface * solver, int state) const; + +protected: + /// Number of states + int numberStates_; + /// Values of integers for various states + int * states_; + /// Start of information for each state (setting new lower) + int * startLower_; + /// Start of information for each state (setting new upper) + int * startUpper_; + /// For each variable new bounds + double * newBound_; + /// Variable + int * variable_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcFollowOn.hpp b/thirdparty/linux/include/coin/coin/CbcFollowOn.hpp new file mode 100644 index 0000000..ada5988 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFollowOn.hpp @@ -0,0 +1,207 @@ +// $Id: CbcFollowOn.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcFollowOn_H +#define CbcFollowOn_H + +#include "CbcBranchBase.hpp" +#include "OsiRowCut.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinPackedMatrix.hpp" + +/** Define a follow on class. + The idea of this is that in air-crew scheduling problems crew may fly in on flight A + and out on flight B or on some other flight. A useful branch is one which on one side + fixes all which go out on flight B to 0, while the other branch fixes all those that do NOT + go out on flight B to 0. + + This branching rule should be in addition to normal rules and have a high priority. +*/ + +class CbcFollowOn : public CbcObject { + +public: + + // Default Constructor + CbcFollowOn (); + + /** Useful constructor + */ + CbcFollowOn (CbcModel * model); + + // Copy constructor + CbcFollowOn ( const CbcFollowOn &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcFollowOn & operator=( const CbcFollowOn& rhs); + + // Destructor + ~CbcFollowOn (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// As some computation is needed in more than one place - returns row + virtual int gutsOfFollowOn(int & otherRow, int & preferredWay) const; + +protected: + /// data + /// Matrix + CoinPackedMatrix matrix_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Possible rhs (if 0 then not possible) + int * rhs_; +}; + +/** General Branching Object class. + Each way fixes some variables to lower bound + */ +class CbcFixingBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcFixingBranchingObject (); + + // Useful constructor + CbcFixingBranchingObject (CbcModel * model, + int way, + int numberOnDownSide, const int * down, + int numberOnUpSide, const int * up); + + // Copy constructor + CbcFixingBranchingObject ( const CbcFixingBranchingObject &); + + // Assignment operator + CbcFixingBranchingObject & operator=( const CbcFixingBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcFixingBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return FollowOnBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// data + /// Number on down list + int numberDown_; + /// Number on up list + int numberUp_; + /// downList - variables to fix to lb on down branch + int * downList_; + /// upList - variables to fix to lb on up branch + int * upList_; +}; + +/** Define an idiotic idea class. + The idea of this is that we take some integer variables away from integer and + sum them with some randomness to get signed sum close to 0.5. We then can + branch to exclude that gap. + + This branching rule should be in addition to normal rules and have a high priority. +*/ + +class CbcIdiotBranch : public CbcObject { + +public: + + // Default Constructor + CbcIdiotBranch (); + + /** Useful constructor + */ + CbcIdiotBranch (CbcModel * model); + + // Copy constructor + CbcIdiotBranch ( const CbcIdiotBranch &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcIdiotBranch & operator=( const CbcIdiotBranch& rhs); + + // Destructor + ~CbcIdiotBranch (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Initialize for branching + virtual void initializeForBranching(CbcModel * ); +protected: + /// Build "cut" + OsiRowCut buildCut(const OsiBranchingInformation * info,int type,int & preferredWay) const; + /// data + /// Thread specific random number generator + mutable CoinThreadRandom randomNumberGenerator_; + /// Saved version of thread specific random number generator + mutable CoinThreadRandom savedRandomNumberGenerator_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcFullNodeInfo.hpp b/thirdparty/linux/include/coin/coin/CbcFullNodeInfo.hpp new file mode 100644 index 0000000..c4704bd --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcFullNodeInfo.hpp @@ -0,0 +1,161 @@ +// $Id: CbcFullNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcFullNodeInfo_H +#define CbcFullNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +//############################################################################# +/** Information required to recreate the subproblem at this node + + When a subproblem is initially created, it is represented by a CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information needed while the subproblem remains live. + The CbcNode is deleted when the last branch arm has been evaluated. + + The CbcNodeInfo contains information required to maintain the branch-and-cut + search tree structure (links and reference counts) and to recreate the + subproblem for this node (basis, variable bounds, cutting planes). A + CbcNodeInfo object remains in existence until all nodes have been pruned from + the subtree rooted at this node. + + The principle used to maintain the reference count is that the reference + count is always the sum of all potential and actual children of the node. + Specifically, + <ul> + <li> Once it's determined how the node will branch, the reference count + is set to the number of potential children (<i>i.e.</i>, the number + of arms of the branch). + <li> As each child is created by CbcNode::branch() (converting a potential + child to the active subproblem), the reference count is decremented. + <li> If the child survives and will become a node in the search tree + (converting the active subproblem into an actual child), increment the + reference count. + </ul> + Notice that the active subproblem lives in a sort of limbo, neither a + potential or an actual node in the branch-and-cut tree. + + CbcNodeInfo objects come in two flavours. A CbcFullNodeInfo object contains + a full record of the information required to recreate a subproblem. + A CbcPartialNodeInfo object expresses this information in terms of + differences from the parent. +*/ + + +/** \brief Holds complete information for recreating a subproblem. + + A CbcFullNodeInfo object contains all necessary information (bounds, basis, + and cuts) required to recreate a subproblem. + + \todo While there's no explicit statement, the code often makes the implicit + assumption that an CbcFullNodeInfo structure will appear only at the + root node of the search tree. Things will break if this assumption + is violated. +*/ + +class CbcFullNodeInfo : public CbcNodeInfo { + +public: + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound information at node, + creates a new basis according to information at node, but with the size + passed in through basis, and adds any cuts to the addCuts array. + + \note The basis passed in via basis is solely a vehicle for passing in + the desired basis size. It will be deleted and a new basis returned. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const ; + + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ; + + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const ; + // Default Constructor + CbcFullNodeInfo (); + + /** Constructor from continuous or satisfied + */ + CbcFullNodeInfo (CbcModel * model, + int numberRowsAtContinuous); + + // Copy constructor + CbcFullNodeInfo ( const CbcFullNodeInfo &); + + // Destructor + ~CbcFullNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + /// Lower bounds + inline const double * lower() const { + return lower_; + } + /// Set a bound + inline void setColLower(int sequence, double value) + { lower_[sequence]=value;} + /// Mutable lower bounds + inline double * mutableLower() const { + return lower_; + } + /// Upper bounds + inline const double * upper() const { + return upper_; + } + /// Set a bound + inline void setColUpper(int sequence, double value) + { upper_[sequence]=value;} + /// Mutable upper bounds + inline double * mutableUpper() const { + return upper_; + } +protected: + // Data + /** Full basis + + This MUST BE A POINTER to avoid cutting extra information in derived + warm start classes. + */ + CoinWarmStartBasis *basis_; + int numberIntegers_; + // Bounds stored in full + double * lower_; + double * upper_; +private: + /// Illegal Assignment operator + CbcFullNodeInfo & operator=(const CbcFullNodeInfo& rhs); +}; +#endif //CbcFullNodeInfo_H + diff --git a/thirdparty/linux/include/coin/coin/CbcGeneral.hpp b/thirdparty/linux/include/coin/coin/CbcGeneral.hpp new file mode 100644 index 0000000..19436b3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcGeneral.hpp @@ -0,0 +1,60 @@ +// $Id: CbcGeneral.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcGeneral_H +#define CbcGeneral_H + +#include "CbcBranchBase.hpp" +/** Define a catch all class. + This will create a list of subproblems +*/ + + +class CbcGeneral : public CbcObject { + +public: + + // Default Constructor + CbcGeneral (); + + /** Useful constructor + Just needs to point to model. + */ + CbcGeneral (CbcModel * model); + + // Copy constructor + CbcGeneral ( const CbcGeneral &); + + /// Clone + virtual CbcObject * clone() const = 0; + + // Assignment operator + CbcGeneral & operator=( const CbcGeneral& rhs); + + // Destructor + ~CbcGeneral (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion() = 0; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns) = 0; + +protected: + /// data +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcGeneralDepth.hpp b/thirdparty/linux/include/coin/coin/CbcGeneralDepth.hpp new file mode 100644 index 0000000..0d9f817 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcGeneralDepth.hpp @@ -0,0 +1,279 @@ +// $Id: CbcGeneralDepth.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcGeneralDepth_H +#define CbcGeneralDepth_H + +#include "CbcGeneral.hpp" +#include "CbcBranchBase.hpp" +#include "CbcSubProblem.hpp" + +#ifdef COIN_HAS_CLP + +/** Define a catch all class. + This will create a list of subproblems using partial evaluation +*/ +#include "ClpSimplex.hpp" +#include "ClpNode.hpp" + + +class CbcGeneralDepth : public CbcGeneral { + +public: + + // Default Constructor + CbcGeneralDepth (); + + /** Useful constructor + Just needs to point to model. + Initial version does evaluation to depth N + This is stored in CbcModel but may be + better here + */ + CbcGeneralDepth (CbcModel * model, int maximumDepth); + + // Copy constructor + CbcGeneralDepth ( const CbcGeneralDepth &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcGeneralDepth & operator=( const CbcGeneralDepth& rhs); + + // Destructor + ~CbcGeneralDepth (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Return maximum number of nodes + inline int maximumNodes() const { + return maximumNodes_; + } + /// Get maximum depth + inline int maximumDepth() const { + return maximumDepth_; + } + /// Set maximum depth + inline void setMaximumDepth(int value) { + maximumDepth_ = value; + } + /// Return number of nodes + inline int numberNodes() const { + return numberNodes_; + } + /// Get which solution + inline int whichSolution() const { + return whichSolution_; + } + /// Get ClpNode info + inline ClpNode * nodeInfo(int which) { + return nodeInfo_->nodeInfo_[which]; + } + + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Maximum depth + int maximumDepth_; + /// Maximum nodes + int maximumNodes_; + /// Which node has solution (or -1) + mutable int whichSolution_; + /// Number of valid nodes (including whichSolution_) + mutable int numberNodes_; + /// For solving nodes + mutable ClpNodeStuff * nodeInfo_; +}; +/** Branching object for general objects + + */ +class CbcNode; +class CbcGeneralBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcGeneralBranchingObject (); + + // Useful constructor + CbcGeneralBranchingObject (CbcModel * model); + + // Copy constructor + CbcGeneralBranchingObject ( const CbcGeneralBranchingObject &); + + // Assignment operator + CbcGeneralBranchingObject & operator=( const CbcGeneralBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcGeneralBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Double checks in case node can change its mind! + Can change objective etc */ + virtual void checkIsCutoff(double cutoff); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /// Fill in current objective etc + void state(double & objectiveValue, double & sumInfeasibilities, + int & numberUnsatisfied, int which) const; + /// Set CbcNode + inline void setNode(CbcNode * node) { + node_ = node; + } + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return GeneralDepthBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + /// Number of subproblems + inline int numberSubProblems() const { + return numberSubProblems_; + } + /// Decrement number left and return number + inline int decrementNumberLeft() { + numberSubLeft_--; + return numberSubLeft_; + } + /// Which node we want to use + inline int whichNode() const { + return whichNode_; + } + /// Set which node we want to use + inline void setWhichNode(int value) { + whichNode_ = value; + } + // Sub problem + const CbcSubProblem * subProblem(int which) const { + return subProblems_ + which; + } + +public: + /// data + // Sub problems + CbcSubProblem * subProblems_; + /// Node + CbcNode * node_; + /// Number of subproblems + int numberSubProblems_; + /// Number of subproblems left + int numberSubLeft_; + /// Which node we want to use (-1 for default) + int whichNode_; + /// Number of rows + int numberRows_; +}; +/** Branching object for general objects - just one + + */ +class CbcOneGeneralBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcOneGeneralBranchingObject (); + + // Useful constructor + CbcOneGeneralBranchingObject (CbcModel * model, + CbcGeneralBranchingObject * object, + int whichOne); + + // Copy constructor + CbcOneGeneralBranchingObject ( const CbcOneGeneralBranchingObject &); + + // Assignment operator + CbcOneGeneralBranchingObject & operator=( const CbcOneGeneralBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcOneGeneralBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Double checks in case node can change its mind! + Can change objective etc */ + virtual void checkIsCutoff(double cutoff); + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return OneGeneralBranchingObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +public: + /// data + /// Object + CbcGeneralBranchingObject * object_; + /// Which one + int whichOne_; +}; +#endif //COIN_HAS_CLP +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristic.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristic.hpp new file mode 100644 index 0000000..32466c6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristic.hpp @@ -0,0 +1,682 @@ +/* $Id: CbcHeuristic.hpp 2094 2014-11-18 11:15:36Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristic_H +#define CbcHeuristic_H + +#include <string> +#include <vector> +#include "CoinPackedMatrix.hpp" +#include "OsiCuts.hpp" +#include "CoinHelperFunctions.hpp" +#include "OsiBranchingObject.hpp" + +class OsiSolverInterface; + +class CbcModel; + +//############################################################################# + +class CbcHeuristicNodeList; +class CbcBranchingObject; + +/** A class describing the branching decisions that were made to get + to the node where a heuristic was invoked from */ + +class CbcHeuristicNode { +private: + void gutsOfConstructor(CbcModel& model); + CbcHeuristicNode(); + CbcHeuristicNode& operator=(const CbcHeuristicNode&); +private: + /// The number of branching decisions made + int numObjects_; + /** The indices of the branching objects. Note: an index may be + listed multiple times. E.g., a general integer variable that has + been branched on multiple times. */ + CbcBranchingObject** brObj_; +public: + CbcHeuristicNode(CbcModel& model); + + CbcHeuristicNode(const CbcHeuristicNode& rhs); + ~CbcHeuristicNode(); + double distance(const CbcHeuristicNode* node) const; + double minDistance(const CbcHeuristicNodeList& nodeList) const; + bool minDistanceIsSmall(const CbcHeuristicNodeList& nodeList, + const double threshold) const; + double avgDistance(const CbcHeuristicNodeList& nodeList) const; +}; + +class CbcHeuristicNodeList { +private: + void gutsOfDelete(); + void gutsOfCopy(const CbcHeuristicNodeList& rhs); +private: + std::vector<CbcHeuristicNode*> nodes_; +public: + CbcHeuristicNodeList() {} + CbcHeuristicNodeList(const CbcHeuristicNodeList& rhs); + CbcHeuristicNodeList& operator=(const CbcHeuristicNodeList& rhs); + ~CbcHeuristicNodeList(); + + void append(CbcHeuristicNode*& node); + void append(const CbcHeuristicNodeList& nodes); + inline const CbcHeuristicNode* node(int i) const { + return nodes_[i]; + } + inline int size() const { + return static_cast<int>(nodes_.size()); + } +}; + +//############################################################################# +/** Heuristic base class */ + +class CbcHeuristic { +private: + void gutsOfDelete() {} + void gutsOfCopy(const CbcHeuristic & rhs); + +public: + // Default Constructor + CbcHeuristic (); + + // Constructor with model - assumed before cuts + CbcHeuristic (CbcModel & model); + + // Copy constructor + CbcHeuristic ( const CbcHeuristic &); + + virtual ~CbcHeuristic(); + + /// Clone + virtual CbcHeuristic * clone() const = 0; + + /// Assignment operator + CbcHeuristic & operator=(const CbcHeuristic& rhs); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model) = 0; + + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution) = 0; + + /** returns 0 if no solution, 1 if valid solution, -1 if just + returning an estimate of best possible solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if nonzero code) + This is called at same time as cut generators - so can add cuts + Default is do nothing + */ + virtual int solution2(double & /*objectiveValue*/, + double * /*newSolution*/, + OsiCuts & /*cs*/) { + return 0; + } + + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() {} + + /** Sets "when" flag - 0 off, 1 at root, 2 other than root, 3 always. + If 10 added then don't worry if validate says there are funny objects + as user knows it will be fine + */ + inline void setWhen(int value) { + when_ = value; + } + /// Gets "when" flag - 0 off, 1 at root, 2 other than root, 3 always + inline int when() const { + return when_; + } + + /// Sets number of nodes in subtree (default 200) + inline void setNumberNodes(int value) { + numberNodes_ = value; + } + /// Gets number of nodes in a subtree (default 200) + inline int numberNodes() const { + return numberNodes_; + } + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + */ + inline void setSwitches(int value) { + switches_ = value; + } + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + 65536 bit and above used for temporary communication + */ + inline int switches() const { + return switches_; + } + /// Whether to exit at once on gap + bool exitNow(double bestObjective) const; + /// Sets feasibility pump options (-1 is off) + inline void setFeasibilityPumpOptions(int value) { + feasibilityPumpOptions_ = value; + } + /// Gets feasibility pump options (-1 is off) + inline int feasibilityPumpOptions() const { + return feasibilityPumpOptions_; + } + /// Just set model - do not do anything else + inline void setModelOnly(CbcModel * model) { + model_ = model; + } + + + /// Sets fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound (default 1.0) + inline void setFractionSmall(double value) { + fractionSmall_ = value; + } + /// Gets fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound (default 1.0) + inline double fractionSmall() const { + return fractionSmall_; + } + /// Get how many solutions the heuristic thought it got + inline int numberSolutionsFound() const { + return numberSolutionsFound_; + } + /// Increment how many solutions the heuristic thought it got + inline void incrementNumberSolutionsFound() { + numberSolutionsFound_++; + } + + /** Do mini branch and bound - return + 0 not finished - no solution + 1 not finished - solution + 2 finished - no solution + 3 finished - solution + (could add global cut if finished) + -1 returned on size + -2 time or user event + */ + int smallBranchAndBound(OsiSolverInterface * solver, int numberNodes, + double * newSolution, double & newSolutionValue, + double cutoff , std::string name) const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /// Create C++ lines to get to current state - does work for base class + void generateCpp( FILE * fp, const char * heuristic) ; + /// Returns true if can deal with "odd" problems e.g. sos type 2 + virtual bool canDealWithOdd() const { + return false; + } + /// return name of heuristic + inline const char *heuristicName() const { + return heuristicName_.c_str(); + } + /// set name of heuristic + inline void setHeuristicName(const char *name) { + heuristicName_ = name; + } + /// Set random number generator seed + void setSeed(int value); + /// Get random number generator seed + int getSeed() const; + /// Sets decay factor (for howOften) on failure + inline void setDecayFactor(double value) { + decayFactor_ = value; + } + /// Set input solution + void setInputSolution(const double * solution, double objValue); + /* Runs if bit set + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + inline void setWhereFrom(int value) { + whereFrom_ = value; + } + inline int whereFrom() const { + return whereFrom_; + } + /** Upto this depth we call the tree shallow and the heuristic can be called + multiple times. That is, the test whether the current node is far from + the others where the jeuristic was invoked will not be done, only the + frequency will be tested. After that depth the heuristic will can be + invoked only once per node, right before branching. That's when it'll be + tested whether the heur should run at all. */ + inline void setShallowDepth(int value) { + shallowDepth_ = value; + } + /** How often to invoke the heuristics in the shallow part of the tree */ + inline void setHowOftenShallow(int value) { + howOftenShallow_ = value; + } + /** How "far" should this node be from every other where the heuristic was + run in order to allow the heuristic to run in this node, too. Currently + this is tested, but we may switch to avgDistanceToRun_ in the future. */ + inline void setMinDistanceToRun(int value) { + minDistanceToRun_ = value; + } + + /** Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + virtual bool shouldHeurRun(int whereFrom); + /** Check whether the heuristic should run this time */ + bool shouldHeurRun_randomChoice(); + void debugNodes(); + void printDistanceToNodes(); + /// how many times the heuristic has actually run + inline int numRuns() const { + return numRuns_; + } + + /// How many times the heuristic could run + inline int numCouldRun() const { + return numCouldRun_; + } + /*! \brief Clone, but ... + + If type is + - 0 clone the solver for the model, + - 1 clone the continuous solver for the model + - Add 2 to say without integer variables which are at low priority + - Add 4 to say quite likely infeasible so give up easily (clp only). + */ + OsiSolverInterface * cloneBut(int type); +protected: + + /// Model + CbcModel * model_; + /// When flag - 0 off, 1 at root, 2 other than root, 3 always + int when_; + /// Number of nodes in any sub tree + int numberNodes_; + /** Feasibility pump options , -1 is off + >=0 for feasibility pump itself + -2 quick proximity search + -3 longer proximity search + */ + int feasibilityPumpOptions_; + /// Fraction of new(rows+columns)/old(rows+columns) before doing small branch and bound + mutable double fractionSmall_; + /// Thread specific random number generator + CoinThreadRandom randomNumberGenerator_; + /// Name for printing + std::string heuristicName_; + + /// How often to do (code can change) + mutable int howOften_; + /// How much to increase how often + double decayFactor_; + /** Switches (does not apply equally to all heuristics) + 1 bit - stop once allowable gap on objective reached + 2 bit - always do given number of passes + 4 bit - weaken cutoff by 5% every 50 passes? + 8 bit - if has cutoff and suminf bobbling for 20 passes then + first try halving distance to best possible then + try keep halving distance to known cutoff + 16 bit - needs new solution to run + 1024 bit - stop all heuristics on max time + */ + mutable int switches_; + /* Runs if bit set + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + int whereFrom_; + /** Upto this depth we call the tree shallow and the heuristic can be called + multiple times. That is, the test whether the current node is far from + the others where the jeuristic was invoked will not be done, only the + frequency will be tested. After that depth the heuristic will can be + invoked only once per node, right before branching. That's when it'll be + tested whether the heur should run at all. */ + int shallowDepth_; + /** How often to invoke the heuristics in the shallow part of the tree */ + int howOftenShallow_; + /** How many invocations happened within the same node when in a shallow + part of the tree. */ + int numInvocationsInShallow_; + /** How many invocations happened when in the deep part of the tree. For + every node we count only one invocation. */ + int numInvocationsInDeep_; + /** After how many deep invocations was the heuristic run last time */ + int lastRunDeep_; + /// how many times the heuristic has actually run + int numRuns_; + /** How "far" should this node be from every other where the heuristic was + run in order to allow the heuristic to run in this node, too. Currently + this is tested, but we may switch to avgDistanceToRun_ in the future. */ + int minDistanceToRun_; + + /// The description of the nodes where this heuristic has been applied + CbcHeuristicNodeList runNodes_; + + /// How many times the heuristic could run + int numCouldRun_; + + /// How many solutions the heuristic thought it got + int numberSolutionsFound_; + + /// How many nodes the heuristic did this go + mutable int numberNodesDone_; + + // Input solution - so can be used as seed + double * inputSolution_; + + +#ifdef JJF_ZERO + /// Lower bounds of last node where the heuristic found a solution + double * lowerBoundLastNode_; + /// Upper bounds of last node where the heuristic found a solution + double * upperBoundLastNode_; +#endif +}; +/** Rounding class + */ + +class CbcRounding : public CbcHeuristic { +public: + + // Default Constructor + CbcRounding (); + + // Constructor with model - assumed before cuts + CbcRounding (CbcModel & model); + + // Copy constructor + CbcRounding ( const CbcRounding &); + + // Destructor + ~CbcRounding (); + + /// Assignment operator + CbcRounding & operator=(const CbcRounding& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + Use solutionValue rather than solvers one + */ + virtual int solution(double & objectiveValue, + double * newSolution, + double solutionValue); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + + /// Set seed + void setSeed(int value) { + seed_ = value; + } + /** Check whether the heuristic should run at all + 0 - before cuts at root node (or from doHeuristics) + 1 - during cuts at root + 2 - after root node cuts + 3 - after cuts at other nodes + 4 - during cuts at other nodes + 8 added if previous heuristic in loop found solution + */ + virtual bool shouldHeurRun(int whereFrom); + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Original matrix by + CoinPackedMatrix matrixByRow_; + + // Down locks + unsigned short * down_; + + // Up locks + unsigned short * up_; + + // Equality locks + unsigned short * equal_; + + // Seed for random stuff + int seed_; +}; + +/** Partial solution class + If user knows a partial solution this tries to get an integer solution + it uses hotstart information + */ + +class CbcHeuristicPartial : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicPartial (); + + /** Constructor with model - assumed before cuts + Fixes all variables with priority <= given + and does given number of nodes + */ + CbcHeuristicPartial (CbcModel & model, int fixPriority = 10000, int numberNodes = 200); + + // Copy constructor + CbcHeuristicPartial ( const CbcHeuristicPartial &); + + // Destructor + ~CbcHeuristicPartial (); + + /// Assignment operator + CbcHeuristicPartial & operator=(const CbcHeuristicPartial& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + + /// Set priority level + void setFixPriority(int value) { + fixPriority_ = value; + } + + /** Check whether the heuristic should run at all */ + virtual bool shouldHeurRun(int whereFrom); + +protected: + // Data + + // All variables with abs priority <= this will be fixed + int fixPriority_; +}; + +/** heuristic - just picks up any good solution + found by solver - see OsiBabSolver + */ + +class CbcSerendipity : public CbcHeuristic { +public: + + // Default Constructor + CbcSerendipity (); + + /* Constructor with model + */ + CbcSerendipity (CbcModel & model); + + // Copy constructor + CbcSerendipity ( const CbcSerendipity &); + + // Destructor + ~CbcSerendipity (); + + /// Assignment operator + CbcSerendipity & operator=(const CbcSerendipity& rhs); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + +protected: +}; + +/** Just One class - this chooses one at random + */ + +class CbcHeuristicJustOne : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicJustOne (); + + // Constructor with model - assumed before cuts + CbcHeuristicJustOne (CbcModel & model); + + // Copy constructor + CbcHeuristicJustOne ( const CbcHeuristicJustOne &); + + // Destructor + ~CbcHeuristicJustOne (); + + /// Clone + virtual CbcHeuristicJustOne * clone() const; + + /// Assignment operator + CbcHeuristicJustOne & operator=(const CbcHeuristicJustOne& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + This does Fractional Diving + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + This is dummy as never called + */ + virtual bool selectVariableToBranch(OsiSolverInterface* /*solver*/, + const double* /*newSolution*/, + int& /*bestColumn*/, + int& /*bestRound*/) { + return true; + } + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + /// Adds an heuristic with probability + void addHeuristic(const CbcHeuristic * heuristic, double probability); + /// Normalize probabilities + void normalizeProbabilities(); +protected: + // Data + + // Probability of running a heuristic + double * probabilities_; + + // Heuristics + CbcHeuristic ** heuristic_; + + // Number of heuristics + int numberHeuristics_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDINS.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDINS.hpp new file mode 100644 index 0000000..49d0c1c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDINS.hpp @@ -0,0 +1,96 @@ +// $Id: CbcHeuristicDINS.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicDINS_H +#define CbcHeuristicDINS_H + +#include "CbcHeuristic.hpp" + + +class CbcHeuristicDINS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDINS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicDINS (CbcModel & model); + + // Copy constructor + CbcHeuristicDINS ( const CbcHeuristicDINS &); + + // Destructor + ~CbcHeuristicDINS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicDINS & operator=(const CbcHeuristicDINS& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Sets maximum number of solutions kept + inline void setMaximumKeep(int value) { + maximumKeepSolutions_ = value; + } + /// Sets tightness of extra constraint + inline void setConstraint(int value) { + localSpace_ = value; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /// Maximum number of solutions to keep + int maximumKeepSolutions_; + /// Number of solutions kept + int numberKeptSolutions_; + /// Number of integer variables + int numberIntegers_; + /// Local parameter + int localSpace_; + /// Values of integer variables + int ** values_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDW.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDW.hpp new file mode 100644 index 0000000..337bd0f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDW.hpp @@ -0,0 +1,309 @@ +// $Id: CbcHeuristicDW.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef CbcHeuristicDW_H +#define CbcHeuristicDW_H + +#include "CbcHeuristic.hpp" + +/** + This is unlike the other heuristics in that it is very very compute intensive. + It tries to find a DW structure and use that + */ + +class CbcHeuristicDW : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDW (); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, int keepContinuous=0); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicDW (CbcModel & model, + int callBack(CbcHeuristicDW * currentHeuristic, + CbcModel * thisModel, + int whereFrom), + int keepContinuous=0); + + // Copy constructor + CbcHeuristicDW ( const CbcHeuristicDW &); + + // Destructor + ~CbcHeuristicDW (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicDW & operator=(const CbcHeuristicDW& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /** Return number of blocks + <=0 - no usable structure */ + inline int numberBlocks() const + { return numberBlocks_;} + /// Pass in a solution + void passInSolution(const double * solution); + /// Pass in continuous solution + void passInContinuousSolution(const double * solution); + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + void setProposalActions(int fullDWEverySoOften); + /// Objective value when whichDw created + double objectiveValueWhen(int whichDW) const; + /// Number of columns in DW + int numberColumnsDW(int whichDW) const; + /// Solver + inline OsiSolverInterface * solver() const + { return solver_;} + /// DW model (user must delete) + OsiSolverInterface * DWModel(int whichDW) const; + /// Best objective value + inline double bestObjective() const + { return bestObjective_;} + /// Best solution found so far + inline const double * bestSolution() const + { return bestSolution_;} + /// Continuous solution + inline const double * continuousSolution() const + { return continuousSolution_;} + /// Reduced costs of fixed solution + inline const double * fixedDj() const + { return fixedDj_;} + /// Objective at which DW updated + inline const double * objectiveDW() const + { return objectiveDW_;} + /// Number of times we have added to DW model + inline int numberDWTimes() const + { return numberDWTimes_;} + /// Number of columns in DW + inline const int * numberColumnsDW() const + { return numberColumnsDW_;} + /// Set number of passes + inline void setNumberPasses(int value) + { numberPasses_ = value;} + /// Set number of passes without better solution + inline void setNumberBadPasses(int value) + { numberBadPasses_ = value;} + /// Set number free integers needed (Base value) + inline void setNumberNeeded(int value) + { nNeededBase_ = value;} + /// Get number free integers needed (Base value) + inline int getNumberNeeded() const + {return nNeededBase_;} + /// Set number free integers needed (Current value) + inline void setCurrentNumberNeeded(int value) + { nNeeded_ = value;} + /// Get number free integers needed (Current value) + inline int getCurrentNumberNeeded() const + {return nNeeded_;} + /// Set number nodes (could be done in callback) (Base value) + inline void setNumberNodes(int value) + { nNodesBase_ = value;} + /// Get number nodes (could be done in callback) (Base value) + inline int getNumberNodes() const + {return nNodesBase_;} + /// Set number nodes (could be done in callback) (Current value) + inline void setCurrentNumberNodes(int value) + { nNodes_ = value;} + /// Get number nodes (could be done in callback) (Current value) + inline int getCurrentNumberNodes() const + {return nNodes_;} + /// Set target objective + inline void setTargetObjective(double value) + { targetObjective_ = value;} + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Block for every row + inline const int * whichRowBlock() const + { return whichRowBlock_;} + /// Block for every column + inline const int * whichColumnBlock() const + { return whichColumnBlock_;} + /// Initial Lower bounds + inline double * initialLower() const + { return saveLower_;} + /// Initial Upper bounds + inline double * initialUpper() const + { return saveUpper_;} + /// Local integer arrays (each numberBlocks_ long) + inline int * intArrays() const + { return intArray_;} + /// Local double arrays (each numberBlocks_ long) + inline double * doubleArrays() const + { return doubleArray_;} + /// Phase of solution + inline int phase() const + { return phase_;} + /// Pass number + inline int pass() const + { return pass_;} + /// Which columns are in block + inline const int * columnsInBlock() const + { return columnsInBlock_;} + /// Starts for columnsInBlock + inline const int * startColumnBlock() const + { return startColumnBlock_;} + /// Number of integer variables in each block + inline const int * intsInBlock() const + { return intsInBlock_;} + /// Objective value (could also check validity) + double objectiveValue(const double * solution); +private: + /// Guts of copy + void gutsOfCopy(const CbcHeuristicDW & rhs); + /// Guts of delete + void gutsOfDelete(); + /// Set default values + void setDefaults(); + /// Find structure + void findStructure(); + /// Set up DW structure + void setupDWStructures(); + /// Add DW proposals + int addDW(const double * solution,int numberBlocksUsed, + const int * whichBlocks); +protected: + typedef int (*heuristicCallBack) (CbcHeuristicDW * ,CbcModel *, int) ; + // Data + /// Target objective + double targetObjective_; + /// Best objective value + double bestObjective_; + /// Objective value last time + double lastObjective_; + /** Call back + whereFrom - + 0 - after blocks found but before data setup + 1 - after blocks sorted but before used + 2 - just before normal branch and bound + 3 - after DW has been updated + 4 - if better solution found + 5 - every time a block might be used + next few for adjustment of nNeeded etc + 6 - complete search done - no solution + 7 - stopped on nodes - no improvement + 8 - improving (same as 4 but after nNeeded changed + Pointers to local data given by following pointers + */ + heuristicCallBack functionPointer_; + /// Local integer arrays (each numberBlocks_ long) + int * intArray_; + /// Local double arrays (each numberBlocks_ long) + double * doubleArray_; + /// Base solver + OsiSolverInterface * solver_; + /// DW solver + OsiSolverInterface * dwSolver_; + /// Best solution found so far + double * bestSolution_; + /// Continuous solution + double * continuousSolution_; + /// Reduced costs of fixed solution + double * fixedDj_; + /// Original lower bounds + double * saveLower_; + /// Original Upper bounds + double * saveUpper_; + /// random numbers for master rows + double * random_; + /// Weights for each proposal + double * weights_; + /// Objective at which DW updated + double * objectiveDW_; + /// Number of columns in each DW + int * numberColumnsDW_; + /// Block for every row + int * whichRowBlock_; + /// Block for every column + int * whichColumnBlock_; + /// Block number for each proposal + int * dwBlock_; + /// Points back to master rows + int * backwardRow_; + /// Which rows are in blocke + int * rowsInBlock_; + /// Which columns are in block + int * columnsInBlock_; + /// Starts for rowsInBlock + int * startRowBlock_; + /// Starts for columnsInBlock + int * startColumnBlock_; + /// Number of integer variables in each block + int * intsInBlock_; + /// Bits set for 1 integers in each block + unsigned int * fingerPrint_; + /// Affinity each block has for other (will be triangular?) + unsigned short * affinity_; + /** DW Proposal actions + fullDWEverySoOften - + 0 - off + k - every k times solution gets better + */ + int fullDWEverySoOften_; + /// Number of passes + int numberPasses_; + /// How often to do (code can change) + int howOften_; + /// Current maximum number of DW proposals + int maximumDW_; + /// Number of DW proposals + int numberDW_; + /// Number of times we have added to DW model + int numberDWTimes_; + /// Number of unsigned ints needed for each block of fingerPrint + int sizeFingerPrint_; + /// Number of columns in master + int numberMasterColumns_; + /// Number of rows in master + int numberMasterRows_; + /// Number of blocks + int numberBlocks_; + /// Action on decomposition - 1 keep continuous, 0 don't + int keepContinuous_; + /// Phase of solution + int phase_; + /// Pass number + int pass_; + /// Base number of integers needed + int nNeededBase_; + /// Base number of nodes needed + int nNodesBase_; + /// Base number of integers needed + int nNeeded_; + /// Base number of nodes needed + int nNodes_; + /// Number of passes without better solution + int numberBadPasses_; + // 0 - fine, 1 can't be better, 2 max node + int solveState_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDive.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDive.hpp new file mode 100644 index 0000000..ea583db --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDive.hpp @@ -0,0 +1,192 @@ +/* $Id: CbcHeuristicDive.hpp 2093 2014-11-06 16:17:38Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDive_H +#define CbcHeuristicDive_H + +#include "CbcHeuristic.hpp" +class CbcSubProblem; +class OsiRowCut; +struct PseudoReducedCost { + int var; + double pseudoRedCost; +}; + + +/** Dive class + */ + +class CbcHeuristicDive : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDive (); + + // Constructor with model - assumed before cuts + CbcHeuristicDive (CbcModel & model); + + // Copy constructor + CbcHeuristicDive ( const CbcHeuristicDive &); + + // Destructor + ~CbcHeuristicDive (); + + /// Clone + virtual CbcHeuristicDive * clone() const = 0; + + /// Assignment operator + CbcHeuristicDive & operator=(const CbcHeuristicDive& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /// Create C++ lines to get to current state - does work for base class + void generateCpp( FILE * fp, const char * heuristic); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + // REMLOVE using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + This does Fractional Diving + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// inner part of dive + int solution(double & objectiveValue, int & numberNodes, + int & numberCuts, OsiRowCut ** cuts, + CbcSubProblem ** & nodes, + double * newSolution); + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + also returns list of nodes + This does Fractional Diving + */ + int fathom(CbcModel * model, int & numberNodes,CbcSubProblem ** & nodes); + + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate(); + + /// Sets priorities if any + void setPriorities(); + + /// Select candidate binary variables for fixing + void selectBinaryVariables(); + + /// Set percentage of integer variables to fix at bounds + void setPercentageToFix(double value) { + percentageToFix_ = value; + } + + /// Set maximum number of iterations + void setMaxIterations(int value) { + maxIterations_ = value; + } + + /// Set maximum number of simplex iterations + void setMaxSimplexIterations(int value) { + maxSimplexIterations_ = value; + } + /// Get maximum number of simplex iterations + inline int maxSimplexIterations() const { + return maxSimplexIterations_; + } + + /// Set maximum number of simplex iterations at root node + void setMaxSimplexIterationsAtRoot(int value) { + maxSimplexIterationsAtRoot_ = value; + } + + /// Set maximum time allowed + void setMaxTime(double value) { + maxTime_ = value; + } + + /// Tests if the heuristic can run + virtual bool canHeuristicRun(); + + /** Selects the next variable to branch on + Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound) = 0; + /** Initializes any data which is going to be used repeatedly + in selectVariableToBranch */ + virtual void initializeData() {} + + /// Perform reduced cost fixing on integer variables + int reducedCostFix (OsiSolverInterface* solver); + /// Fix other variables at bounds + virtual int fixOtherVariables(OsiSolverInterface * solver, + const double * solution, + PseudoReducedCost * candidate, + const double * random); + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Original matrix by + CoinPackedMatrix matrixByRow_; + + // Down locks + unsigned short * downLocks_; + + // Up locks + unsigned short * upLocks_; + + /// Extra down array (number Integers long) + double * downArray_; + + /// Extra up array (number Integers long) + double * upArray_; + + /// Array of priorities + typedef struct { + unsigned int direction:3; // 0 bit off, 1 bit (0 down first, 1 up first) 2 bit non zero don't try other way + unsigned int priority:29; + } PriorityType; + PriorityType * priority_; + // Indexes of binary variables with 0 objective coefficient + // and in variable bound constraints + std::vector<int> binVarIndex_; + + // Indexes of variable bound rows for each binary variable + std::vector<int> vbRowIndex_; + + // Percentage of integer variables to fix at bounds + double percentageToFix_; + + // Maximum time allowed + double maxTime_; + + // Small objective (i.e. treat zero objective as this) + double smallObjective_; + + // Maximum number of major iterations + int maxIterations_; + + // Maximum number of simplex iterations + int maxSimplexIterations_; + + // Maximum number of simplex iterations at root node + int maxSimplexIterationsAtRoot_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDiveCoefficient.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveCoefficient.hpp new file mode 100644 index 0000000..d4b7b68 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveCoefficient.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveCoefficient.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveCoefficient_H +#define CbcHeuristicDiveCoefficient_H + +#include "CbcHeuristicDive.hpp" + +/** DiveCoefficient class + */ + +class CbcHeuristicDiveCoefficient : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveCoefficient (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveCoefficient (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveCoefficient ( const CbcHeuristicDiveCoefficient &); + + // Destructor + ~CbcHeuristicDiveCoefficient (); + + /// Clone + virtual CbcHeuristicDiveCoefficient * clone() const; + + /// Assignment operator + CbcHeuristicDiveCoefficient & operator=(const CbcHeuristicDiveCoefficient& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDiveFractional.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveFractional.hpp new file mode 100644 index 0000000..bc17047 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveFractional.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveFractional.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveFractional_H +#define CbcHeuristicDiveFractional_H + +#include "CbcHeuristicDive.hpp" + +/** DiveFractional class + */ + +class CbcHeuristicDiveFractional : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveFractional (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveFractional (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveFractional ( const CbcHeuristicDiveFractional &); + + // Destructor + ~CbcHeuristicDiveFractional (); + + /// Clone + virtual CbcHeuristicDiveFractional * clone() const; + + /// Assignment operator + CbcHeuristicDiveFractional & operator=(const CbcHeuristicDiveFractional& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDiveGuided.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveGuided.hpp new file mode 100644 index 0000000..2b369dc --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveGuided.hpp @@ -0,0 +1,55 @@ +/* $Id: CbcHeuristicDiveGuided.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveGuided_H +#define CbcHeuristicDiveGuided_H + +#include "CbcHeuristicDive.hpp" + +/** DiveGuided class + */ + +class CbcHeuristicDiveGuided : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveGuided (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveGuided (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveGuided ( const CbcHeuristicDiveGuided &); + + // Destructor + ~CbcHeuristicDiveGuided (); + + /// Clone + virtual CbcHeuristicDiveGuided * clone() const; + + /// Assignment operator + CbcHeuristicDiveGuided & operator=(const CbcHeuristicDiveGuided& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Tests if the heuristic can run + virtual bool canHeuristicRun(); + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDiveLineSearch.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveLineSearch.hpp new file mode 100644 index 0000000..30c5f63 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveLineSearch.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveLineSearch.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveLineSearch_H +#define CbcHeuristicDiveLineSearch_H + +#include "CbcHeuristicDive.hpp" + +/** DiveLineSearch class + */ + +class CbcHeuristicDiveLineSearch : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveLineSearch (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveLineSearch (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveLineSearch ( const CbcHeuristicDiveLineSearch &); + + // Destructor + ~CbcHeuristicDiveLineSearch (); + + /// Clone + virtual CbcHeuristicDiveLineSearch * clone() const; + + /// Assignment operator + CbcHeuristicDiveLineSearch & operator=(const CbcHeuristicDiveLineSearch& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDivePseudoCost.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDivePseudoCost.hpp new file mode 100644 index 0000000..4f0dcb0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDivePseudoCost.hpp @@ -0,0 +1,60 @@ +/* $Id: CbcHeuristicDivePseudoCost.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDivePseudoCost_H +#define CbcHeuristicDivePseudoCost_H + +#include "CbcHeuristicDive.hpp" + +/** DivePseudoCost class + */ + +class CbcHeuristicDivePseudoCost : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDivePseudoCost (); + + // Constructor with model - assumed before cuts + CbcHeuristicDivePseudoCost (CbcModel & model); + + // Copy constructor + CbcHeuristicDivePseudoCost ( const CbcHeuristicDivePseudoCost &); + + // Destructor + ~CbcHeuristicDivePseudoCost (); + + /// Clone + virtual CbcHeuristicDivePseudoCost * clone() const; + + /// Assignment operator + CbcHeuristicDivePseudoCost & operator=(const CbcHeuristicDivePseudoCost& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + /** Initializes any data which is going to be used repeatedly + in selectVariableToBranch */ + virtual void initializeData() ; + /// Fix other variables at bounds + virtual int fixOtherVariables(OsiSolverInterface * solver, + const double * solution, + PseudoReducedCost * candidate, + const double * random); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicDiveVectorLength.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveVectorLength.hpp new file mode 100644 index 0000000..c83852f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicDiveVectorLength.hpp @@ -0,0 +1,52 @@ +/* $Id: CbcHeuristicDiveVectorLength.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicDiveVectorLength_H +#define CbcHeuristicDiveVectorLength_H + +#include "CbcHeuristicDive.hpp" + +/** DiveVectorLength class + */ + +class CbcHeuristicDiveVectorLength : public CbcHeuristicDive { +public: + + // Default Constructor + CbcHeuristicDiveVectorLength (); + + // Constructor with model - assumed before cuts + CbcHeuristicDiveVectorLength (CbcModel & model); + + // Copy constructor + CbcHeuristicDiveVectorLength ( const CbcHeuristicDiveVectorLength &); + + // Destructor + ~CbcHeuristicDiveVectorLength (); + + /// Clone + virtual CbcHeuristicDiveVectorLength * clone() const; + + /// Assignment operator + CbcHeuristicDiveVectorLength & operator=(const CbcHeuristicDiveVectorLength& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Selects the next variable to branch on + /** Returns true if all the fractional variables can be trivially + rounded. Returns false, if there is at least one fractional variable + that is not trivially roundable. In this case, the bestColumn + returned will not be trivially roundable. + */ + virtual bool selectVariableToBranch(OsiSolverInterface* solver, + const double* newSolution, + int& bestColumn, + int& bestRound); + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicFPump.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicFPump.hpp new file mode 100644 index 0000000..1c1af86 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicFPump.hpp @@ -0,0 +1,340 @@ +/* $Id: CbcHeuristicFPump.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicFeasibilityPump_H +#define CbcHeuristicFeasibilityPump_H + +#include "CbcHeuristic.hpp" +#include "OsiClpSolverInterface.hpp" + +/** Feasibility Pump class + */ + +class CbcHeuristicFPump : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicFPump (); + + // Constructor with model - assumed before cuts + CbcHeuristicFPump (CbcModel & model, + double downValue = 0.5, bool roundExpensive = false); + + // Copy constructor + CbcHeuristicFPump ( const CbcHeuristicFPump &); + + // Destructor + ~CbcHeuristicFPump (); + + /// Assignment operator + CbcHeuristicFPump & operator=(const CbcHeuristicFPump& rhs); + /// Clone + virtual CbcHeuristic * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts. + + It may make sense for user to call this outside Branch and Cut to + get solution. Or normally is just at root node. + + * new meanings for when_ - on first try then set back to 1 + 11 - at end fix all integers at same bound throughout + 12 - also fix all integers staying at same internal integral value throughout + 13 - also fix all continuous variables staying at same bound throughout + 14 - also fix all continuous variables staying at same internal value throughout + 15 - as 13 but no internal integers + And beyond that, it's apparently possible for the range to be between 21 + and 25, in which case it's reduced on entry to solution() to be between + 11 and 15 and allSlack is set to true. Then, if we're not processing + general integers, we'll use an all-slack basis to solve ... what? Don't + see that yet. + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Set maximum Time (default off) - also sets starttime to current + void setMaximumTime(double value); + /// Get maximum Time (default 0.0 == time limit off) + inline double maximumTime() const { + return maximumTime_; + } + /// Set fake cutoff (default COIN_DBL_MAX == off) + inline void setFakeCutoff(double value) { + fakeCutoff_ = value; + } + /// Get fake cutoff (default 0.0 == off) + inline double fakeCutoff() const { + return fakeCutoff_; + } + /// Set absolute increment (default 0.0 == off) + inline void setAbsoluteIncrement(double value) { + absoluteIncrement_ = value; + } + /// Get absolute increment (default 0.0 == off) + inline double absoluteIncrement() const { + return absoluteIncrement_; + } + /// Set relative increment (default 0.0 == off) + inline void setRelativeIncrement(double value) { + relativeIncrement_ = value; + } + /// Get relative increment (default 0.0 == off) + inline double relativeIncrement() const { + return relativeIncrement_; + } + /// Set default rounding (default 0.5) + inline void setDefaultRounding(double value) { + defaultRounding_ = value; + } + /// Get default rounding (default 0.5) + inline double defaultRounding() const { + return defaultRounding_; + } + /// Set initial weight (default 0.0 == off) + inline void setInitialWeight(double value) { + initialWeight_ = value; + } + /// Get initial weight (default 0.0 == off) + inline double initialWeight() const { + return initialWeight_; + } + /// Set weight factor (default 0.1) + inline void setWeightFactor(double value) { + weightFactor_ = value; + } + /// Get weight factor (default 0.1) + inline double weightFactor() const { + return weightFactor_; + } + /// Set threshold cost for using original cost - even on continuous (default infinity) + inline void setArtificialCost(double value) { + artificialCost_ = value; + } + /// Get threshold cost for using original cost - even on continuous (default infinity) + inline double artificialCost() const { + return artificialCost_; + } + /// Get iteration to size ratio + inline double iterationRatio() const { + return iterationRatio_; + } + /// Set iteration to size ratio + inline void setIterationRatio(double value) { + iterationRatio_ = value; + } + /// Set maximum passes (default 100) + inline void setMaximumPasses(int value) { + maximumPasses_ = value; + } + /// Get maximum passes (default 100) + inline int maximumPasses() const { + return maximumPasses_; + } + /// Set maximum retries (default 1) + inline void setMaximumRetries(int value) { + maximumRetries_ = value; + } + /// Get maximum retries (default 1) + inline int maximumRetries() const { + return maximumRetries_; + } + /** Set use of multiple solutions and solves + 0 - do not reuse solves, do not accumulate integer solutions for local search + 1 - do not reuse solves, accumulate integer solutions for local search + 2 - reuse solves, do not accumulate integer solutions for local search + 3 - reuse solves, accumulate integer solutions for local search + If we add 4 then use second form of problem (with extra rows and variables for general integers) + At some point (date?), I added + + And then there are a few bit fields: + 4 - something about general integers + So my (lh) guess for 4 was at least in the ballpark, but I'll have to + rethink 8 entirely (and it may well not mean the same thing as it did + when I added that comment. + 8 - determines whether we process general integers + + And on 090831, John added + + If we add 4 then use second form of problem (with extra rows and + variables for general integers) + If we add 8 then can run after initial cuts (if no solution) + */ + inline void setAccumulate(int value) { + accumulate_ = value; + } + /// Get accumulation option + inline int accumulate() const { + return accumulate_; + } + /** Set whether to fix variables on known solution + 0 - do not fix + 1 - fix integers on reduced costs + 2 - fix integers on reduced costs but only on entry + */ + inline void setFixOnReducedCosts(int value) { + fixOnReducedCosts_ = value; + } + /// Get reduced cost option + inline int fixOnReducedCosts() const { + return fixOnReducedCosts_; + } + /** Set reduced cost multiplier + 1.0 as normal + <1.0 (x) - pretend gap is x* actual gap - just for fixing + */ + inline void setReducedCostMultiplier(double value) { + reducedCostMultiplier_ = value; + } + /// Get reduced cost multiplier + inline double reducedCostMultiplier() const { + return reducedCostMultiplier_; + } + +protected: + // Data + /// Start time + double startTime_; + /// Maximum Cpu seconds + double maximumTime_; + /** Fake cutoff value. + If set then better of real cutoff and this used to add a constraint + */ + double fakeCutoff_; + /// If positive carry on after solution expecting gain of at least this + double absoluteIncrement_; + /// If positive carry on after solution expecting gain of at least this times objective + double relativeIncrement_; + /// Default is round up if > this + double defaultRounding_; + /// Initial weight for true objective + double initialWeight_; + /// Factor for decreasing weight + double weightFactor_; + /// Threshold cost for using original cost - even on continuous + double artificialCost_; + /** If iterationRatio >0 use instead of maximumPasses_ + test is iterations > ratio*(2*nrow+ncol) */ + double iterationRatio_; + /** Reduced cost multiplier + 1.0 as normal + <1.0 (x) - pretend gap is x* actual gap - just for fixing + */ + double reducedCostMultiplier_; + /// Maximum number of passes + int maximumPasses_; + /** Maximum number of retries if we find a solution. + If negative we clean out used array + */ + int maximumRetries_; + /** Set use of multiple solutions and solves + 0 - do not reuse solves, do not accumulate integer solutions for local search + 1 - do not reuse solves, accumulate integer solutions for local search + 2 - reuse solves, do not accumulate integer solutions for local search + 3 - reuse solves, accumulate integer solutions for local search + If we add 4 then use second form of problem (with extra rows and variables for general integers) + If we do not accumulate solutions then no mini branch and bounds will be done + reuse - refers to initial solve after adding in new "cut" + If we add 8 then can run after initial cuts (if no solution) + */ + int accumulate_; + /** Set whether to fix variables on known solution + 0 - do not fix + 1 - fix integers on reduced costs + 2 - fix integers on reduced costs but only on entry + */ + int fixOnReducedCosts_; + /// If true round to expensive + bool roundExpensive_; + +private: + /** Rounds solution - down if < downValue + If roundExpensive then always to more expnsive. + returns 0 if current is solution + */ + int rounds(OsiSolverInterface * solver, double * solution, + /*const double * objective, */ + int numberIntegers, const int * integerVariable, + /*char * pumpPrint,*/int passNumber, + /*bool roundExpensive=false,*/ + double downValue = 0.5, int *flip = 0); + /* note for eagle eyed readers. + when_ can now be exotic - + <=10 normal + */ +}; + +# ifdef COIN_HAS_CLP + +class CbcDisasterHandler : public OsiClpDisasterHandler { +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ +#ifdef JJF_ZERO + /// Into simplex + virtual void intoSimplex(); + /// Checks if disaster + virtual bool check() const ; + /// saves information for next attempt + virtual void saveInfo(); +#endif + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CbcDisasterHandler(CbcModel * model = NULL); + /** Destructor */ + virtual ~CbcDisasterHandler(); + // Copy + CbcDisasterHandler(const CbcDisasterHandler&); + // Assignment + CbcDisasterHandler& operator=(const CbcDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setCbcModel(CbcModel * model); + /// Get model + inline CbcModel * cbcModel() const { + return cbcModel_; + } + + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to model + CbcModel * cbcModel_; + + //@} +}; +#endif + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicGreedy.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicGreedy.hpp new file mode 100644 index 0000000..4a6a1f3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicGreedy.hpp @@ -0,0 +1,280 @@ +/* $Id: CbcHeuristicGreedy.hpp 1585 2011-01-11 19:04:34Z forrest $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicGreedy_H +#define CbcHeuristicGreedy_H + +#include "CbcHeuristic.hpp" +/** Greedy heuristic classes + */ + +class CbcHeuristicGreedyCover : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedyCover (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedyCover (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedyCover ( const CbcHeuristicGreedyCover &); + + // Destructor + ~CbcHeuristicGreedyCover (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedyCover & operator=(const CbcHeuristicGreedyCover& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + if 100 added round up all >=0.5 + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } + +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + // original number of rows + int originalNumberRows_; + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + + +class CbcHeuristicGreedyEquality : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedyEquality (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedyEquality (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedyEquality ( const CbcHeuristicGreedyEquality &); + + // Destructor + ~CbcHeuristicGreedyEquality (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedyEquality & operator=(const CbcHeuristicGreedyEquality& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + if 100 added round up all >=0.5 + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Fraction of rhs to cover before branch and cut + inline void setFraction(double value) { + fraction_ = value; + } + inline double fraction() const { + return fraction_; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + // Fraction of rhs to cover before branch and cut + double fraction_; + // original number of rows + int originalNumberRows_; + /* Algorithm + 0 - use current upper bounds + 1 - use original upper bounds + If 10 added perturb ratios more + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + +/** Greedy heuristic for SOS and L rows (and positive elements) + */ + +class CbcHeuristicGreedySOS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicGreedySOS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicGreedySOS (CbcModel & model); + + // Copy constructor + CbcHeuristicGreedySOS ( const CbcHeuristicGreedySOS &); + + // Destructor + ~CbcHeuristicGreedySOS (); + + /// Clone + virtual CbcHeuristic * clone() const; + /// Assignment operator + CbcHeuristicGreedySOS & operator=(const CbcHeuristicGreedySOS& rhs); + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Validate model i.e. sets when_ to 0 if necessary (may be NULL) + virtual void validate() ; + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /* Algorithm + Bits + 1 bit - use current model, otherwise original + 2 - use current solution as starting point, otherwise pure greedy + 4 - as 2 but use merit not merit/size + 8 - use duals to modify greedy + 16 - use duals on GUB/SOS in special way + */ + inline int algorithm() const { + return algorithm_; + } + inline void setAlgorithm(int value) { + algorithm_ = value; + } + // Only do this many times + inline int numberTimes() const { + return numberTimes_; + } + inline void setNumberTimes(int value) { + numberTimes_ = value; + } + +protected: + /// Guts of constructor from a CbcModel + void gutsOfConstructor(CbcModel * model); + // Data + + // Original RHS - if -1.0 then SOS otherwise <= value + double * originalRhs_; + // Original matrix by column + CoinPackedMatrix matrix_; + // original number of rows + int originalNumberRows_; + /* Algorithm + */ + int algorithm_; + /// Do this many times + int numberTimes_; + +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicLocal.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicLocal.hpp new file mode 100644 index 0000000..baed8d5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicLocal.hpp @@ -0,0 +1,271 @@ +/* $Id: CbcHeuristicLocal.hpp 1943 2013-07-21 09:05:45Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicLocal_H +#define CbcHeuristicLocal_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicLocal : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicLocal (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicLocal (CbcModel & model); + + // Copy constructor + CbcHeuristicLocal ( const CbcHeuristicLocal &); + + // Destructor + ~CbcHeuristicLocal (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicLocal & operator=(const CbcHeuristicLocal& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This is called after cuts have been added - so can not add cuts + First tries setting a variable to better value. If feasible then + tries setting others. If not feasible then tries swaps + + ******** + + This first version does not do LP's and does swaps of two integer + variables. Later versions could do Lps. + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets type of search + inline void setSearchType(int value) { + swap_ = value; + } + /// Used array so we can set + inline int * used() const { + return used_; + } + +protected: + // Data + + // Original matrix by column + CoinPackedMatrix matrix_; + + // Number of solutions so we only do after new solution + int numberSolutions_; + // Type of search 0=normal, 1=BAB + int swap_; + /// Whether a variable has been in a solution (also when) + int * used_; +}; + +/** Proximity Search class + */ +class CbcHeuristicFPump; +class CbcHeuristicProximity : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicProximity (); + + /* Constructor with model - assumed before cuts + */ + CbcHeuristicProximity (CbcModel & model); + + // Copy constructor + CbcHeuristicProximity ( const CbcHeuristicProximity &); + + // Destructor + ~CbcHeuristicProximity (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicProximity & operator=(const CbcHeuristicProximity& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Set extra increment + inline void setIncrement(double value) + { increment_ = value;} + /// Used array so we can set + inline int * used() const { + return used_; + } + +protected: + // Data + /// Increment to use if no change + double increment_; + /// Copy of Feasibility pump + CbcHeuristicFPump * feasibilityPump_; + /// Number of solutions so we only do after new solution + int numberSolutions_; + /// Whether a variable has been in a solution (also when) + int * used_; +}; + + +/** Naive class + a) Fix all ints as close to zero as possible + b) Fix all ints with nonzero costs and < large to zero + c) Put bounds round continuous and UIs and maximize + */ + +class CbcHeuristicNaive : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicNaive (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicNaive (CbcModel & model); + + // Copy constructor + CbcHeuristicNaive ( const CbcHeuristicNaive &); + + // Destructor + ~CbcHeuristicNaive (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicNaive & operator=(const CbcHeuristicNaive& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Sets large cost value + inline void setLargeValue(double value) { + large_ = value; + } + /// Gets large cost value + inline double largeValue() const { + return large_; + } + +protected: + /// Data + /// Large value + double large_; +}; + +/** Crossover Search class + */ + +class CbcHeuristicCrossover : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicCrossover (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicCrossover (CbcModel & model); + + // Copy constructor + CbcHeuristicCrossover ( const CbcHeuristicCrossover &); + + // Destructor + ~CbcHeuristicCrossover (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicCrossover & operator=(const CbcHeuristicCrossover& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Fix variables if agree in useNumber_ solutions + when_ 0 off, 1 only at new solutions, 2 also every now and then + add 10 to make only if agree at lower bound + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Sets number of solutions to use + inline void setNumberSolutions(int value) { + if (value > 0 && value <= 10) + useNumber_ = value; + } + +protected: + // Data + /// Attempts + std::vector <double> attempts_; + /// Random numbers to stop same search happening + double random_[10]; + /// Number of solutions so we only do after new solution + int numberSolutions_; + /// Number of solutions to use + int useNumber_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicPivotAndFix.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicPivotAndFix.hpp new file mode 100644 index 0000000..9a945f6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicPivotAndFix.hpp @@ -0,0 +1,58 @@ +/* $Id: CbcHeuristicPivotAndFix.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicPivotAndFix_H +#define CbcHeuristicPivotAndFix_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicPivotAndFix : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicPivotAndFix (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicPivotAndFix (CbcModel & model); + + // Copy constructor + CbcHeuristicPivotAndFix ( const CbcHeuristicPivotAndFix &); + + // Destructor + ~CbcHeuristicPivotAndFix (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicPivotAndFix & operator=(const CbcHeuristicPivotAndFix& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + needs comments + */ + virtual int solution(double & objectiveValue, + double * newSolution); + +protected: +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicRENS.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicRENS.hpp new file mode 100644 index 0000000..6cc96fa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicRENS.hpp @@ -0,0 +1,77 @@ +// $Id: CbcHeuristicRENS.hpp 2105 2015-01-05 13:11:11Z forrest $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicRENS_H +#define CbcHeuristicRENS_H + +#include "CbcHeuristic.hpp" + +/** LocalSearch class + */ + +class CbcHeuristicRENS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRENS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRENS (CbcModel & model); + + // Copy constructor + CbcHeuristicRENS ( const CbcHeuristicRENS &); + + // Destructor + ~CbcHeuristicRENS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicRENS & operator=(const CbcHeuristicRENS& rhs); + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Extension Neighborhood Search + Does not run if when_<2 and a solution exists + */ + virtual int solution(double & objectiveValue, + double * newSolution); + + /// Set type + inline void setRensType(int value) + { rensType_ = value;} + +protected: + // Data + /// Number of tries + int numberTries_; + /** Type + 0 - fix at LB + 1 - fix on dj + 2 - fix at UB as well + 3 - fix on 0.01*average dj + add 16 to allow two tries + 32 - if solution exists use to keep more variables + 64 - if priorities keep high priority + 128 - if priorities keep low priority + */ + int rensType_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicRINS.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicRINS.hpp new file mode 100644 index 0000000..89281b5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicRINS.hpp @@ -0,0 +1,102 @@ +/* $Id: CbcHeuristicRINS.hpp 1956 2013-08-17 15:28:45Z forrest $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicRINS_H +#define CbcHeuristicRINS_H + +#include "CbcHeuristic.hpp" +// for backward compatibility include 3 other headers +#include "CbcHeuristicRENS.hpp" +#include "CbcHeuristicDINS.hpp" +#include "CbcHeuristicVND.hpp" +/** LocalSearch class + */ + +class CbcHeuristicRINS : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRINS (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRINS (CbcModel & model); + + // Copy constructor + CbcHeuristicRINS ( const CbcHeuristicRINS &); + + // Destructor + ~CbcHeuristicRINS (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicRINS & operator=(const CbcHeuristicRINS& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// Used array so we can set + inline char * used() const { + return used_; + } + /// Resets lastNode + inline void setLastNode(int value) { + lastNode_ = value; + } + /// Resets number of solutions + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /** State of fixing continuous variables - + 0 - not tried + +n - this divisor makes small enough + -n - this divisor still not small enough + */ + int stateOfFixing_; + /// Node when last done + int lastNode_; + /// Whether a variable has been in a solution + char * used_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicRandRound.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicRandRound.hpp new file mode 100644 index 0000000..dd1eedb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicRandRound.hpp @@ -0,0 +1,58 @@ +/* $Id: CbcHeuristicRandRound.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcHeuristicRandRound_H +#define CbcHeuristicRandRound_H + +#include "CbcHeuristic.hpp" +/** LocalSearch class + */ + +class CbcHeuristicRandRound : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicRandRound (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicRandRound (CbcModel & model); + + // Copy constructor + CbcHeuristicRandRound ( const CbcHeuristicRandRound &); + + // Destructor + ~CbcHeuristicRandRound (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// Assignment operator + CbcHeuristicRandRound & operator=(const CbcHeuristicRandRound& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + needs comments + */ + virtual int solution(double & objectiveValue, + double * newSolution); + +protected: +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcHeuristicVND.hpp b/thirdparty/linux/include/coin/coin/CbcHeuristicVND.hpp new file mode 100644 index 0000000..a245ab0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcHeuristicVND.hpp @@ -0,0 +1,94 @@ +// $Id: CbcHeuristicVND.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// edwin 12/5/09 carved out of CbcHeuristicRINS + +#ifndef CbcHeuristicVND_H +#define CbcHeuristicVND_H + +#include "CbcHeuristic.hpp" + + +/** LocalSearch class + */ + +class CbcHeuristicVND : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicVND (); + + /* Constructor with model - assumed before cuts + Initial version does not do Lps + */ + CbcHeuristicVND (CbcModel & model); + + // Copy constructor + CbcHeuristicVND ( const CbcHeuristicVND &); + + // Destructor + ~CbcHeuristicVND (); + + /// Clone + virtual CbcHeuristic * clone() const; + + + /// Assignment operator + CbcHeuristicVND & operator=(const CbcHeuristicVND& rhs); + + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + + /// update model (This is needed if cliques update matrix etc) + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + This does Relaxation Induced Neighborhood Search + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// This version fixes stuff and does IP + int solutionFix(double & objectiveValue, + double * newSolution, + const int * keep); + + /// Sets how often to do it + inline void setHowOften(int value) { + howOften_ = value; + } + /// base solution array so we can set + inline double * baseSolution() const { + return baseSolution_; + } + +protected: + // Data + + /// Number of solutions so we can do something at solution + int numberSolutions_; + /// How often to do (code can change) + int howOften_; + /// Number of successes + int numberSuccesses_; + /// Number of tries + int numberTries_; + /// Node when last done + int lastNode_; + /// Step size for decomposition + int stepSize_; + int k_; + int kmax_; + int nDifferent_; + /// Base solution + double * baseSolution_; +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcLinked.hpp b/thirdparty/linux/include/coin/coin/CbcLinked.hpp new file mode 100644 index 0000000..daa977c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcLinked.hpp @@ -0,0 +1,1406 @@ +/* $Id: CbcLinked.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglLinked_H +#define CglLinked_H +/* THIS CONTAINS STUFF THAT SHOULD BE IN + OsiSolverLink + OsiBranchLink + CglTemporary +*/ +#include "CoinModel.hpp" +#include "OsiClpSolverInterface.hpp" +#include "OsiChooseVariable.hpp" +#include "CbcFathom.hpp" +class CbcModel; +class CoinPackedMatrix; +class OsiLinkedBound; +class OsiObject; +class CglStored; +class CglTemporary; +/** + +This is to allow the user to replace initialSolve and resolve +This version changes coefficients +*/ + +class OsiSolverLink : public CbcOsiSolver { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /** + Problem specific + Returns -1 if node fathomed and no solution + 0 if did nothing + 1 if node fathomed and solution + allFixed is true if all LinkedBound variables are fixed + */ + virtual int fathom(bool allFixed) ; + /** Solves nonlinear problem from CoinModel using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + Returns solution array + */ + double * nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solve linearized quadratic objective branch and bound. + Return cutoff and OA cut + */ + double linearizedBAB(CglStored * cut) ; + /** Solves nonlinear problem from CoinModel using SLP - and then tries to get + heuristic solution + Returns solution array + mode - + 0 just get continuous + 1 round and try normal bab + 2 use defaultBound_ to bound integer variables near current solution + */ + double * heuristicSolution(int numberPasses, double deltaTolerance, int mode); + + /// Do OA cuts + int doAOCuts(CglTemporary * cutGen, const double * solution, const double * solution2); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLink (); + + /** This creates from a coinModel object + + if errors.then number of sets is -1 + + This creates linked ordered sets information. It assumes - + + for product terms syntax is yy*f(zz) + also just f(zz) is allowed + and even a constant + + modelObject not const as may be changed as part of process. + */ + OsiSolverLink( CoinModel & modelObject); + // Other way with existing object + void load( CoinModel & modelObject, bool tightenBounds = false, int logLevel = 1); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLink (const OsiSolverLink &); + + /// Assignment operator + OsiSolverLink & operator=(const OsiSolverLink& rhs); + + /// Destructor + virtual ~OsiSolverLink (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, int whichVariableAffected, + double multiplier = 1.0); + /// Update coefficients - returns number updated if in updating mode + int updateCoefficients(ClpSimplex * solver, CoinPackedMatrix * matrix); + /// Analyze constraints to see which are convex (quadratic) + void analyzeObjects(); + /// Add reformulated bilinear constraints + void addTighterConstraints(); + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Set objective value of best solution found internally + inline void setBestObjectiveValue(double value) { + bestObjectiveValue_ = value; + } + /// Best solution found internally + inline const double * bestSolution() const { + return bestSolution_; + } + /// Set best solution found internally + void setBestSolution(const double * solution, int numberColumns); + /// Set special options + inline void setSpecialOptions2(int value) { + specialOptions2_ = value; + } + /// Say convex (should work it out) - if convex false then strictly concave + void sayConvex(bool convex); + /// Get special options + inline int specialOptions2() const { + return specialOptions2_; + } + /** Clean copy of matrix + So we can add rows + */ + CoinPackedMatrix * cleanMatrix() const { + return matrix_; + } + /** Row copy of matrix + Just genuine columns and rows + Linear part + */ + CoinPackedMatrix * originalRowCopy() const { + return originalRowCopy_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + /// Gets correct form for a quadratic row - user to delete + CoinPackedMatrix * quadraticRow(int rowNumber, double * linear) const; + /// Default meshSize + inline double defaultMeshSize() const { + return defaultMeshSize_; + } + inline void setDefaultMeshSize(double value) { + defaultMeshSize_ = value; + } + /// Default maximumbound + inline double defaultBound() const { + return defaultBound_; + } + inline void setDefaultBound(double value) { + defaultBound_ = value; + } + /// Set integer priority + inline void setIntegerPriority(int value) { + integerPriority_ = value; + } + /// Get integer priority + inline int integerPriority() const { + return integerPriority_; + } + /// Objective transfer variable if one + inline int objectiveVariable() const { + return objectiveVariable_; + } + /// Set biLinear priority + inline void setBiLinearPriority(int value) { + biLinearPriority_ = value; + } + /// Get biLinear priority + inline int biLinearPriority() const { + return biLinearPriority_; + } + /// Return CoinModel + inline const CoinModel * coinModel() const { + return &coinModel_; + } + /// Set all biLinear priorities on x-x variables + void setBiLinearPriorities(int value, double meshSize = 1.0); + /** Set options and priority on all or some biLinear variables + 1 - on I-I + 2 - on I-x + 4 - on x-x + or combinations. + -1 means leave (for priority value and strategy value) + */ + void setBranchingStrategyOnVariables(int strategyValue, int priorityValue = -1, + int mode = 7); + /// Set all mesh sizes on x-x variables + void setMeshSizes(double value); + /** Two tier integer problem where when set of variables with priority + less than this are fixed the problem becomes an easier integer problem + */ + void setFixedPriority(int priorityValue); + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + /// Do real work of initialize + //void initialize(ClpSimplex * & solver, OsiObject ** & object) const; + /// Do real work of delete + void gutsOfDestructor(bool justNullify = false); + /// Do real work of copy + void gutsOfCopy(const OsiSolverLink & rhs) ; + //@} + + /**@name Private member data */ + //@{ + /** Clean copy of matrix + Marked coefficients will be multiplied by L or U + */ + CoinPackedMatrix * matrix_; + /** Row copy of matrix + Just genuine columns and rows + */ + CoinPackedMatrix * originalRowCopy_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Number of rows with nonLinearities + int numberNonLinearRows_; + /// Starts of lists + int * startNonLinear_; + /// Row number for a list + int * rowNonLinear_; + /** Indicator whether is convex, concave or neither + -1 concave, 0 neither, +1 convex + */ + int * convex_; + /// Indices in a list/row + int * whichNonLinear_; + /// Model in CoinModel format + CoinModel coinModel_; + /// Number of variables in tightening phase + int numberVariables_; + /// Information + OsiLinkedBound * info_; + /** + 0 bit (1) - call fathom (may do mini B&B) + 1 bit (2) - quadratic only in objective (add OA cuts) + 2 bit (4) - convex + 3 bit (8) - try adding OA cuts + 4 bit (16) - add linearized constraints + */ + int specialOptions2_; + /// Objective transfer row if one + int objectiveRow_; + /// Objective transfer variable if one + int objectiveVariable_; + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Default mesh + double defaultMeshSize_; + /// Default maximum bound + double defaultBound_; + /// Best solution found internally + double * bestSolution_; + /// Priority for integers + int integerPriority_; + /// Priority for bilinear + int biLinearPriority_; + /// Number of variables which when fixed help + int numberFix_; + /// list of fixed variables + int * fixVariables_; + //@} +}; +/** + List of bounds which depend on other bounds +*/ + +class OsiLinkedBound { + +public: + //--------------------------------------------------------------------------- + /**@name Action methods */ + //@{ + /// Update other bounds + void updateBounds(ClpSimplex * solver); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiLinkedBound (); + /// Useful Constructor + OsiLinkedBound(OsiSolverInterface * model, int variable, + int numberAffected, const int * positionL, + const int * positionU, const double * multiplier); + + /// Copy constructor + OsiLinkedBound (const OsiLinkedBound &); + + /// Assignment operator + OsiLinkedBound & operator=(const OsiLinkedBound& rhs); + + /// Destructor + ~OsiLinkedBound (); + + //@} + + /**@name Sets and Gets */ + //@{ + /// Get variable + inline int variable() const { + return variable_; + } + /// Add a bound modifier + void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, + double multiplier = 1.0); + //@} + +private: + typedef struct { + double multiplier; // to use in computation + int affected; // variable or element affected + /* + 0 - LB of variable affected + 1 - UB of variable affected + 2 - element in position (affected) affected + */ + unsigned char affect; + unsigned char ubUsed; // nonzero if UB of this variable is used + /* + 0 - use x*multiplier + 1 - use multiplier/x + 2 - if UB use min of current upper and x*multiplier, if LB use max of current lower and x*multiplier + */ + unsigned char type; // type of computation + } boundElementAction; + + /**@name Private member data */ + //@{ + /// Pointer back to model + OsiSolverInterface * model_; + /// Variable + int variable_; + /// Number of variables/elements affected + int numberAffected_; + /// Maximum number of variables/elements affected + int maximumAffected_; + /// Actions + boundElementAction * affected_; + //@} +}; +#include "CbcHeuristic.hpp" +/** heuristic - just picks up any good solution + */ + +class CbcHeuristicDynamic3 : public CbcHeuristic { +public: + + // Default Constructor + CbcHeuristicDynamic3 (); + + /* Constructor with model + */ + CbcHeuristicDynamic3 (CbcModel & model); + + // Copy constructor + CbcHeuristicDynamic3 ( const CbcHeuristicDynamic3 &); + + // Destructor + ~CbcHeuristicDynamic3 (); + + /// Clone + virtual CbcHeuristic * clone() const; + + /// update model + virtual void setModel(CbcModel * model); + + using CbcHeuristic::solution ; + /** returns 0 if no solution, 1 if valid solution. + Sets solution values if good, sets objective value (only if good) + We leave all variables which are at one at this node of the + tree to that value and will + initially set all others to zero. We then sort all variables in order of their cost + divided by the number of entries in rows which are not yet covered. We randomize that + value a bit so that ties will be broken in different ways on different runs of the heuristic. + We then choose the best one and set it to one and repeat the exercise. + + */ + virtual int solution(double & objectiveValue, + double * newSolution); + /// Resets stuff if model changes + virtual void resetModel(CbcModel * model); + /// Returns true if can deal with "odd" problems e.g. sos type 2 + virtual bool canDealWithOdd() const { + return true; + } + +protected: +private: + /// Illegal Assignment operator + CbcHeuristicDynamic3 & operator=(const CbcHeuristicDynamic3& rhs); +}; + +#include "OsiBranchingObject.hpp" + +/** Define Special Linked Ordered Sets. + +*/ +class CoinWarmStartBasis; + +class OsiOldLink : public OsiSOS { + +public: + + // Default Constructor + OsiOldLink (); + + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables in matrix are the numberInSet*numberLink + starting at first. If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int first, + const double * weights, int setNumber); + /** Useful constructor - A valid solution is if all variables are zero + apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through + numberInSet-1. The length of weights array is numberInSet. + For this constructor the variables are given by list - grouped. + If weights null then 0,1,2.. + */ + OsiOldLink (const OsiSolverInterface * solver, int numberMembers, + int numberLinks, int typeSOS, const int * which, + const double * weights, int setNumber); + + // Copy constructor + OsiOldLink ( const OsiOldLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiOldLink & operator=( const OsiOldLink& rhs); + + // Destructor + virtual ~OsiOldLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + + /// Number of links + int numberLinks_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiOldLinkBranchingObject : public OsiSOSBranchingObject { + +public: + + // Default Constructor + OsiOldLinkBranchingObject (); + + // Useful constructor + OsiOldLinkBranchingObject (OsiSolverInterface * solver, const OsiOldLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiOldLinkBranchingObject ( const OsiOldLinkBranchingObject &); + + // Assignment operator + OsiOldLinkBranchingObject & operator=( const OsiOldLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiOldLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define data for one link + +*/ + + +class OsiOneLink { + +public: + + // Default Constructor + OsiOneLink (); + + /** Useful constructor - + + */ + OsiOneLink (const OsiSolverInterface * solver, int xRow, int xColumn, int xyRow, + const char * functionString); + + // Copy constructor + OsiOneLink ( const OsiOneLink &); + + // Assignment operator + OsiOneLink & operator=( const OsiOneLink& rhs); + + // Destructor + virtual ~OsiOneLink (); + + /// data + + /// Row which defines x (if -1 then no x) + int xRow_; + /// Column which defines x + int xColumn_; + /// Output row + int xyRow; + /// Function + std::string function_; +}; +/** Define Special Linked Ordered Sets. New style + + members and weights may be stored in SOS object + + This is for y and x*f(y) and z*g(y) etc + +*/ + + +class OsiLink : public OsiSOS { + +public: + + // Default Constructor + OsiLink (); + + /** Useful constructor - + + */ + OsiLink (const OsiSolverInterface * solver, int yRow, + int yColumn, double meshSize); + + // Copy constructor + OsiLink ( const OsiLink &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLink & operator=( const OsiLink& rhs); + + // Destructor + virtual ~OsiLink (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of links for each member + inline int numberLinks() const { + return numberLinks_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return false; + } + +private: + /// data + /// Current increment for y points + double meshSize_; + /// Links + OsiOneLink * data_; + /// Number of links + int numberLinks_; + /// Row which defines y + int yRow_; + /// Column which defines y + int yColumn_; +}; +/** Branching object for Linked ordered sets + + */ +class OsiLinkBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiLinkBranchingObject (); + + // Useful constructor + OsiLinkBranchingObject (OsiSolverInterface * solver, const OsiLink * originalObject, + int way, + double separator); + + // Copy constructor + OsiLinkBranchingObject ( const OsiLinkBranchingObject &); + + // Assignment operator + OsiLinkBranchingObject & operator=( const OsiLinkBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiLinkBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); +private: + /// data +}; +/** Define BiLinear objects + + This models x*y where one or both are integer + +*/ + + +class OsiBiLinear : public OsiObject2 { + +public: + + // Default Constructor + OsiBiLinear (); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const solver + */ + OsiBiLinear (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + /** Useful constructor - + This Adds in rows and variables to construct valid Linked Ordered Set + Adds extra constraints to match other x/y + So note not const model + */ + OsiBiLinear (CoinModel * coinModel, int xColumn, + int yColumn, int xyRow, double coefficient, + double xMesh, double yMesh, + int numberExistingObjects = 0, const OsiObject ** objects = NULL ); + + // Copy constructor + OsiBiLinear ( const OsiBiLinear &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinear & operator=( const OsiBiLinear& rhs); + + // Destructor + virtual ~OsiBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return false; + } + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const { + return (branchingStrategy_&4) != 0; + } + /// X column + inline int xColumn() const { + return xColumn_; + } + /// Y column + inline int yColumn() const { + return yColumn_; + } + /// X row + inline int xRow() const { + return xRow_; + } + /// Y row + inline int yRow() const { + return yRow_; + } + /// XY row + inline int xyRow() const { + return xyRow_; + } + /// Coefficient + inline double coefficient() const { + return coefficient_; + } + /// Set coefficient + inline void setCoefficient(double value) { + coefficient_ = value; + } + /// First lambda (of 4) + inline int firstLambda() const { + return firstLambda_; + } + /// X satisfied if less than this away from mesh + inline double xSatisfied() const { + return xSatisfied_; + } + inline void setXSatisfied(double value) { + xSatisfied_ = value; + } + /// Y satisfied if less than this away from mesh + inline double ySatisfied() const { + return ySatisfied_; + } + inline void setYSatisfied(double value) { + ySatisfied_ = value; + } + /// X other satisfied if less than this away from mesh + inline double xOtherSatisfied() const { + return xOtherSatisfied_; + } + inline void setXOtherSatisfied(double value) { + xOtherSatisfied_ = value; + } + /// Y other satisfied if less than this away from mesh + inline double yOtherSatisfied() const { + return yOtherSatisfied_; + } + inline void setYOtherSatisfied(double value) { + yOtherSatisfied_ = value; + } + /// X meshSize + inline double xMeshSize() const { + return xMeshSize_; + } + inline void setXMeshSize(double value) { + xMeshSize_ = value; + } + /// Y meshSize + inline double yMeshSize() const { + return yMeshSize_; + } + inline void setYMeshSize(double value) { + yMeshSize_ = value; + } + /// XY satisfied if two version differ by less than this + inline double xySatisfied() const { + return xySatisfied_; + } + inline void setXYSatisfied(double value) { + xySatisfied_ = value; + } + /// Set sizes and other stuff + void setMeshSizes(const OsiSolverInterface * solver, double x, double y); + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + inline int branchingStrategy() const { + return branchingStrategy_; + } + inline void setBranchingStrategy(int value) { + branchingStrategy_ = value; + } + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + inline int boundType() const { + return boundType_; + } + inline void setBoundType(int value) { + boundType_ = value; + } + /// Does work of branching + void newBounds(OsiSolverInterface * solver, int way, short xOrY, double separator) const; + /// Updates coefficients - returns number updated + int updateCoefficients(const double * lower, const double * upper, double * objective, + CoinPackedMatrix * matrix, CoinWarmStartBasis * basis) const; + /// Returns true value of single xyRow coefficient + double xyCoefficient(const double * solution) const; + /// Get LU coefficients from matrix + void getCoefficients(const OsiSolverInterface * solver, double xB[2], double yB[2], double xybar[4]) const; + /// Compute lambdas (third entry in each .B is current value) (nonzero if bad) + double computeLambdas(const double xB[3], const double yB[3], const double xybar[4], double lambda[4]) const; + /// Adds in data for extra row with variable coefficients + void addExtraRow(int row, double multiplier); + /// Sets infeasibility and other when pseudo shadow prices + void getPseudoShadow(const OsiBranchingInformation * info); + /// Gets sum of movements to correct value + double getMovement(const OsiBranchingInformation * info); + +protected: + /// Compute lambdas if coefficients not changing + void computeLambdas(const OsiSolverInterface * solver, double lambda[4]) const; + /// data + + /// Coefficient + double coefficient_; + /// x mesh + double xMeshSize_; + /// y mesh + double yMeshSize_; + /// x satisfied if less than this away from mesh + double xSatisfied_; + /// y satisfied if less than this away from mesh + double ySatisfied_; + /// X other satisfied if less than this away from mesh + double xOtherSatisfied_; + /// Y other satisfied if less than this away from mesh + double yOtherSatisfied_; + /// xy satisfied if less than this away from true + double xySatisfied_; + /// value of x or y to branch about + mutable double xyBranchValue_; + /// x column + int xColumn_; + /// y column + int yColumn_; + /// First lambda (of 4) + int firstLambda_; + /** branching strategy etc + bottom 2 bits + 0 branch on either, 1 branch on x, 2 branch on y + next bit + 4 set to say don't update coefficients + next bit + 8 set to say don't use in feasible region + next bit + 16 set to say - Always satisfied !! + */ + int branchingStrategy_; + /** Simple quadratic bound marker. + 0 no + 1 L if coefficient pos, G if negative i.e. value is ub on xy + 2 G if coefficient pos, L if negative i.e. value is lb on xy + 3 E + If bound then real coefficient is 1.0 and coefficient_ is bound + */ + int boundType_; + /// x row + int xRow_; + /// y row (-1 if x*x) + int yRow_; + /// Output row + int xyRow_; + /// Convexity row + int convexity_; + /// Number of extra rows (coefficients to be modified) + int numberExtraRows_; + /// Multiplier for coefficient on row + double * multiplier_; + /// Row number + int * extraRow_; + /// Which chosen -1 none, 0 x, 1 y + mutable short chosen_; +}; +/** Branching object for BiLinear objects + + */ +class OsiBiLinearBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiBiLinearBranchingObject (); + + // Useful constructor + OsiBiLinearBranchingObject (OsiSolverInterface * solver, const OsiBiLinear * originalObject, + int way, + double separator, int chosen); + + // Copy constructor + OsiBiLinearBranchingObject ( const OsiBiLinearBranchingObject &); + + // Assignment operator + OsiBiLinearBranchingObject & operator=( const OsiBiLinearBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiBiLinearBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver = NULL); + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const; +private: + /// data + /// 1 means branch on x, 2 branch on y + short chosen_; +}; +/** Define Continuous BiLinear objects for an == bound + + This models x*y = b where both are continuous + +*/ + + +class OsiBiLinearEquality : public OsiBiLinear { + +public: + + // Default Constructor + OsiBiLinearEquality (); + + /** Useful constructor - + This Adds in rows and variables to construct Ordered Set + for x*y = b + So note not const solver + */ + OsiBiLinearEquality (OsiSolverInterface * solver, int xColumn, + int yColumn, int xyRow, double rhs, + double xMesh); + + // Copy constructor + OsiBiLinearEquality ( const OsiBiLinearEquality &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiBiLinearEquality & operator=( const OsiBiLinearEquality& rhs); + + // Destructor + virtual ~OsiBiLinearEquality (); + + /// Possible improvement + virtual double improvement(const OsiSolverInterface * solver) const; + /** change grid + if type 0 then use solution and make finer + if 1 then back to original + returns mesh size + */ + double newGrid(OsiSolverInterface * solver, int type) const; + /// Number of points + inline int numberPoints() const { + return numberPoints_; + } + inline void setNumberPoints(int value) { + numberPoints_ = value; + } + +private: + /// Number of points + int numberPoints_; +}; +/// Define a single integer class - but one where you keep branching until fixed even if satisfied + + +class OsiSimpleFixedInteger : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiSimpleFixedInteger (); + + /// Useful constructor - passed solver index + OsiSimpleFixedInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleFixedInteger (int iColumn, double lower, double upper); + + /// Useful constructor - passed simple integer + OsiSimpleFixedInteger (const OsiSimpleInteger &); + + /// Copy constructor + OsiSimpleFixedInteger ( const OsiSimpleFixedInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleFixedInteger & operator=( const OsiSimpleFixedInteger& rhs); + + /// Destructor + virtual ~OsiSimpleFixedInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; +protected: + /// data + +}; +/** Define a single variable class which is involved with OsiBiLinear objects. + This is used so can make better decision on where to branch as it can look at + all objects. + + This version sees if it can re-use code from OsiSimpleInteger + even if not an integer variable. If not then need to duplicate code. +*/ + + +class OsiUsesBiLinear : public OsiSimpleInteger { + +public: + + /// Default Constructor + OsiUsesBiLinear (); + + /// Useful constructor - passed solver index + OsiUsesBiLinear (const OsiSolverInterface * solver, int iColumn, int type); + + /// Useful constructor - passed solver index and original bounds + OsiUsesBiLinear (int iColumn, double lower, double upper, int type); + + /// Useful constructor - passed simple integer + OsiUsesBiLinear (const OsiSimpleInteger & rhs, int type); + + /// Copy constructor + OsiUsesBiLinear ( const OsiUsesBiLinear & rhs); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiUsesBiLinear & operator=( const OsiUsesBiLinear& rhs); + + /// Destructor + virtual ~OsiUsesBiLinear (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current value. + + Given an current value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /// Add all bi-linear objects + void addBiLinearObjects(OsiSolverLink * solver); +protected: + /// data + /// Number of bilinear objects (maybe could be more general) + int numberBiLinear_; + /// Type of variable - 0 continuous, 1 integer + int type_; + /// Objects + OsiObject ** objects_; +}; +/** This class chooses a variable to branch on + + This is just as OsiChooseStrong but it fakes it so only + first so many are looked at in this phase + +*/ + +class OsiChooseStrongSubset : public OsiChooseStrong { + +public: + + /// Default Constructor + OsiChooseStrongSubset (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrongSubset (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrongSubset (const OsiChooseStrongSubset &); + + /// Assignment operator + OsiChooseStrongSubset & operator= (const OsiChooseStrongSubset& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrongSubset (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /// Number of objects to use + inline int numberObjectsToUse() const { + return numberObjectsToUse_; + } + /// Set number of objects to use + inline void setNumberObjectsToUse(int value) { + numberObjectsToUse_ = value; + } + +protected: + // Data + /// Number of objects to be used (and set in solver) + int numberObjectsToUse_; +}; + +#include <string> + +#include "CglStored.hpp" + +class CoinWarmStartBasis; +/** Stored Temporary Cut Generator Class - destroyed after first use */ +class CglTemporary : public CglStored { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Stored cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + This generator just looks at previously stored cuts + and inserts any that are violated by enough + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglTemporary (); + + /// Copy constructor + CglTemporary (const CglTemporary & rhs); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglTemporary & + operator=(const CglTemporary& rhs); + + /// Destructor + virtual + ~CglTemporary (); + //@} + +private: + +// Private member methods + + // Private member data +}; +//############################################################################# + +/** + +This is to allow the user to replace initialSolve and resolve +*/ + +class OsiSolverLinearizedQuadratic : public OsiClpSolverInterface { + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiSolverLinearizedQuadratic (); + /// Useful constructor (solution should be good) + OsiSolverLinearizedQuadratic( ClpSimplex * quadraticModel); + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSolverLinearizedQuadratic (const OsiSolverLinearizedQuadratic &); + + /// Assignment operator + OsiSolverLinearizedQuadratic & operator=(const OsiSolverLinearizedQuadratic& rhs); + + /// Destructor + virtual ~OsiSolverLinearizedQuadratic (); + + //@} + + + /**@name Sets and Gets */ + //@{ + /// Objective value of best solution found internally + inline double bestObjectiveValue() const { + return bestObjectiveValue_; + } + /// Best solution found internally + const double * bestSolution() const { + return bestSolution_; + } + /// Set special options + inline void setSpecialOptions3(int value) { + specialOptions3_ = value; + } + /// Get special options + inline int specialOptions3() const { + return specialOptions3_; + } + /// Copy of quadratic model if one + ClpSimplex * quadraticModel() const { + return quadraticModel_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + + + /**@name functions */ + //@{ + + /**@name Private member data */ + //@{ + /// Objective value of best solution found internally + double bestObjectiveValue_; + /// Copy of quadratic model if one + ClpSimplex * quadraticModel_; + /// Best solution found internally + double * bestSolution_; + /** + 0 bit (1) - don't do mini B&B + 1 bit (2) - quadratic only in objective + */ + int specialOptions3_; + //@} +}; +class ClpSimplex; +/** Return an approximate solution to a CoinModel. + Lots of bounds may be odd to force a solution. + mode = 0 just tries to get a continuous solution +*/ +ClpSimplex * approximateSolution(CoinModel & coinModel, + int numberPasses, double deltaTolerance, + int mode = 0); +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcMessage.hpp b/thirdparty/linux/include/coin/coin/CbcMessage.hpp new file mode 100644 index 0000000..50690cf --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcMessage.hpp @@ -0,0 +1,94 @@ +/* $Id: CbcMessage.hpp 1791 2012-06-08 15:15:10Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcMessage_H +#define CbcMessage_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +/** This deals with Cbc messages (as against Clp messages etc). + CoinMessageHandler.hpp is the general part of message handling. + All it has are enum's for the various messages. + CbcMessage.cpp has text in various languages. + + It is trivial to use the .hpp and .cpp file as a basis for + messages for other components. + */ + +#include "CoinMessageHandler.hpp" +enum CBC_Message { + CBC_END_GOOD, + CBC_MAXNODES, + CBC_MAXTIME, + CBC_MAXSOLS, + CBC_EVENT, + CBC_MAXITERS, + CBC_SOLUTION, + CBC_END_SOLUTION, + CBC_SOLUTION2, + CBC_END, + CBC_INFEAS, + CBC_STRONG, + CBC_SOLINDIVIDUAL, + CBC_INTEGERINCREMENT, + CBC_STATUS, + CBC_GAP, + CBC_ROUNDING, + CBC_TREE_SOL, + CBC_ROOT, + CBC_GENERATOR, + CBC_BRANCH, + CBC_STRONGSOL, + CBC_NOINT, + CBC_VUB_PASS, + CBC_VUB_END, + CBC_NOTFEAS1, + CBC_NOTFEAS2, + CBC_NOTFEAS3, + CBC_CUTOFF_WARNING1, + CBC_ITERATE_STRONG, + CBC_PRIORITY, + CBC_WARNING_STRONG, + CBC_START_SUB, + CBC_END_SUB, + CBC_THREAD_STATS, + CBC_CUTS_STATS, + CBC_STRONG_STATS, + CBC_UNBOUNDED, + CBC_OTHER_STATS, + CBC_HEURISTICS_OFF, + CBC_STATUS2, + CBC_FPUMP1, + CBC_FPUMP2, + CBC_STATUS3, + CBC_OTHER_STATS2, + CBC_RELAXED1, + CBC_RELAXED2, + CBC_RESTART, + CBC_GENERAL, + CBC_ROOT_DETAIL, +#ifndef NO_FATHOM_PRINT + CBC_FATHOM_CHANGE, +#endif + CBC_DUMMY_END +}; + +class CbcMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + CbcMessage(Language language = us_en); + //@} + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcMipStartIO.hpp b/thirdparty/linux/include/coin/coin/CbcMipStartIO.hpp new file mode 100644 index 0000000..58e6c0a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcMipStartIO.hpp @@ -0,0 +1,26 @@ +#ifndef MIPSTARTIO_HPP_INCLUDED +#define MIPSTARTIO_HPP_INCLUDED + +#include <vector> +#include <string> +#include <utility> +class CbcModel; + +class OsiSolverInterface; + +/* tries to read mipstart (solution file) from + fileName, filling colValues and obj + returns 0 with success, + 1 otherwise */ +int readMIPStart( CbcModel * model, const char *fileName, + std::vector< std::pair< std::string, double > > &colValues, + double &solObj ); + +/* from a partial list of variables tries to fill the + remaining variable values */ +int computeCompleteSolution( CbcModel * model, + const std::vector< std::string > colNames, + const std::vector< std::pair< std::string, double > > &colValues, + double *sol, double &obj ); + +#endif // MIPSTARTIO_HPP_INCLUDED diff --git a/thirdparty/linux/include/coin/coin/CbcModel.hpp b/thirdparty/linux/include/coin/coin/CbcModel.hpp new file mode 100644 index 0000000..ceef661 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcModel.hpp @@ -0,0 +1,2952 @@ +/* $Id: CbcModel.hpp 2206 2015-07-07 20:44:40Z stefan $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcModel_H +#define CbcModel_H +#include <string> +#include <vector> +#include "CoinMessageHandler.hpp" +#include "OsiSolverInterface.hpp" +#include "OsiBranchingObject.hpp" +#include "OsiCuts.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CbcCompareBase.hpp" +#include "CbcCountRowCut.hpp" +#include "CbcMessage.hpp" +#include "CbcEventHandler.hpp" +#include "ClpDualRowPivot.hpp" + + +class CbcCutGenerator; +class CbcBaseModel; +class OsiRowCut; +class OsiBabSolver; +class OsiRowCutDebugger; +class CglCutGenerator; +class CglStored; +class CbcCutModifier; +class CglTreeProbingInfo; +class CbcHeuristic; +class OsiObject; +class CbcThread; +class CbcTree; +class CbcStrategy; +class CbcSymmetry; +class CbcFeasibilityBase; +class CbcStatistics; +class CbcFullNodeInfo; +class CbcEventHandler ; +class CglPreProcess; +class OsiClpSolverInterface; +class ClpNodeStuff; + +// #define CBC_CHECK_BASIS 1 + +//############################################################################# + +/** Simple Branch and bound class + + The initialSolve() method solves the initial LP relaxation of the MIP + problem. The branchAndBound() method can then be called to finish using + a branch and cut algorithm. + + <h3>Search Tree Traversal</h3> + + Subproblems (aka nodes) requiring additional evaluation are stored using + the CbcNode and CbcNodeInfo objects. Ancestry linkage is maintained in the + CbcNodeInfo object. Evaluation of a subproblem within branchAndBound() + proceeds as follows: + <ul> + <li> The node representing the most promising parent subproblem is popped + from the heap which holds the set of subproblems requiring further + evaluation. + <li> Using branching instructions stored in the node, and information in + its ancestors, the model and solver are adjusted to create the + active subproblem. + <li> If the parent subproblem will require further evaluation + (<i>i.e.</i>, there are branches remaining) its node is pushed back + on the heap. Otherwise, the node is deleted. This may trigger + recursive deletion of ancestors. + <li> The newly created subproblem is evaluated. + <li> If the subproblem requires further evaluation, a node is created. + All information needed to recreate the subproblem (branching + information, row and column cuts) is placed in the node and the node + is added to the set of subproblems awaiting further evaluation. + </ul> + Note that there is never a node representing the active subproblem; the model + and solver represent the active subproblem. + + <h3>Row (Constraint) Cut Handling</h3> + + For a typical subproblem, the sequence of events is as follows: + <ul> + <li> The subproblem is rebuilt for further evaluation: One result of a + call to addCuts() is a traversal of ancestors, leaving a list of all + cuts used in the ancestors in #addedCuts_. This list is then scanned + to construct a basis that includes only tight cuts. Entries for + loose cuts are set to NULL. + <li> The subproblem is evaluated: One result of a call to solveWithCuts() + is the return of a set of newly generated cuts for the subproblem. + #addedCuts_ is also kept up-to-date as old cuts become loose. + <li> The subproblem is stored for further processing: A call to + CbcNodeInfo::addCuts() adds the newly generated cuts to the + CbcNodeInfo object associated with this node. + </ul> + See CbcCountRowCut for details of the bookkeeping associated with cut + management. +*/ + +class CbcModel { + +public: + + enum CbcIntParam { + /** The maximum number of nodes before terminating */ + CbcMaxNumNode = 0, + /** The maximum number of solutions before terminating */ + CbcMaxNumSol, + /** Fathoming discipline + + Controls objective function comparisons for purposes of fathoming by bound + or determining monotonic variables. + + If 1, action is taken only when the current objective is strictly worse + than the target. Implementation is handled by adding a small tolerance to + the target. + */ + CbcFathomDiscipline, + /** Adjusts printout + 1 does different node message with number unsatisfied on last branch + */ + CbcPrinting, + /** Number of branches (may be more than number of nodes as may + include strong branching) */ + CbcNumberBranches, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastIntParam + }; + + enum CbcDblParam { + /** The maximum amount the value of an integer variable can vary from + integer and still be considered feasible. */ + CbcIntegerTolerance = 0, + /** The objective is assumed to worsen by this amount for each + integer infeasibility. */ + CbcInfeasibilityWeight, + /** The amount by which to tighten the objective function cutoff when + a new solution is discovered. */ + CbcCutoffIncrement, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcAllowableGap, + /** Stop when the gap between the objective value of the best known solution + and the best bound on the objective of any solution is less than this + fraction of of the absolute value of best known solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcAllowableFractionGap, + /** \brief The maximum number of seconds before terminating. + A double should be adequate! */ + CbcMaximumSeconds, + /// Cutoff - stored for speed + CbcCurrentCutoff, + /// Optimization direction - stored for speed + CbcOptimizationDirection, + /// Current objective value + CbcCurrentObjectiveValue, + /// Current minimization objective value + CbcCurrentMinimizationObjectiveValue, + /** \brief The time at start of model. + So that other pieces of code can access */ + CbcStartSeconds, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this. + + This is an absolute value. Conversion from a percentage is left to the + client. + */ + CbcHeuristicGap, + /** Stop doing heuristics when the gap between the objective value of the + best known solution and the best bound on the objective of any solution + is less than this fraction of of the absolute value of best known + solution. + + Code stops if either this test or CbcAllowableGap test succeeds + */ + CbcHeuristicFractionGap, + /// Smallest non-zero change on a branch + CbcSmallestChange, + /// Sum of non-zero changes on a branch + CbcSumChange, + /// Largest non-zero change on a branch + CbcLargestChange, + /// Small non-zero change on a branch to be used as guess + CbcSmallChange, + /** Just a marker, so that a static sized array can store parameters. */ + CbcLastDblParam + }; + + //--------------------------------------------------------------------------- + +public: + ///@name Solve methods + //@{ + /** \brief Solve the initial LP relaxation + + Invoke the solver's %initialSolve() method. + */ + void initialSolve(); + + /** \brief Invoke the branch \& cut algorithm + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node, then proceeds to explore the + branch & cut search tree. The search ends when the tree is exhausted or + one of several execution limits is reached. + If doStatistics is 1 summary statistics are printed + if 2 then also the path to best solution (if found by branching) + if 3 then also one line per node + */ + void branchAndBound(int doStatistics = 0); +private: + + /** \brief Evaluate a subproblem using cutting planes and heuristics + + The method invokes a main loop which generates cuts, applies heuristics, + and reoptimises using the solver's native %resolve() method. + It returns true if the subproblem remains feasible at the end of the + evaluation. + */ + bool solveWithCuts(OsiCuts & cuts, int numberTries, CbcNode * node); + /** Generate one round of cuts - serial mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int serialCuts(OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Generate one round of cuts - parallel mode + returns - + 0 - normal + 1 - must keep going + 2 - set numberTries to zero + -1 - infeasible + */ + int parallelCuts(CbcBaseModel * master, OsiCuts & cuts, CbcNode * node, OsiCuts & slackCuts, int lastNumberCuts); + /** Input one node output N nodes to put on tree and optional solution update + This should be able to operate in parallel so is given a solver and is const(ish) + However we will need to keep an array of solver_ and bases and more + status is 0 for normal, 1 if solution + Calling code should always push nodes back on tree + */ + CbcNode ** solveOneNode(int whichSolver, CbcNode * node, + int & numberNodesOutput, int & status) ; + /// Update size of whichGenerator + void resizeWhichGenerator(int numberNow, int numberAfter); +public: +#ifdef CBC_KEEP_DEPRECATED + // See if anyone is using these any more!! + /** \brief create a clean model from partially fixed problem + + The method creates a new model with given bounds and with no tree. + */ + CbcModel * cleanModel(const double * lower, const double * upper); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method presolves the given model and does branch and cut. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + Normally okay to do cleanModel immediately followed by subBranchandBound + (== other form of subBranchAndBound) + but may need to get at model for advanced features. + + Deletes model2 + */ + int subBranchAndBound(CbcModel * model2, + CbcModel * presolvedModel, + int maximumNodes); + /** \brief Invoke the branch \& cut algorithm on partially fixed problem + + The method creates a new model with given bounds, presolves it + then proceeds to explore the branch & cut search tree. The search + ends when the tree is exhausted or maximum nodes is reached. + + If better solution found then it is saved. + + Returns 0 if search completed and solution, 1 if not completed and solution, + 2 if completed and no solution, 3 if not completed and no solution. + + This is just subModel immediately followed by other version of + subBranchandBound. + + */ + int subBranchAndBound(const double * lower, const double * upper, + int maximumNodes); + + /** \brief Process root node and return a strengthened model + + The method assumes that initialSolve() has been called to solve the + LP relaxation. It processes the root node and then returns a pointer + to the strengthened model (or NULL if infeasible) + */ + OsiSolverInterface * strengthenedModel(); + /** preProcess problem - replacing solver + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + If makeEquality is 1 add slacks to get cliques, + if 2 add slacks to get sos (but only if looks plausible) and keep sos info + */ + CglPreProcess * preProcess( int makeEquality = 0, int numberPasses = 5, + int tuning = 5); + /** Does postprocessing - original solver back. + User has to delete process */ + void postProcess(CglPreProcess * process); +#endif + /// Adds an update information object + void addUpdateInformation(const CbcObjectUpdateData & data); + /** Do one node - broken out for clarity? + also for parallel (when baseModel!=this) + Returns 1 if solution found + node NULL on return if no branches left + newNode NULL if no new node created + */ + int doOneNode(CbcModel * baseModel, CbcNode * & node, CbcNode * & newNode); + +public: + /** \brief Reoptimise an LP relaxation + + Invoke the solver's %resolve() method. + whereFrom - + 0 - initial continuous + 1 - resolve on branch (before new cuts) + 2 - after new cuts + 3 - obsolete code or something modified problem in unexpected way + 10 - after strong branching has fixed variables at root + 11 - after strong branching has fixed variables in tree + + returns 1 feasible, 0 infeasible, -1 feasible but skip cuts + */ + int resolve(CbcNodeInfo * parent, int whereFrom, + double * saveSolution = NULL, + double * saveLower = NULL, + double * saveUpper = NULL); + /// Make given rows (L or G) into global cuts and remove from lp + void makeGlobalCuts(int numberRows, const int * which); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut * cut); + /// Make given cut into a global cut + int makeGlobalCut(const OsiRowCut & cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut * cut); + /// Make given column cut into a global cut + void makeGlobalCut(const OsiColCut & cut); + /// Make partial cut into a global cut and save + void makePartialCut(const OsiRowCut * cut, const OsiSolverInterface * solver=NULL); + /// Make partial cuts into global cuts + void makeGlobalCuts(); + /// Which cut generator generated this cut + inline const int * whichGenerator() const + { return whichGenerator_;} + //@} + + /** \name Presolve methods */ + //@{ + + /** Identify cliques and construct corresponding objects. + + Find cliques with size in the range + [\p atLeastThisMany, \p lessThanThis] and construct corresponding + CbcClique objects. + If \p makeEquality is true then a new model may be returned if + modifications had to be made, otherwise \c this is returned. + If the problem is infeasible #numberObjects_ is set to -1. + A client must use deleteObjects() before a second call to findCliques(). + If priorities exist, clique priority is set to the default. + */ + CbcModel * findCliques(bool makeEquality, int atLeastThisMany, + int lessThanThis, int defaultValue = 1000); + + /** Do integer presolve, creating a new (presolved) model. + + Returns the new model, or NULL if feasibility is lost. + If weak is true then just does a normal presolve + + \todo It remains to work out the cleanest way of getting a solution to + the original problem at the end. So this is very preliminary. + */ + CbcModel * integerPresolve(bool weak = false); + + /** Do integer presolve, modifying the current model. + + Returns true if the model remains feasible after presolve. + */ + bool integerPresolveThisModel(OsiSolverInterface * originalSolver, bool weak = false); + + + /// Put back information into the original model after integer presolve. + void originalModel(CbcModel * presolvedModel, bool weak); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + Returns false if feasibility is lost. + If CglProbing is available, it will be tried as well to see if it can + tighten bounds. + This routine is just a front end for tightenVubs(int,const int*,double). + + If <tt>type = -1</tt> all variables are processed (could be very slow). + If <tt>type = 0</tt> only variables involved in VUBs are processed. + If <tt>type = n > 0</tt>, only the n most expensive VUB variables + are processed, where it is assumed that x is at its maximum so delta + would have to go to 1 (if x not at bound). + + If \p allowMultipleBinary is true, then a VUB constraint is a row with + one continuous variable and any number of binary variables. + + If <tt>useCutoff < 1.0e30</tt>, the original objective is installed as a + constraint with \p useCutoff as a bound. + */ + bool tightenVubs(int type, bool allowMultipleBinary = false, + double useCutoff = 1.0e50); + + /** \brief For variables involved in VUB constraints, see if we can tighten + bounds by solving lp's + + This version is just handed a list of variables to be processed. + */ + bool tightenVubs(int numberVubs, const int * which, + double useCutoff = 1.0e50); + /** + Analyze problem to find a minimum change in the objective function. + */ + void analyzeObjective(); + + /** + Add additional integers. + */ + void AddIntegers(); + /** + Save copy of the model. + */ + void saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible); + /** + Flip direction of optimization on all models + */ + void flipModel(); + + //@} + + /** \name Object manipulation routines + + See OsiObject for an explanation of `object' in the context of CbcModel. + */ + //@{ + + /// Get the number of objects + inline int numberObjects() const { + return numberObjects_; + } + /// Set the number of objects + inline void setNumberObjects(int number) { + numberObjects_ = number; + } + + /// Get the array of objects + inline OsiObject ** objects() const { + return object_; + } + + /// Get the specified object + const inline OsiObject * object(int which) const { + return object_[which]; + } + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { + return object_[which]; + } + + void setOptionalInteger(int index); + + /// Delete all object information (and just back to integers if true) + void deleteObjects(bool findIntegers = true); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, CbcObject ** objects); + + /// Ensure attached objects point to this model. + void synchronizeModel() ; + + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an CbcSimpleInteger object for each + one. + If \p startAgain is true, a new scan is forced, overwriting any existing + integer variable information. + If type > 0 then 1==PseudoCost, 2 new ones low priority + */ + + void findIntegers(bool startAgain, int type = 0); + +#ifdef SWITCH_VARIABLES + /// Convert Dynamic to Switching + int findSwitching(); + /// Fix associated variables + int fixAssociated(OsiSolverInterface * solver,int cleanBasis); + /// Debug associated variables + int checkAssociated(const OsiSolverInterface * solver, + const double * solution, int printLevel); +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + /// Set an integer parameter + inline bool setIntParam(CbcIntParam key, int value) { + intParam_[key] = value; + return true; + } + /// Set a double parameter + inline bool setDblParam(CbcDblParam key, double value) { + dblParam_[key] = value; + return true; + } + /// Get an integer parameter + inline int getIntParam(CbcIntParam key) const { + return intParam_[key]; + } + /// Get a double parameter + inline double getDblParam(CbcDblParam key) const { + return dblParam_[key]; + } + /*! \brief Set cutoff bound on the objective function. + + When using strict comparison, the bound is adjusted by a tolerance to + avoid accidentally cutting off the optimal solution. + */ + void setCutoff(double value) ; + + /// Get the cutoff bound on the objective function - always as minimize + inline double getCutoff() const { //double value ; + //solver_->getDblParam(OsiDualObjectiveLimit,value) ; + //assert( dblParam_[CbcCurrentCutoff]== value * solver_->getObjSense()); + return dblParam_[CbcCurrentCutoff]; + } + + /// Set the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline bool setMaximumNodes( int value) { + return setIntParam(CbcMaxNumNode, value); + } + + /// Get the \link CbcModel::CbcMaxNumNode maximum node limit \endlink + inline int getMaximumNodes() const { + return getIntParam(CbcMaxNumNode); + } + + /** Set the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline bool setMaximumSolutions( int value) { + return setIntParam(CbcMaxNumSol, value); + } + /** Get the + \link CbcModel::CbcMaxNumSol maximum number of solutions \endlink + desired. + */ + inline int getMaximumSolutions() const { + return getIntParam(CbcMaxNumSol); + } + /// Set the printing mode + inline bool setPrintingMode( int value) { + return setIntParam(CbcPrinting, value); + } + + /// Get the printing mode + inline int getPrintingMode() const { + return getIntParam(CbcPrinting); + } + + /** Set the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline bool setMaximumSeconds( double value) { + return setDblParam(CbcMaximumSeconds, value); + } + /** Get the + \link CbcModel::CbcMaximumSeconds maximum number of seconds \endlink + desired. + */ + inline double getMaximumSeconds() const { + return getDblParam(CbcMaximumSeconds); + } + /// Current time since start of branchAndbound + double getCurrentSeconds() const ; + + /// Return true if maximum time reached + bool maximumSecondsReached() const ; + + /** Set the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline bool setIntegerTolerance( double value) { + return setDblParam(CbcIntegerTolerance, value); + } + /** Get the + \link CbcModel::CbcIntegerTolerance integrality tolerance \endlink + */ + inline double getIntegerTolerance() const { + return getDblParam(CbcIntegerTolerance); + } + + /** Set the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline bool setInfeasibilityWeight( double value) { + return setDblParam(CbcInfeasibilityWeight, value); + } + /** Get the + \link CbcModel::CbcInfeasibilityWeight + weight per integer infeasibility \endlink + */ + inline double getInfeasibilityWeight() const { + return getDblParam(CbcInfeasibilityWeight); + } + + /** Set the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableGap( double value) { + return setDblParam(CbcAllowableGap, value); + } + /** Get the \link CbcModel::CbcAllowableGap allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableGap() const { + return getDblParam(CbcAllowableGap); + } + + /** Set the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowableFractionGap( double value) { + return setDblParam(CbcAllowableFractionGap, value); + } + /** Get the \link CbcModel::CbcAllowableFractionGap fraction allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowableFractionGap() const { + return getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setAllowablePercentageGap( double value) { + return setDblParam(CbcAllowableFractionGap, value*0.01); + } + /** Get the \link CbcModel::CbcAllowableFractionGap percentage allowable gap \endlink + between the best known solution and the best possible solution. + */ + inline double getAllowablePercentageGap() const { + return 100.0*getDblParam(CbcAllowableFractionGap); + } + /** Set the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicGap( double value) { + return setDblParam(CbcHeuristicGap, value); + } + /** Get the \link CbcModel::CbcHeuristicGap heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicGap() const { + return getDblParam(CbcHeuristicGap); + } + + /** Set the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline bool setHeuristicFractionGap( double value) { + return setDblParam(CbcHeuristicFractionGap, value); + } + /** Get the \link CbcModel::CbcHeuristicFractionGap fraction heuristic gap \endlink + between the best known solution and the best possible solution. + */ + inline double getHeuristicFractionGap() const { + return getDblParam(CbcHeuristicFractionGap); + } + /** Set the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline bool setCutoffIncrement( double value) { + return setDblParam(CbcCutoffIncrement, value); + } + /** Get the + \link CbcModel::CbcCutoffIncrement \endlink + desired. + */ + inline double getCutoffIncrement() const { + return getDblParam(CbcCutoffIncrement); + } + /// See if can stop on gap + bool canStopOnGap() const; + + /** Pass in target solution and optional priorities. + If priorities then >0 means only branch if incorrect + while <0 means branch even if correct. +1 or -1 are + highest priority */ + void setHotstartSolution(const double * solution, const int * priorities = NULL) ; + + /// Set the minimum drop to continue cuts + inline void setMinimumDrop(double value) { + minimumDrop_ = value; + } + /// Get the minimum drop to continue cuts + inline double getMinimumDrop() const { + return minimumDrop_; + } + + /** Set the maximum number of cut passes at root node (default 20) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPassesAtRoot(int value) { + maximumCutPassesAtRoot_ = value; + } + /** Get the maximum number of cut passes at root node */ + inline int getMaximumCutPassesAtRoot() const { + return maximumCutPassesAtRoot_; + } + + /** Set the maximum number of cut passes at other nodes (default 10) + Minimum drop can also be used for fine tuning */ + inline void setMaximumCutPasses(int value) { + maximumCutPasses_ = value; + } + /** Get the maximum number of cut passes at other nodes (default 10) */ + inline int getMaximumCutPasses() const { + return maximumCutPasses_; + } + /** Get current cut pass number in this round of cuts. + (1 is first pass) */ + inline int getCurrentPassNumber() const { + return currentPassNumber_; + } + /** Set current cut pass number in this round of cuts. + (1 is first pass) */ + inline void setCurrentPassNumber(int value) { + currentPassNumber_ = value; + } + + /** Set the maximum number of candidates to be evaluated for strong + branching. + + A value of 0 disables strong branching. + */ + void setNumberStrong(int number); + /** Get the maximum number of candidates to be evaluated for strong + branching. + */ + inline int numberStrong() const { + return numberStrong_; + } + /** Set global preferred way to branch + -1 down, +1 up, 0 no preference */ + inline void setPreferredWay(int value) { + preferredWay_ = value; + } + /** Get the preferred way to branch (default 0) */ + inline int getPreferredWay() const { + return preferredWay_; + } + /// Get at which depths to do cuts + inline int whenCuts() const { + return whenCuts_; + } + /// Set at which depths to do cuts + inline void setWhenCuts(int value) { + whenCuts_ = value; + } + /** Return true if we want to do cuts + If allowForTopOfTree zero then just does on multiples of depth + if 1 then allows for doing at top of tree + if 2 then says if cuts allowed anywhere apart from root + */ + bool doCutsNow(int allowForTopOfTree) const; + + /** Set the number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 disables dynamic strong branching. + */ + void setNumberBeforeTrust(int number); + /** get the number of branches before pseudo costs believed + in dynamic strong branching. */ + inline int numberBeforeTrust() const { + return numberBeforeTrust_; + } + /** Set the number of variables for which to compute penalties + in dynamic strong branching. + + A value of 0 disables penalties. + */ + void setNumberPenalties(int number); + /** get the number of variables for which to compute penalties + in dynamic strong branching. */ + inline int numberPenalties() const { + return numberPenalties_; + } + /// Pointer to top of tree + inline const CbcFullNodeInfo * topOfTree() const + { return topOfTree_;} + /// Number of analyze iterations to do + inline void setNumberAnalyzeIterations(int number) { + numberAnalyzeIterations_ = number; + } + inline int numberAnalyzeIterations() const { + return numberAnalyzeIterations_; + } + /** Get scale factor to make penalties match strong. + Should/will be computed */ + inline double penaltyScaleFactor() const { + return penaltyScaleFactor_; + } + /** Set scale factor to make penalties match strong. + Should/will be computed */ + void setPenaltyScaleFactor(double value); + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + 4 - all +- 1 or all +1 and odd + */ + void inline setProblemType(int number) { + problemType_ = number; + } + inline int problemType() const { + return problemType_; + } + /// Current depth + inline int currentDepth() const { + return currentDepth_; + } + + /// Set how often to scan global cuts + void setHowOftenGlobalScan(int number); + /// Get how often to scan global cuts + inline int howOftenGlobalScan() const { + return howOftenGlobalScan_; + } + /// Original columns as created by integerPresolve or preprocessing + inline int * originalColumns() const { + return originalColumns_; + } + /// Set original columns as created by preprocessing + void setOriginalColumns(const int * originalColumns, + int numberGood=COIN_INT_MAX) ; + /// Create conflict cut (well - most of) + OsiRowCut * conflictCut(const OsiSolverInterface * solver, bool & localCuts); + + /** Set the print frequency. + + Controls the number of nodes evaluated between status prints. + If <tt>number <=0</tt> the print frequency is set to 100 nodes for large + problems, 1000 for small problems. + Print frequency has very slight overhead if small. + */ + inline void setPrintFrequency(int number) { + printFrequency_ = number; + } + /// Get the print frequency + inline int printFrequency() const { + return printFrequency_; + } + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + bool isAbandoned() const; + /// Is optimality proven? + bool isProvenOptimal() const; + /// Is infeasiblity proven (or none better than cutoff)? + bool isProvenInfeasible() const; + /// Was continuous solution unbounded + bool isContinuousUnbounded() const; + /// Was continuous solution unbounded + bool isProvenDualInfeasible() const; + /// Node limit reached? + bool isNodeLimitReached() const; + /// Time limit reached? + bool isSecondsLimitReached() const; + /// Solution limit reached? + bool isSolutionLimitReached() const; + /// Get how many iterations it took to solve the problem. + inline int getIterationCount() const { + return numberIterations_; + } + /// Increment how many iterations it took to solve the problem. + inline void incrementIterationCount(int value) { + numberIterations_ += value; + } + /// Get how many Nodes it took to solve the problem (including those in complete fathoming B&B inside CLP). + inline int getNodeCount() const { + return numberNodes_; + } + /// Increment how many nodes it took to solve the problem. + inline void incrementNodeCount(int value) { + numberNodes_ += value; + } + /// Get how many Nodes were enumerated in complete fathoming B&B inside CLP + inline int getExtraNodeCount() const { + return numberExtraNodes_; + } + /// Get how many times complete fathoming B&B was done + inline int getFathomCount() const { + return numberFathoms_; + } + /** Final status of problem + Some of these can be found out by is...... functions + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + */ + inline int status() const { + return status_; + } + inline void setProblemStatus(int value) { + status_ = value; + } + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + 8 stopped on iteration limit + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int value) { + secondaryStatus_ = value; + } + /// Are there numerical difficulties (for initialSolve) ? + bool isInitialSolveAbandoned() const ; + /// Is optimality proven (for initialSolve) ? + bool isInitialSolveProvenOptimal() const ; + /// Is primal infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenPrimalInfeasible() const ; + /// Is dual infeasiblity proven (for initialSolve) ? + bool isInitialSolveProvenDualInfeasible() const ; + + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Number of rows in continuous (root) problem. + inline int numberRowsAtContinuous() const { + return numberRowsAtContinuous_; + } + + /// Get number of columns + inline int getNumCols() const { + return solver_->getNumCols(); + } + + /// Get number of rows + inline int getNumRows() const { + return solver_->getNumRows(); + } + + /// Get number of nonzero elements + inline CoinBigIndex getNumElements() const { + return solver_->getNumElements(); + } + + /// Number of integers in problem + inline int numberIntegers() const { + return numberIntegers_; + } + // Integer variables + inline const int * integerVariable() const { + return integerVariable_; + } + /// Whether or not integer + inline char integerType(int i) const { + assert (integerInfo_); + assert (integerInfo_[i] == 0 || integerInfo_[i] == 1); + return integerInfo_[i]; + } + /// Whether or not integer + inline const char * integerType() const { + return integerInfo_; + } + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const { + return solver_->getColLower(); + } + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const { + return solver_->getColUpper(); + } + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + inline const char * getRowSense() const { + return solver_->getRowSense(); + } + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + inline const double * getRightHandSide() const { + return solver_->getRightHandSide(); + } + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + */ + inline const double * getRowRange() const { + return solver_->getRowRange(); + } + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const { + return solver_->getRowLower(); + } + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const { + return solver_->getRowUpper(); + } + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const { + return solver_->getObjCoefficients(); + } + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const { + //assert (dblParam_[CbcOptimizationDirection]== solver_->getObjSense()); + return dblParam_[CbcOptimizationDirection]; + } + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const { + return solver_->isContinuous(colIndex); + } + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const { + return solver_->isBinary(colIndex); + } + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + inline bool isInteger(int colIndex) const { + return solver_->isInteger(colIndex); + } + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const { + return solver_->isIntegerNonBinary(colIndex); + } + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const { + return solver_->isFreeBinary(colIndex) ; + } + + /// Get pointer to row-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByRow() const { + return solver_->getMatrixByRow(); + } + + /// Get pointer to column-wise copy of matrix + inline const CoinPackedMatrix * getMatrixByCol() const { + return solver_->getMatrixByCol(); + } + + /// Get solver's value for infinity + inline double getInfinity() const { + return solver_->getInfinity(); + } + /// Get pointer to array[getNumCols()] (for speed) of column lower bounds + inline const double * getCbcColLower() const { + return cbcColLower_; + } + /// Get pointer to array[getNumCols()] (for speed) of column upper bounds + inline const double * getCbcColUpper() const { + return cbcColUpper_; + } + /// Get pointer to array[getNumRows()] (for speed) of row lower bounds + inline const double * getCbcRowLower() const { + return cbcRowLower_; + } + /// Get pointer to array[getNumRows()] (for speed) of row upper bounds + inline const double * getCbcRowUpper() const { + return cbcRowUpper_; + } + /// Get pointer to array[getNumCols()] (for speed) of primal solution vector + inline const double * getCbcColSolution() const { + return cbcColSolution_; + } + /// Get pointer to array[getNumRows()] (for speed) of dual prices + inline const double * getCbcRowPrice() const { + return cbcRowPrice_; + } + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + inline const double * getCbcReducedCost() const { + return cbcReducedCost_; + } + /// Get pointer to array[getNumRows()] (for speed) of row activity levels. + inline const double * getCbcRowActivity() const { + return cbcRowActivity_; + } + //@} + + + /**@name Methods related to querying the solution */ + //@{ + /// Holds solution at continuous (after cuts if branchAndBound called) + inline double * continuousSolution() const { + return continuousSolution_; + } + /** Array marked whenever a solution is found if non-zero. + Code marks if heuristic returns better so heuristic + need only mark if it wants to on solutions which + are worse than current */ + inline int * usedInSolution() const { + return usedInSolution_; + } + /// Increases usedInSolution for nonzeros + void incrementUsed(const double * solution); + /// Record a new incumbent solution and update objectiveValue + void setBestSolution(CBC_Message how, + double & objectiveValue, const double *solution, + int fixVariables = 0); + /// Just update objectiveValue + void setBestObjectiveValue( double objectiveValue); + /// Deals with event handler and solution + CbcEventHandler::CbcAction dealWithEventHandler(CbcEventHandler::CbcEvent event, + double objValue, + const double * solution); + + /** Call this to really test if a valid solution can be feasible + Solution is number columns in size. + If fixVariables true then bounds of continuous solver updated. + Returns objective value (worse than cutoff if not feasible) + Previously computed objective value is now passed in (in case user does not do solve) + virtual so user can override + */ + virtual double checkSolution(double cutoff, double * solution, + int fixVariables, double originalObjValue); + /** Test the current solution for feasiblility. + + Scan all objects for indications of infeasibility. This is broken down + into simple integer infeasibility (\p numberIntegerInfeasibilities) + and all other reports of infeasibility (\p numberObjectInfeasibilities). + */ + bool feasibleSolution(int & numberIntegerInfeasibilities, + int & numberObjectInfeasibilities) const; + + /** Solution to the most recent lp relaxation. + + The solver's solution to the most recent lp relaxation. + */ + + inline double * currentSolution() const { + return currentSolution_; + } + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + inline const double * testSolution() const { + return testSolution_; + } + inline void setTestSolution(const double * solution) { + testSolution_ = solution; + } + /// Make sure region there and optionally copy solution + void reserveCurrentSolution(const double * solution = NULL); + + /// Get pointer to array[getNumCols()] of primal solution vector + inline const double * getColSolution() const { + return solver_->getColSolution(); + } + + /// Get pointer to array[getNumRows()] of dual prices + inline const double * getRowPrice() const { + return solver_->getRowPrice(); + } + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const { + return solver_->getReducedCost(); + } + + /// Get pointer to array[getNumRows()] of row activity levels. + inline const double * getRowActivity() const { + return solver_->getRowActivity(); + } + + /// Get current objective function value + inline double getCurrentObjValue() const { + return dblParam_[CbcCurrentObjectiveValue]; + } + /// Get current minimization objective function value + inline double getCurrentMinimizationObjValue() const { + return dblParam_[CbcCurrentMinimizationObjectiveValue]; + } + + /// Get best objective function value as minimization + inline double getMinimizationObjValue() const { + return bestObjective_; + } + /// Set best objective function value as minimization + inline void setMinimizationObjValue(double value) { + bestObjective_ = value; + } + + /// Get best objective function value + inline double getObjValue() const { + return bestObjective_ * solver_->getObjSense() ; + } + /** Get best possible objective function value. + This is better of best possible left on tree + and best solution found. + If called from within branch and cut may be optimistic. + */ + double getBestPossibleObjValue() const; + /// Set best objective function value + inline void setObjValue(double value) { + bestObjective_ = value * solver_->getObjSense() ; + } + /// Get solver objective function value (as minimization) + inline double getSolverObjValue() const { + return solver_->getObjValue() * solver_->getObjSense() ; + } + + /** The best solution to the integer programming problem. + + The best solution to the integer programming problem found during + the search. If no solution is found, the method returns null. + */ + + inline double * bestSolution() const { + return bestSolution_; + } + /** User callable setBestSolution. + If check false does not check valid + If true then sees if feasible and warns if objective value + worse than given (so just set to COIN_DBL_MAX if you don't care). + If check true then does not save solution if not feasible + */ + void setBestSolution(const double * solution, int numberColumns, + double objectiveValue, bool check = false); + + /// Get number of solutions + inline int getSolutionCount() const { + return numberSolutions_; + } + + /// Set number of solutions (so heuristics will be different) + inline void setSolutionCount(int value) { + numberSolutions_ = value; + } + /// Number of saved solutions (including best) + int numberSavedSolutions() const; + /// Maximum number of extra saved solutions + inline int maximumSavedSolutions() const { + return maximumSavedSolutions_; + } + /// Set maximum number of extra saved solutions + void setMaximumSavedSolutions(int value); + /// Return a saved solution (0==best) - NULL if off end + const double * savedSolution(int which) const; + /// Return a saved solution objective (0==best) - COIN_DBL_MAX if off end + double savedSolutionObjective(int which) const; + /// Delete a saved solution and move others up + void deleteSavedSolution(int which); + + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + inline int phase() const { + return phase_; + } + + /// Get number of heuristic solutions + inline int getNumberHeuristicSolutions() const { + return numberHeuristicSolutions_; + } + /// Set number of heuristic solutions + inline void setNumberHeuristicSolutions(int value) { + numberHeuristicSolutions_ = value; + } + + /// Set objective function sense (1 for min (default), -1 for max,) + inline void setObjSense(double s) { + dblParam_[CbcOptimizationDirection] = s; + solver_->setObjSense(s); + } + + /// Value of objective at continuous + inline double getContinuousObjective() const { + return originalContinuousObjective_; + } + inline void setContinuousObjective(double value) { + originalContinuousObjective_ = value; + } + /// Number of infeasibilities at continuous + inline int getContinuousInfeasibilities() const { + return continuousInfeasibilities_; + } + inline void setContinuousInfeasibilities(int value) { + continuousInfeasibilities_ = value; + } + /// Value of objective after root node cuts added + inline double rootObjectiveAfterCuts() const { + return continuousObjective_; + } + /// Sum of Changes to objective by first solve + inline double sumChangeObjective() const { + return sumChangeObjective1_; + } + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + inline int numberGlobalViolations() const { + return numberGlobalViolations_; + } + inline void clearNumberGlobalViolations() { + numberGlobalViolations_ = 0; + } + /// Whether to force a resolve after takeOffCuts + inline bool resolveAfterTakeOffCuts() const { + return resolveAfterTakeOffCuts_; + } + inline void setResolveAfterTakeOffCuts(bool yesNo) { + resolveAfterTakeOffCuts_ = yesNo; + } + /// Maximum number of rows + inline int maximumRows() const { + return maximumRows_; + } + /// Work basis for temporary use + inline CoinWarmStartBasis & workingBasis() { + return workingBasis_; + } + /// Get number of "iterations" to stop after + inline int getStopNumberIterations() const { + return stopNumberIterations_; + } + /// Set number of "iterations" to stop after + inline void setStopNumberIterations(int value) { + stopNumberIterations_ = value; + } + /// A pointer to model from CbcHeuristic + inline CbcModel * heuristicModel() const + { return heuristicModel_;} + /// Set a pointer to model from CbcHeuristic + inline void setHeuristicModel(CbcModel * model) + { heuristicModel_ = model;} + //@} + + /** \name Node selection */ + //@{ + // Comparison functions (which may be overridden by inheritance) + inline CbcCompareBase * nodeComparison() const { + return nodeCompare_; + } + void setNodeComparison(CbcCompareBase * compare); + void setNodeComparison(CbcCompareBase & compare); + //@} + + /** \name Problem feasibility checking */ + //@{ + // Feasibility functions (which may be overridden by inheritance) + inline CbcFeasibilityBase * problemFeasibility() const { + return problemFeasibility_; + } + void setProblemFeasibility(CbcFeasibilityBase * feasibility); + void setProblemFeasibility(CbcFeasibilityBase & feasibility); + //@} + + /** \name Tree methods and subtree methods */ + //@{ + /// Tree method e.g. heap (which may be overridden by inheritance) + inline CbcTree * tree() const { + return tree_; + } + /// For modifying tree handling (original is cloned) + void passInTreeHandler(CbcTree & tree); + /** For passing in an CbcModel to do a sub Tree (with derived tree handlers). + Passed in model must exist for duration of branch and bound + */ + void passInSubTreeModel(CbcModel & model); + /** For retrieving a copy of subtree model with given OsiSolver. + If no subtree model will use self (up to user to reset cutoff etc). + If solver NULL uses current + */ + CbcModel * subTreeModel(OsiSolverInterface * solver = NULL) const; + /// Returns number of times any subtree stopped on nodes, time etc + inline int numberStoppedSubTrees() const { + return numberStoppedSubTrees_; + } + /// Says a sub tree was stopped + inline void incrementSubTreeStopped() { + numberStoppedSubTrees_++; + } + /** Whether to automatically do presolve before branch and bound (subTrees). + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + inline int typePresolve() const { + return presolve_; + } + inline void setTypePresolve(int value) { + presolve_ = value; + } + + //@} + + /** \name Branching Decisions + + See the CbcBranchDecision class for additional information. + */ + //@{ + + /// Get the current branching decision method. + inline CbcBranchDecision * branchingMethod() const { + return branchingMethod_; + } + /// Set the branching decision method. + inline void setBranchingMethod(CbcBranchDecision * method) { + delete branchingMethod_; + branchingMethod_ = method->clone(); + } + /** Set the branching method + + \overload + */ + inline void setBranchingMethod(CbcBranchDecision & method) { + delete branchingMethod_; + branchingMethod_ = method.clone(); + } + /// Get the current cut modifier method + inline CbcCutModifier * cutModifier() const { + return cutModifier_; + } + /// Set the cut modifier method + void setCutModifier(CbcCutModifier * modifier); + /** Set the cut modifier method + + \overload + */ + void setCutModifier(CbcCutModifier & modifier); + //@} + + /** \name Row (constraint) and Column (variable) cut generation */ + //@{ + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + inline int stateOfSearch() const { + return stateOfSearch_; + } + inline void setStateOfSearch(int state) { + stateOfSearch_ = state; + } + /// Strategy worked out - mainly at root node for use by CbcNode + inline int searchStrategy() const { + return searchStrategy_; + } + /// Set strategy worked out - mainly at root node for use by CbcNode + inline void setSearchStrategy(int value) { + searchStrategy_ = value; + } + /// Stong branching strategy + inline int strongStrategy() const { + return strongStrategy_; + } + /// Set strong branching strategy + inline void setStrongStrategy(int value) { + strongStrategy_ = value; + } + + /// Get the number of cut generators + inline int numberCutGenerators() const { + return numberCutGenerators_; + } + /// Get the list of cut generators + inline CbcCutGenerator ** cutGenerators() const { + return generator_; + } + ///Get the specified cut generator + inline CbcCutGenerator * cutGenerator(int i) const { + return generator_[i]; + } + ///Get the specified cut generator before any changes + inline CbcCutGenerator * virginCutGenerator(int i) const { + return virginGenerator_[i]; + } + /** Add one generator - up to user to delete generators. + howoften affects how generator is used. 0 or 1 means always, + >1 means every that number of nodes. Negative values have same + meaning as positive but they may be switched off (-> -100) by code if + not many cuts generated at continuous. -99 is just done at root. + Name is just for printout. + If depth >0 overrides how often generator is called (if howOften==-1 or >0). + */ + void addCutGenerator(CglCutGenerator * generator, + int howOften = 1, const char * name = NULL, + bool normal = true, bool atSolution = false, + bool infeasible = false, int howOftenInSub = -100, + int whatDepth = -1, int whatDepthInSub = -1); +//@} + /** \name Strategy and sub models + + See the CbcStrategy class for additional information. + */ + //@{ + + /// Get the current strategy + inline CbcStrategy * strategy() const { + return strategy_; + } + /// Set the strategy. Clones + void setStrategy(CbcStrategy & strategy); + /// Set the strategy. assigns + inline void setStrategy(CbcStrategy * strategy) { + strategy_ = strategy; + } + /// Get the current parent model + inline CbcModel * parentModel() const { + return parentModel_; + } + /// Set the parent model + inline void setParentModel(CbcModel & parentModel) { + parentModel_ = &parentModel; + } + //@} + + + /** \name Heuristics and priorities */ + //@{ + /*! \brief Add one heuristic - up to user to delete + + The name is just used for print messages. + */ + void addHeuristic(CbcHeuristic * generator, const char *name = NULL, + int before = -1); + ///Get the specified heuristic + inline CbcHeuristic * heuristic(int i) const { + return heuristic_[i]; + } + /// Get the number of heuristics + inline int numberHeuristics() const { + return numberHeuristics_; + } + /// Set the number of heuristics + inline void setNumberHeuristics(int value) { + numberHeuristics_ = value; + } + /// Pointer to heuristic solver which found last solution (or NULL) + inline CbcHeuristic * lastHeuristic() const { + return lastHeuristic_; + } + /// set last heuristic which found a solution + inline void setLastHeuristic(CbcHeuristic * last) { + lastHeuristic_ = last; + } + + /** Pass in branching priorities. + + If ifClique then priorities are on cliques otherwise priorities are + on integer variables. + Other type (if exists set to default) + 1 is highest priority. (well actually -INT_MAX is but that's ugly) + If hotstart > 0 then branches are created to force + the variable to the value given by best solution. This enables a + sort of hot start. The node choice should be greatest depth + and hotstart should normally be switched off after a solution. + + If ifNotSimpleIntegers true then appended to normal integers + + This is now deprecated except for simple usage. If user + creates Cbcobjects then set priority in them + + \internal Added for Kurt Spielberg. + */ + void passInPriorities(const int * priorities, bool ifNotSimpleIntegers); + + /// Returns priority level for an object (or 1000 if no priorities exist) + inline int priority(int sequence) const { + return object_[sequence]->priority(); + } + + /*! \brief Set an event handler + + A clone of the handler passed as a parameter is stored in CbcModel. + */ + void passInEventHandler(const CbcEventHandler *eventHandler) ; + + /*! \brief Retrieve a pointer to the event handler */ + inline CbcEventHandler* getEventHandler() const { + return (eventHandler_) ; + } + + //@} + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + + /// Get application data + void * getApplicationData() const; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. Information could be built into + OsiSolverInterface but this is an alternative so that that interface + does not have to be changed. If something similar is useful to + enough solvers then it could be migrated + You can also pass in by using solver->setAuxiliaryInfo. + You should do that if solver is odd - if solver is normal simplex + then use this. + NOTE - characteristics are not cloned + */ + void passInSolverCharacteristics(OsiBabSolver * solverCharacteristics); + /// Get solver characteristics + inline const OsiBabSolver * solverCharacteristics() const { + return solverCharacteristics_; + } + //@} + + //--------------------------------------------------------------------------- + + /**@name Message handling etc */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages & messages() { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return &messages_; + } + /// Set log level + void setLogLevel(int value); + /// Get log level + inline int logLevel() const { + return handler_->logLevel(); + } + /** Set flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + inline void setDefaultHandler(bool yesNo) { + defaultHandler_ = yesNo; + } + /// Check default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + //@} + //--------------------------------------------------------------------------- + ///@name Specialized + //@{ + + /** + Set special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + inline void setSpecialOptions(int value) { + specialOptions_ = value; + } + /// Get special options + inline int specialOptions() const { + return specialOptions_; + } + /// Set random seed + inline void setRandomSeed(int value) { + randomSeed_ = value; + } + /// Get random seed + inline int getRandomSeed() const { + return randomSeed_; + } + /// Set multiple root tries + inline void setMultipleRootTries(int value) { + multipleRootTries_ = value; + } + /// Get multiple root tries + inline int getMultipleRootTries() const { + return multipleRootTries_; + } + /// Tell model to stop on event + inline void sayEventHappened() + { eventHappened_=true;} + /// Says if normal solver i.e. has well defined CoinPackedMatrix + inline bool normalSolver() const { + return (specialOptions_&16) == 0; + } + /** Says if model is sitting there waiting for mini branch and bound to finish + This is because an event handler may only have access to parent model in + mini branch and bound + */ + inline bool waitingForMiniBranchAndBound() const { + return (specialOptions_&1048576) != 0; + } + /** Set more special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + 22 bit (4194304) - Conflict analysis + 23 bit (8388608) - Conflict analysis - temporary bit + 24 bit (16777216) - Add cutoff as LP constraint (out) + 25 bit (33554432) - diving/reordering + 26 bit (67108864) - load global cuts from file + 27 bit (134217728) - append binding global cuts to file + 28 bit (268435456) - idiot branching + 29 bit (536870912) - don't make fake objective + 30 bit (1073741824) - Funny SOS or similar - be careful + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + /// Get more special options + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + 13/14 bit 8192 - go to bitter end in strong branching (first time) + */ + inline void setMoreSpecialOptions2(int value) { + moreSpecialOptions2_ = value; + } + /// Get more special options2 + inline int moreSpecialOptions2() const { + return moreSpecialOptions2_; + } + /// Set cutoff as constraint + inline void setCutoffAsConstraint(bool yesNo) { + cutoffRowNumber_ = (yesNo) ? -2 : -1; + } + /// Set time method + inline void setUseElapsedTime(bool yesNo) { + if (yesNo) + moreSpecialOptions_ |= 131072; + else + moreSpecialOptions_ &= ~131072; + } + /// Get time method + inline bool useElapsedTime() const { + return (moreSpecialOptions_&131072)!=0; + } + /// Get useful temporary pointer + inline void * temporaryPointer() const + { return temporaryPointer_;} + /// Set useful temporary pointer + inline void setTemporaryPointer(void * pointer) + { temporaryPointer_=pointer;} + /// Go to dantzig pivot selection if easy problem (clp only) + void goToDantzig(int numberNodes, ClpDualRowPivot *& savePivotMethod); + /// Now we may not own objects - just point to solver's objects + inline bool ownObjects() const { + return ownObjects_; + } + /// Check original model before it gets messed up + void checkModel(); + //@} + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcModel(); + + /// Constructor from solver + CbcModel(const OsiSolverInterface &); + + /** Assign a solver to the model (model assumes ownership) + + On return, \p solver will be NULL. + If deleteSolver then current solver deleted (if model owned) + + \note Parameter settings in the outgoing solver are not inherited by + the incoming solver. + */ + void assignSolver(OsiSolverInterface *&solver, bool deleteSolver = true); + + /** \brief Set ownership of solver + + A parameter of false tells CbcModel it does not own the solver and + should not delete it. Once you claim ownership of the solver, you're + responsible for eventually deleting it. Note that CbcModel clones + solvers with abandon. Unless you have a deep understanding of the + workings of CbcModel, the only time you want to claim ownership is when + you're about to delete the CbcModel object but want the solver to + continue to exist (as, for example, when branchAndBound has finished + and you want to hang on to the answer). + */ + inline void setModelOwnsSolver (bool ourSolver) { + ownership_ = ourSolver ? (ownership_ | 0x80000000) : (ownership_ & (~0x80000000)) ; + } + + /*! \brief Get ownership of solver + + A return value of true means that CbcModel owns the solver and will + take responsibility for deleting it when that becomes necessary. + */ + inline bool modelOwnsSolver () { + return ((ownership_&0x80000000) != 0) ; + } + + /** Copy constructor . + If cloneHandler is true then message handler is cloned + */ + CbcModel(const CbcModel & rhs, bool cloneHandler = false); + + /** Clone */ + virtual CbcModel *clone (bool cloneHandler); + + /// Assignment operator + CbcModel & operator=(const CbcModel& rhs); + + /// Destructor + virtual ~CbcModel (); + + /// Returns solver - has current state + inline OsiSolverInterface * solver() const { + return solver_; + } + + /// Returns current solver - sets new one + inline OsiSolverInterface * swapSolver(OsiSolverInterface * solver) { + OsiSolverInterface * returnSolver = solver_; + solver_ = solver; + return returnSolver; + } + + /// Returns solver with continuous state + inline OsiSolverInterface * continuousSolver() const { + return continuousSolver_; + } + + /// Create solver with continuous state + inline void createContinuousSolver() { + continuousSolver_ = solver_->clone(); + } + /// Clear solver with continuous state + inline void clearContinuousSolver() { + delete continuousSolver_; + continuousSolver_ = NULL; + } + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + inline OsiSolverInterface * referenceSolver() const { + return referenceSolver_; + } + + /// Save a copy of the current solver so can be reset to + void saveReferenceSolver(); + + /** Uses a copy of reference solver to be current solver. + Because of possible mismatches all exotic integer information is loat + (apart from normal information in OsiSolverInterface) + so SOS etc and priorities will have to be redone + */ + void resetToReferenceSolver(); + + /// Clears out as much as possible (except solver) + void gutsOfDestructor(); + /** Clears out enough to reset CbcModel as if no branch and bound done + */ + void gutsOfDestructor2(); + /** Clears out enough to reset CbcModel cutoff etc + */ + void resetModel(); + /** Most of copy constructor + mode - 0 copy but don't delete before + 1 copy and delete before + 2 copy and delete before (but use virgin generators) + */ + void gutsOfCopy(const CbcModel & rhs, int mode = 0); + /// Move status, nodes etc etc across + void moveInfo(const CbcModel & rhs); + //@} + + ///@name Multithreading + //@{ + /// Indicates whether Cbc library has been compiled with multithreading support + static bool haveMultiThreadSupport(); + /// Get pointer to masterthread + CbcThread * masterThread() const { + return masterThread_; + } + /// Get pointer to walkback + CbcNodeInfo ** walkback() const { + return walkback_; + } + /// Get number of threads + inline int getNumberThreads() const { + return numberThreads_; + } + /// Set number of threads + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + /// Get thread mode + inline int getThreadMode() const { + return threadMode_; + } + /** Set thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + 8 set and numberThreads - do heuristics numberThreads at a time + 8 set and numberThreads==0 do all heuristics at once + default is 0 + */ + inline void setThreadMode(int value) { + threadMode_ = value; + } + /** Return + -2 if deterministic threaded and main thread + -1 if deterministic threaded and serial thread + 0 if serial + 1 if opportunistic threaded + */ + inline int parallelMode() const { + if (!numberThreads_) { + if ((threadMode_&1) == 0) + return 0; + else + return -1; + return 0; + } else { + if ((threadMode_&1) == 0) + return 1; + else + return -2; + } + } + /// Thread stuff for master + inline CbcBaseModel * master() const + { return master_;} + /// From here to end of section - code in CbcThread.cpp until class changed + /// Returns true if locked + bool isLocked() const; +#ifdef CBC_THREAD + /** + Locks a thread if parallel so that stuff like cut pool + can be updated and/or used. + */ + void lockThread(); + /** + Unlocks a thread if parallel to say cut pool stuff not needed + */ + void unlockThread(); +#else + inline void lockThread() {} + inline void unlockThread() {} +#endif + /** Set information in a child + -3 pass pointer to child thread info + -2 just stop + -1 delete simple child stuff + 0 delete opportunistic child stuff + 1 delete deterministic child stuff + */ + void setInfoInChild(int type, CbcThread * info); + /** Move/copy information from one model to another + -1 - initialization + 0 - from base model + 1 - to base model (and reset) + 2 - add in final statistics etc (and reset so can do clean destruction) + */ + void moveToModel(CbcModel * baseModel, int mode); + /// Split up nodes + int splitModel(int numberModels, CbcModel ** model, + int numberNodes); + /// Start threads + void startSplitModel(int numberIterations); + /// Merge models + void mergeModels(int numberModel, CbcModel ** model, + int numberNodes); + //@} + + ///@name semi-private i.e. users should not use + //@{ + /// Get how many Nodes it took to solve the problem. + int getNodeCount2() const { + return numberNodes2_; + } + /// Set pointers for speed + void setPointers(const OsiSolverInterface * solver); + /** Perform reduced cost fixing + + Fixes integer variables at their current value based on reduced cost + penalties. Returns number fixed + */ + int reducedCostFix() ; + /** Makes all handlers same. If makeDefault 1 then makes top level + default and rest point to that. If 2 then each is copy + */ + void synchronizeHandlers(int makeDefault); + /// Save a solution to saved list + void saveExtraSolution(const double * solution, double objectiveValue); + /// Save a solution to best and move current to saved + void saveBestSolution(const double * solution, double objectiveValue); + /// Delete best and saved solutions + void deleteSolutions(); + /// Encapsulates solver resolve + int resolve(OsiSolverInterface * solver); +#ifdef CLP_RESOLVE + /// Special purpose resolve + int resolveClp(OsiClpSolverInterface * solver, int type); +#endif + + /** Encapsulates choosing a variable - + anyAction -2, infeasible (-1 round again), 0 done + */ + int chooseBranch(CbcNode * & newNode, int numberPassesLeft, + CbcNode * oldNode, OsiCuts & cuts, + bool & resolved, CoinWarmStartBasis *lastws, + const double * lowerBefore, const double * upperBefore, + OsiSolverBranch * & branches); + int chooseBranch(CbcNode * newNode, int numberPassesLeft, bool & resolved); + + /** Return an empty basis object of the specified size + + A useful utility when constructing a basis for a subproblem from scratch. + The object returned will be of the requested capacity and appropriate for + the solver attached to the model. + */ + CoinWarmStartBasis *getEmptyBasis(int ns = 0, int na = 0) const ; + + /** Remove inactive cuts from the model + + An OsiSolverInterface is expected to maintain a valid basis, but not a + valid solution, when loose cuts are deleted. Restoring a valid solution + requires calling the solver to reoptimise. If it's certain the solution + will not be required, set allowResolve to false to suppress + reoptimisation. + If saveCuts then slack cuts will be saved + On input current cuts are cuts and newCuts + on exit current cuts will be correct. Returns number dropped + */ + int takeOffCuts(OsiCuts &cuts, + bool allowResolve, OsiCuts * saveCuts, + int numberNewCuts = 0, const OsiRowCut ** newCuts = NULL) ; + + /** Determine and install the active cuts that need to be added for + the current subproblem + + The whole truth is a bit more complicated. The first action is a call to + addCuts1(). addCuts() then sorts through the list, installs the tight + cuts in the model, and does bookkeeping (adjusts reference counts). + The basis returned from addCuts1() is adjusted accordingly. + + If it turns out that the node should really be fathomed by bound, + addCuts() simply treats all the cuts as loose as it does the bookkeeping. + + */ + int addCuts(CbcNode * node, CoinWarmStartBasis *&lastws); + + /** Traverse the tree from node to root and prep the model + + addCuts1() begins the job of prepping the model to match the current + subproblem. The model is stripped of all cuts, and the search tree is + traversed from node to root to determine the changes required. Appropriate + bounds changes are installed, a list of cuts is collected but not + installed, and an appropriate basis (minus the cuts, but big enough to + accommodate them) is constructed. + + Returns true if new problem similar to old + + \todo addCuts1() is called in contexts where it's known in advance that + all that's desired is to determine a list of cuts and do the + bookkeeping (adjust the reference counts). The work of installing + bounds and building a basis goes to waste. + */ + bool addCuts1(CbcNode * node, CoinWarmStartBasis *&lastws); + /** Returns bounds just before where - initially original bounds. + Also sets downstream nodes (lower if force 1, upper if 2) + */ + void previousBounds (CbcNode * node, CbcNodeInfo * where, int iColumn, + double & lower, double & upper, int force); + /** Set objective value in a node. This is separated out so that + odd solvers can use. It may look at extra information in + solverCharacteriscs_ and will also use bound from parent node + */ + void setObjectiveValue(CbcNode * thisNode, const CbcNode * parentNode) const; + + /** If numberBeforeTrust >0 then we are going to use CbcBranchDynamic. + Scan and convert CbcSimpleInteger objects + */ + void convertToDynamic(); + /// Set numberBeforeTrust in all objects + void synchronizeNumberBeforeTrust(int type = 0); + /// Zap integer information in problem (may leave object info) + void zapIntegerInformation(bool leaveObjects = true); + /// Use cliques for pseudocost information - return nonzero if infeasible + int cliquePseudoCosts(int doStatistics); + /// Fill in useful estimates + void pseudoShadow(int type); + /** Return pseudo costs + If not all integers or not pseudo costs - returns all zero + Length of arrays are numberIntegers() and entries + correspond to integerVariable()[i] + User must allocate arrays before call + */ + void fillPseudoCosts(double * downCosts, double * upCosts, + int * priority = NULL, + int * numberDown = NULL, int * numberUp = NULL, + int * numberDownInfeasible = NULL, + int * numberUpInfeasible = NULL) const; + /** Do heuristics at root. + 0 - don't delete + 1 - delete + 2 - just delete - don't even use + */ + void doHeuristicsAtRoot(int deleteHeuristicsAfterwards = 0); + /// Adjust heuristics based on model + void adjustHeuristics(); + /// Get the hotstart solution + inline const double * hotstartSolution() const { + return hotstartSolution_; + } + /// Get the hotstart priorities + inline const int * hotstartPriorities() const { + return hotstartPriorities_; + } + + /// Return the list of cuts initially collected for this subproblem + inline CbcCountRowCut ** addedCuts() const { + return addedCuts_; + } + /// Number of entries in the list returned by #addedCuts() + inline int currentNumberCuts() const { + return currentNumberCuts_; + } + /// Global cuts + inline CbcRowCuts * globalCuts() { + return &globalCuts_; + } + /// Get rid of global cuts + inline void zapGlobalCuts() { + globalCuts_ = CbcRowCuts(); + } + /// Copy and set a pointer to a row cut which will be added instead of normal branching. + void setNextRowCut(const OsiRowCut & cut); + /// Get a pointer to current node (be careful) + inline CbcNode * currentNode() const { + return currentNode_; + } + /// Get a pointer to probing info + inline CglTreeProbingInfo * probingInfo() const { + return probingInfo_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Set the number of iterations done in strong branching. + inline void setNumberStrongIterations(int number) { + numberStrongIterations_ = number; + } + /// Get the number of iterations done in strong branching. + inline int numberStrongIterations() const { + return numberStrongIterations_; + } + /// Get maximum number of iterations (designed to be used in heuristics) + inline int maximumNumberIterations() const { + return maximumNumberIterations_; + } + /// Set maximum number of iterations (designed to be used in heuristics) + inline void setMaximumNumberIterations(int value) { + maximumNumberIterations_ = value; + } + /// Symmetry information + inline CbcSymmetry * symmetryInfo() const + { return symmetryInfo_;} + /// Set depth for fast nodes + inline void setFastNodeDepth(int value) { + fastNodeDepth_ = value; + } + /// Get depth for fast nodes + inline int fastNodeDepth() const { + return fastNodeDepth_; + } + /// Get anything with priority >= this can be treated as continuous + inline int continuousPriority() const { + return continuousPriority_; + } + /// Set anything with priority >= this can be treated as continuous + inline void setContinuousPriority(int value) { + continuousPriority_ = value; + } + inline void incrementExtra(int nodes, int iterations, int fathoms=1) { + numberExtraNodes_ += nodes; + numberExtraIterations_ += iterations; + numberFathoms_ += fathoms; + } + /// Zero extra + inline void zeroExtra() { + numberExtraNodes_ = 0; + numberExtraIterations_ = 0; + numberFathoms_ = 0; + } + /// Number of extra iterations + inline int numberExtraIterations() const { + return numberExtraIterations_; + } + /// Increment strong info + void incrementStrongInfo(int numberTimes, int numberIterations, + int numberFixed, bool ifInfeasible); + /// Return strong info + inline const int * strongInfo() const { + return strongInfo_; + } + + /// Return mutable strong info + inline int * mutableStrongInfo() { + return strongInfo_; + } + /// Get stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts() const { + return storedRowCuts_; + } + /// Set stored row cuts for donor/recipient CbcModel + void setStoredRowCuts(CglStored * cuts) { + storedRowCuts_ = cuts; + } + /// Says whether all dynamic integers + inline bool allDynamic () const { + return ((ownership_&0x40000000) != 0) ; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, int options); + /// Generate an OsiBranchingInformation object + OsiBranchingInformation usefulInformation() const; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + inline void setBestSolutionBasis(const CoinWarmStartBasis & bestSolutionBasis) { + bestSolutionBasis_ = bestSolutionBasis; + } + /// Redo walkback arrays + void redoWalkBack(); + //@} + + void setMIPStart( const std::vector< std::pair< std::string, double > > &mips ) { + this->mipStart_ = mips; + } + + const std::vector< std::pair< std::string, double > > &getMIPStart() { + return this->mipStart_; + } + + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + + /// The solver associated with this model. + OsiSolverInterface * solver_; + + /** Ownership of objects and other stuff + + 0x80000000 model owns solver + 0x40000000 all variables CbcDynamicPseudoCost + */ + unsigned int ownership_ ; + + /// A copy of the solver, taken at the continuous (root) node. + OsiSolverInterface * continuousSolver_; + + /// A copy of the solver, taken at constructor or by saveReferenceSolver + OsiSolverInterface * referenceSolver_; + + /// Message handler + CoinMessageHandler * handler_; + + /** Flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + bool defaultHandler_; + + /// Cbc messages + CoinMessages messages_; + + /// Array for integer parameters + int intParam_[CbcLastIntParam]; + + /// Array for double parameters + double dblParam_[CbcLastDblParam]; + + /** Pointer to an empty warm start object + + It turns out to be useful to have this available as a base from + which to build custom warm start objects. This is typed as CoinWarmStart + rather than CoinWarmStartBasis to allow for the possibility that a + client might want to apply a solver that doesn't use a basis-based warm + start. See getEmptyBasis for an example of how this field can be used. + */ + mutable CoinWarmStart *emptyWarmStart_ ; + + /// Best objective + double bestObjective_; + /// Best possible objective + double bestPossibleObjective_; + /// Sum of Changes to objective by first solve + double sumChangeObjective1_; + /// Sum of Changes to objective by subsequent solves + double sumChangeObjective2_; + + /// Array holding the incumbent (best) solution. + double * bestSolution_; + /// Arrays holding other solutions. + double ** savedSolutions_; + + /** Array holding the current solution. + + This array is used more as a temporary. + */ + double * currentSolution_; + /** For testing infeasibilities - will point to + currentSolution_ or solver-->getColSolution() + */ + mutable const double * testSolution_; + /** MIPstart values + values for integer variables which will be converted to a complete integer initial feasible solution + */ + std::vector< std::pair< std::string, double > > mipStart_; + /** Warm start object produced by heuristic or strong branching + + If get a valid integer solution outside branch and bound then it can take + a reasonable time to solve LP which produces clean solution. If this object has + any size then it will be used in solve. + */ + CoinWarmStartBasis bestSolutionBasis_ ; + /// Global cuts + CbcRowCuts globalCuts_; + /// Global conflict cuts + CbcRowCuts * globalConflictCuts_; + + /// Minimum degradation in objective value to continue cut generation + double minimumDrop_; + /// Number of solutions + int numberSolutions_; + /// Number of saved solutions + int numberSavedSolutions_; + /// Maximum number of saved solutions + int maximumSavedSolutions_; + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// At which depths to do cuts + int whenCuts_; + /// Hotstart solution + double * hotstartSolution_; + /// Hotstart priorities + int * hotstartPriorities_; + /// Number of heuristic solutions + int numberHeuristicSolutions_; + /// Cumulative number of nodes + int numberNodes_; + /** Cumulative number of nodes for statistics. + Must fix to match up + */ + int numberNodes2_; + /// Cumulative number of iterations + int numberIterations_; + /// Cumulative number of solves + int numberSolves_; + /// Status of problem - 0 finished, 1 stopped, 2 difficulties + int status_; + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + */ + int secondaryStatus_; + /// Number of integers in problem + int numberIntegers_; + /// Number of rows at continuous + int numberRowsAtContinuous_; + /** + -1 - cutoff as constraint not activated + -2 - waiting to activate + >=0 - activated + */ + int cutoffRowNumber_; + /// Maximum number of cuts + int maximumNumberCuts_; + /** Current phase (so heuristics etc etc can find out). + 0 - initial solve + 1 - solve with cuts at root + 2 - solve with cuts + 3 - other e.g. strong branching + 4 - trying to validate a solution + 5 - at end of search + */ + int phase_; + + /// Number of entries in #addedCuts_ + int currentNumberCuts_; + + /** Current limit on search tree depth + + The allocated size of #walkback_. Increased as needed. + */ + int maximumDepth_; + /** Array used to assemble the path between a node and the search tree root + + The array is resized when necessary. #maximumDepth_ is the current + allocated size. + */ + CbcNodeInfo ** walkback_; + CbcNodeInfo ** lastNodeInfo_; + const OsiRowCut ** lastCut_; + int lastDepth_; + int lastNumberCuts2_; + int maximumCuts_; + int * lastNumberCuts_; + + /** The list of cuts initially collected for this subproblem + + When the subproblem at this node is rebuilt, a set of cuts is collected + for inclusion in the constraint system. If any of these cuts are + subsequently removed because they have become loose, the corresponding + entry is set to NULL. + */ + CbcCountRowCut ** addedCuts_; + + /** A pointer to a row cut which will be added instead of normal branching. + After use it should be set to NULL. + */ + OsiRowCut * nextRowCut_; + + /// Current node so can be used elsewhere + CbcNode * currentNode_; + + /// Indices of integer variables + int * integerVariable_; + /// Whether of not integer + char * integerInfo_; + /// Holds solution at continuous (after cuts) + double * continuousSolution_; + /// Array marked whenever a solution is found if non-zero + int * usedInSolution_; + /** + Special options + 0 bit (1) - check if cuts valid (if on debugger list) + 1 bit (2) - use current basis to check integer solution (rather than all slack) + 2 bit (4) - don't check integer solution (by solving LP) + 3 bit (8) - fast analyze + 4 bit (16) - non-linear model - so no well defined CoinPackedMatrix + 5 bit (32) - keep names + 6 bit (64) - try for dominated columns + 7 bit (128) - SOS type 1 but all declared integer + 8 bit (256) - Set to say solution just found, unset by doing cuts + 9 bit (512) - Try reduced model after 100 nodes + 10 bit (1024) - Switch on some heuristics even if seems unlikely + 11 bit (2048) - Mark as in small branch and bound + 12 bit (4096) - Funny cuts so do slow way (in some places) + 13 bit (8192) - Funny cuts so do slow way (in other places) + 14 bit (16384) - Use Cplex! for fathoming + 15 bit (32768) - Try reduced model after 0 nodes + 16 bit (65536) - Original model had integer bounds + 17 bit (131072) - Perturbation switched off + 18 bit (262144) - donor CbcModel + 19 bit (524288) - recipient CbcModel + 20 bit (1048576) - waiting for sub model to return + 22 bit (4194304) - do not initialize random seed in solver (user has) + 23 bit (8388608) - leave solver_ with cuts + 24 bit (16777216) - just get feasible if no cutoff + */ + int specialOptions_; + /** More special options + at present bottom 6 bits used for shadow price mode + 1024 for experimental hotstart + 2048,4096 breaking out of cuts + 8192 slowly increase minimum drop + 16384 gomory + 32768 more heuristics in sub trees + 65536 no cuts in preprocessing + 131072 Time limits elapsed + 18 bit (262144) - Perturb fathom nodes + 19 bit (524288) - No limit on fathom nodes + 20 bit (1048576) - Reduce sum of infeasibilities before cuts + 21 bit (2097152) - Reduce sum of infeasibilities after cuts + */ + int moreSpecialOptions_; + /** More more special options + 0 bit (1) - find switching variables + 1 bit (2) - using fake objective until solution + 2 bit (4) - switching variables exist + 3 bit (8) - skip most of setBestSolution checks + 4 bit (16) - very lightweight preprocessing in smallB&B + 5 bit (32) - event handler needs to be cloned when parallel + 6 bit (64) - testing - use probing to make cliques + 7/8 bit (128) - try orbital branching (if nauty) + 9 bit (512) - branching on objective (later) + 10 bit (1024) - branching on constraints (later) + 11/12 bit 2048 - intermittent cuts + */ + int moreSpecialOptions2_; + /// User node comparison function + CbcCompareBase * nodeCompare_; + /// User feasibility function (see CbcFeasibleBase.hpp) + CbcFeasibilityBase * problemFeasibility_; + /// Tree + CbcTree * tree_; + /// Pointer to top of tree + CbcFullNodeInfo * topOfTree_; + /// A pointer to model to be used for subtrees + CbcModel * subTreeModel_; + /// A pointer to model from CbcHeuristic + CbcModel * heuristicModel_; + /// Number of times any subtree stopped on nodes, time etc + int numberStoppedSubTrees_; + /// Variable selection function + CbcBranchDecision * branchingMethod_; + /// Cut modifier function + CbcCutModifier * cutModifier_; + /// Strategy + CbcStrategy * strategy_; + /// Parent model + CbcModel * parentModel_; + /** Whether to automatically do presolve before branch and bound. + 0 - no + 1 - ordinary presolve + 2 - integer presolve (dodgy) + */ + /// Pointer to array[getNumCols()] (for speed) of column lower bounds + const double * cbcColLower_; + /// Pointer to array[getNumCols()] (for speed) of column upper bounds + const double * cbcColUpper_; + /// Pointer to array[getNumRows()] (for speed) of row lower bounds + const double * cbcRowLower_; + /// Pointer to array[getNumRows()] (for speed) of row upper bounds + const double * cbcRowUpper_; + /// Pointer to array[getNumCols()] (for speed) of primal solution vector + const double * cbcColSolution_; + /// Pointer to array[getNumRows()] (for speed) of dual prices + const double * cbcRowPrice_; + /// Get a pointer to array[getNumCols()] (for speed) of reduced costs + const double * cbcReducedCost_; + /// Pointer to array[getNumRows()] (for speed) of row activity levels. + const double * cbcRowActivity_; + /// Pointer to user-defined data structure + void * appData_; + /// Presolve for CbcTreeLocal + int presolve_; + /** Maximum number of candidates to consider for strong branching. + To disable strong branching, set this to 0. + */ + int numberStrong_; + /** \brief The number of branches before pseudo costs believed + in dynamic strong branching. + + A value of 0 is off. + */ + int numberBeforeTrust_; + /** \brief The number of variables for which to compute penalties + in dynamic strong branching. + */ + int numberPenalties_; + /// For threads - stop after this many "iterations" + int stopNumberIterations_; + /** Scale factor to make penalties match strong. + Should/will be computed */ + double penaltyScaleFactor_; + /// Number of analyze iterations to do + int numberAnalyzeIterations_; + /// Arrays with analysis results + double * analyzeResults_; + /// Useful temporary pointer + void * temporaryPointer_; + /// Number of nodes infeasible by normal branching (before cuts) + int numberInfeasibleNodes_; + /** Problem type as set by user or found by analysis. This will be extended + 0 - not known + 1 - Set partitioning <= + 2 - Set partitioning == + 3 - Set covering + */ + int problemType_; + /// Print frequency + int printFrequency_; + /// Number of cut generators + int numberCutGenerators_; + // Cut generators + CbcCutGenerator ** generator_; + // Cut generators before any changes + CbcCutGenerator ** virginGenerator_; + /// Number of heuristics + int numberHeuristics_; + /// Heuristic solvers + CbcHeuristic ** heuristic_; + /// Pointer to heuristic solver which found last solution (or NULL) + CbcHeuristic * lastHeuristic_; + /// Depth for fast nodes + int fastNodeDepth_; + /*! Pointer to the event handler */ +# ifdef CBC_ONLY_CLP + ClpEventHandler *eventHandler_ ; +# else + CbcEventHandler *eventHandler_ ; +# endif + /// Symmetry information + CbcSymmetry * symmetryInfo_; + /// Total number of objects + int numberObjects_; + + /** \brief Integer and Clique and ... information + + \note The code assumes that the first objects on the list will be + SimpleInteger objects for each integer variable, followed by + Clique objects. Portions of the code that understand Clique objects + will fail if they do not immediately follow the SimpleIntegers. + Large chunks of the code will fail if the first objects are not + SimpleInteger. As of 2003.08, SimpleIntegers and Cliques are the only + objects. + */ + OsiObject ** object_; + /// Now we may not own objects - just point to solver's objects + bool ownObjects_; + + /// Original columns as created by integerPresolve or preprocessing + int * originalColumns_; + /// How often to scan global cuts + int howOftenGlobalScan_; + /** Number of times global cuts violated. When global cut pool then this + should be kept for each cut and type of cut */ + int numberGlobalViolations_; + /// Number of extra iterations in fast lp + int numberExtraIterations_; + /// Number of extra nodes in fast lp + int numberExtraNodes_; + /// Number of times fast lp entered + int numberFathoms_; + /** Value of objective at continuous + (Well actually after initial round of cuts) + */ + double continuousObjective_; + /** Value of objective before root node cuts added + */ + double originalContinuousObjective_; + /// Number of infeasibilities at continuous + int continuousInfeasibilities_; + /// Maximum number of cut passes at root + int maximumCutPassesAtRoot_; + /// Maximum number of cut passes + int maximumCutPasses_; + /// Preferred way of branching + int preferredWay_; + /// Current cut pass number + int currentPassNumber_; + /// Maximum number of cuts (for whichGenerator_) + int maximumWhich_; + /// Maximum number of rows + int maximumRows_; + /// Random seed + int randomSeed_; + /// Multiple root tries + int multipleRootTries_; + /// Current depth + int currentDepth_; + /// Thread specific random number generator + mutable CoinThreadRandom randomNumberGenerator_; + /// Work basis for temporary use + CoinWarmStartBasis workingBasis_; + /// Which cut generator generated this cut + int * whichGenerator_; + /// Maximum number of statistics + int maximumStatistics_; + /// statistics + CbcStatistics ** statistics_; + /// Maximum depth reached + int maximumDepthActual_; + /// Number of reduced cost fixings + double numberDJFixed_; + /// Probing info + CglTreeProbingInfo * probingInfo_; + /// Number of fixed by analyze at root + int numberFixedAtRoot_; + /// Number fixed by analyze so far + int numberFixedNow_; + /// Whether stopping on gap + bool stoppedOnGap_; + /// Whether event happened + mutable bool eventHappened_; + /// Number of long strong goes + int numberLongStrong_; + /// Number of old active cuts + int numberOldActiveCuts_; + /// Number of new cuts + int numberNewCuts_; + /// Strategy worked out - mainly at root node + int searchStrategy_; + /** Strategy for strong branching + 0 - normal + when to do all fractional + 1 - root node + 2 - depth less than modifier + 4 - if objective == best possible + 6 - as 2+4 + when to do all including satisfied + 10 - root node etc. + If >=100 then do when depth <= strategy/100 (otherwise 5) + */ + int strongStrategy_; + /// Number of iterations in strong branching + int numberStrongIterations_; + /** 0 - number times strong branching done, 1 - number fixed, 2 - number infeasible + Second group of three is a snapshot at node [6] */ + int strongInfo_[7]; + /** + For advanced applications you may wish to modify the behavior of Cbc + e.g. if the solver is a NLP solver then you may not have an exact + optimum solution at each step. This gives characteristics - just for one BAB. + For actually saving/restoring a solution you need the actual solver one. + */ + OsiBabSolver * solverCharacteristics_; + /// Whether to force a resolve after takeOffCuts + bool resolveAfterTakeOffCuts_; + /// Maximum number of iterations (designed to be used in heuristics) + int maximumNumberIterations_; + /// Anything with priority >= this can be treated as continuous + int continuousPriority_; + /// Number of outstanding update information items + int numberUpdateItems_; + /// Maximum number of outstanding update information items + int maximumNumberUpdateItems_; + /// Update items + CbcObjectUpdateData * updateItems_; + /// Stored row cuts for donor/recipient CbcModel + CglStored * storedRowCuts_; + /** + Parallel + 0 - off + 1 - testing + 2-99 threads + other special meanings + */ + int numberThreads_; + /** thread mode + always use numberThreads for branching + 1 set then deterministic + 2 set then use numberThreads for root cuts + 4 set then use numberThreads in root mini branch and bound + default is 0 + */ + int threadMode_; + /// Number of global cuts on entry to a node + int numberGlobalCutsIn_; + /// Thread stuff for master + CbcBaseModel * master_; + /// Pointer to masterthread + CbcThread * masterThread_; +//@} +}; +/// So we can use osiObject or CbcObject during transition +void getIntegerInformation(const OsiObject * object, double & originalLower, + double & originalUpper) ; +// So we can call from other programs +// Real main program +class OsiClpSolverInterface; +int CbcMain (int argc, const char *argv[], OsiClpSolverInterface & solver, CbcModel ** babSolver); +int CbcMain (int argc, const char *argv[], CbcModel & babSolver); +// four ways of calling +int callCbc(const char * input2, OsiClpSolverInterface& solver1); +int callCbc(const char * input2); +int callCbc(const std::string input2, OsiClpSolverInterface& solver1); +int callCbc(const std::string input2) ; +// When we want to load up CbcModel with options first +void CbcMain0 (CbcModel & babSolver); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver); +// two ways of calling +int callCbc(const char * input2, CbcModel & babSolver); +int callCbc(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize +int callCbc1(const char * input2, CbcModel & babSolver); +int callCbc1(const std::string input2, CbcModel & babSolver); +// And when CbcMain0 already called to initialize (with call back) (see CbcMain1 for whereFrom) +int callCbc1(const char * input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int callCbc1(const std::string input2, CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom)); +// For uniform setting of cut and heuristic options +void setCutAndHeuristicOptions(CbcModel & model); +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcNWay.hpp b/thirdparty/linux/include/coin/coin/CbcNWay.hpp new file mode 100644 index 0000000..d74c724 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcNWay.hpp @@ -0,0 +1,166 @@ +// $Id: CbcNWay.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +/** Define an n-way class for variables. + Only valid value is one at UB others at LB + Normally 0-1 +*/ +#ifndef CbcNWay_H +#define CbcNWay_H + +class CbcNWay : public CbcObject { + +public: + + // Default Constructor + CbcNWay (); + + /** Useful constructor (which are matrix indices) + */ + CbcNWay (CbcModel * model, int numberMembers, + const int * which, int identifier); + + // Copy constructor + CbcNWay ( const CbcNWay &); + + /// Clone + virtual CbcObject * clone() const; + + /// Assignment operator + CbcNWay & operator=( const CbcNWay& rhs); + + /// Destructor + virtual ~CbcNWay (); + + /// Set up a consequence for a single member + void setConsequence(int iColumn, const CbcConsequence & consequence); + + /// Applies a consequence for a single member + void applyConsequence(int iSequence, int state) const; + + /// Infeasibility - large is 0.5 (and 0.5 will give this) + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const { + return members_; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + +protected: + /// data + /// Number of members + int numberMembers_; + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /// Consequences (normally NULL) + CbcConsequence ** consequence_; +}; +/** N way branching Object class. + Variable is number of set. + */ +class CbcNWayBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcNWayBranchingObject (); + + /** Useful constructor - order had matrix indices + way_ -1 corresponds to setting first, +1 to second, +3 etc. + this is so -1 and +1 have similarity to normal + */ + CbcNWayBranchingObject (CbcModel * model, const CbcNWay * nway, + int numberBranches, const int * order); + + // Copy constructor + CbcNWayBranchingObject ( const CbcNWayBranchingObject &); + + // Assignment operator + CbcNWayBranchingObject & operator=( const CbcNWayBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcNWayBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + +#ifdef JJF_ZERO + // FIXME: what do we need to do here? + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + /** The number of branch arms created for this branching object + */ + virtual int numberBranches() const { + return numberInSet_; + } + /// Is this a two way object (-1 down, +1 up) + virtual bool twoWay() const { + return false; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return NWayBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +private: + /// order of branching - points back to CbcNWay + int * order_; + /// Points back to object + const CbcNWay * object_; + /// Number in set + int numberInSet_; +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcNode.hpp b/thirdparty/linux/include/coin/coin/CbcNode.hpp new file mode 100644 index 0000000..69b6737 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcNode.hpp @@ -0,0 +1,351 @@ +/* $Id: CbcNode.hpp 1957 2013-08-27 15:19:55Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcNode_H +#define CbcNode_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" +#include "CbcFullNodeInfo.hpp" +#include "CbcPartialNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +/** Information required while the node is live + + When a subproblem is initially created, it is represented by an CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information (depth, branching instructions), that's + needed while the subproblem remains `live', <i>i.e.</i>, while the + subproblem is not fathomed and there are branch arms still be be + evaluated. The CbcNode is deleted when the last branch arm has been + evaluated. + + The CbcNodeInfo object contains the information needed to maintain the + search tree and recreate the subproblem for the node. It remains in + existence until there are no nodes remaining in the subtree rooted at this + node. +*/ + +class CbcNode : public CoinTreeNode { + +public: + + /// Default Constructor + CbcNode (); + + /// Construct and increment parent reference count + CbcNode (CbcModel * model, CbcNode * lastNode); + + /// Copy constructor + CbcNode (const CbcNode &); + + /// Assignment operator + CbcNode & operator= (const CbcNode& rhs); + + /// Destructor + ~CbcNode (); + + /** Create a description of the subproblem at this node + + The CbcNodeInfo structure holds the information (basis & variable bounds) + required to recreate the subproblem for this node. It also links the node + to its parent (via the parent's CbcNodeInfo object). + + If lastNode == NULL, a CbcFullNodeInfo object will be created. All + parameters except \p model are unused. + + If lastNode != NULL, a CbcPartialNodeInfo object will be created. Basis and + bounds information will be stored in the form of differences between the + parent subproblem and this subproblem. + (More precisely, \p lastws, \p lastUpper, \p lastLower, + \p numberOldActiveCuts, and \p numberNewCuts are used.) + */ + void + createInfo(CbcModel * model, + CbcNode * lastNode, + const CoinWarmStartBasis *lastws, + const double * lastLower, const double * lastUpper, + int numberOldActiveCuts, int numberNewCuts); + + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseBranch (CbcModel * model, + CbcNode * lastNode, + int numberPassesLeft); + /** Create a branching object for the node - when dynamic pseudo costs + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + This version gives preference in evaluation to variables which + have not been evaluated many times. It also uses numberStrong + to say give up if last few tries have not changed incumbent. + See Achterberg, Koch and Martin. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + <li> >0: Number of quich branching objects (and branches will be non NULL) + </ul> + */ + int chooseDynamicBranch (CbcModel * model, + CbcNode * lastNode, + OsiSolverBranch * & branches, + int numberPassesLeft); + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. The candidates are + evaluated, and an appropriate branch object is installed. + + The numberPassesLeft is decremented to stop fixing one variable each time + and going on and on (e.g. for stock cutting, air crew scheduling) + + If evaluation determines that an object is monotone or infeasible, + the routine returns immediately. In the case of a monotone object, + the branch object has already been called to modify the model. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + Branch state: + <ul> + <li> -1: start + <li> -1: A monotone object was discovered + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseOsiBranch (CbcModel * model, + CbcNode * lastNode, + OsiBranchingInformation * usefulInfo, + int branchState); + /** Create a branching object for the node + + The routine scans the object list of the model and selects a set of + unsatisfied objects as candidates for branching. It then solves a + series of problems and a CbcGeneral branch object is installed. + + If evaluation determines that an object is infeasible, + the routine returns immediately. + + Return value: + <ul> + <li> 0: A branching object has been installed + <li> -2: An infeasible object was discovered + </ul> + */ + int chooseClpBranch (CbcModel * model, + CbcNode * lastNode); + int analyze(CbcModel * model, double * results); + /// Decrement active cut counts + void decrementCuts(int change = 1); + + /// Decrement all active cut counts in chain starting at parent + void decrementParentCuts(CbcModel * model, int change = 1); + + /// Nulls out node info + void nullNodeInfo(); + /** Initialize reference counts in attached CbcNodeInfo + + This is a convenience routine, which will initialize the reference counts + in the attached CbcNodeInfo object based on the attached + OsiBranchingObject. + + \sa CbcNodeInfo::initializeInfo(int). + */ + void initializeInfo(); + + /// Does next branch and updates state + int branch(OsiSolverInterface * solver); + + /** Double checks in case node can change its mind! + Returns objective value + Can change objective etc */ + double checkIsCutoff(double cutoff); + // Information to make basis and bounds + inline CbcNodeInfo * nodeInfo() const { + return nodeInfo_; + } + + // Objective value + inline double objectiveValue() const { + return objectiveValue_; + } + inline void setObjectiveValue(double value) { + objectiveValue_ = value; + } + /// Number of arms defined for the attached OsiBranchingObject. + inline int numberBranches() const { + if (branch_) + return (branch_->numberBranches()) ; + else + return (-1) ; + } + + /* Active arm of the attached OsiBranchingObject. + + In the simplest instance, coded -1 for the down arm of the branch, +1 for + the up arm. But see OsiBranchingObject::way() + Use nodeInfo--.numberBranchesLeft_ to see how active + */ + int way() const; + /// Depth in branch-and-cut search tree + inline int depth() const { + return depth_; + } + /// Set depth in branch-and-cut search tree + inline void setDepth(int value) { + depth_ = value; + } + /// Get the number of objects unsatisfied at this node. + inline int numberUnsatisfied() const { + return numberUnsatisfied_; + } + /// Set the number of objects unsatisfied at this node. + inline void setNumberUnsatisfied(int value) { + numberUnsatisfied_ = value; + } + /// Get sum of "infeasibilities" reported by each object + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Set sum of "infeasibilities" reported by each object + inline void setSumInfeasibilities(double value) { + sumInfeasibilities_ = value; + } + // Guessed objective value (for solution) + inline double guessedObjectiveValue() const { + return guessedObjectiveValue_; + } + inline void setGuessedObjectiveValue(double value) { + guessedObjectiveValue_ = value; + } + /// Branching object for this node + inline const OsiBranchingObject * branchingObject() const { + return branch_; + } + /// Modifiable branching object for this node + inline OsiBranchingObject * modifiableBranchingObject() const { + return branch_; + } + /// Set branching object for this node (takes ownership) + inline void setBranchingObject(OsiBranchingObject * branchingObject) { + branch_ = branchingObject; + } + /// The node number + inline int nodeNumber() const { + return nodeNumber_; + } + inline void setNodeNumber(int node) { + nodeNumber_ = node; + } + /// Returns true if on tree + inline bool onTree() const { + return (state_&1) != 0; + } + /// Sets true if on tree + inline void setOnTree(bool yesNo) { + if (yesNo) state_ |= 1; + else state_ &= ~1; + } + /// Returns true if active + inline bool active() const { + return (state_&2) != 0; + } + /// Sets true if active + inline void setActive(bool yesNo) { + if (yesNo) state_ |= 2; + else state_ &= ~2; + } + /// Get state (really for debug) + inline int getState() const + { return state_;} + /// Set state (really for debug) + inline void setState(int value) + { state_ = value;} + /// Print + void print() const; + /// Debug + inline void checkInfo() const { + assert (nodeInfo_->numberBranchesLeft() == + branch_->numberBranchesLeft()); + } + +private: + // Data + /// Information to make basis and bounds + CbcNodeInfo * nodeInfo_; + /// Objective value + double objectiveValue_; + /// Guessed satisfied Objective value + double guessedObjectiveValue_; + /// Sum of "infeasibilities" reported by each object + double sumInfeasibilities_; + /// Branching object for this node + OsiBranchingObject * branch_; + /// Depth of the node in the search tree + int depth_; + /// The number of objects unsatisfied at this node. + int numberUnsatisfied_; + /// The node number + int nodeNumber_; + /** State + 1 - on tree + 2 - active + */ + int state_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcNodeInfo.hpp b/thirdparty/linux/include/coin/coin/CbcNodeInfo.hpp new file mode 100644 index 0000000..914a347 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcNodeInfo.hpp @@ -0,0 +1,349 @@ +// $Id: CbcNodeInfo.hpp 2048 2014-07-16 09:29:16Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcNodeInfo_H +#define CbcNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; + +//############################################################################# +/** Information required to recreate the subproblem at this node + + When a subproblem is initially created, it is represented by a CbcNode + object and an attached CbcNodeInfo object. + + The CbcNode contains information needed while the subproblem remains live. + The CbcNode is deleted when the last branch arm has been evaluated. + + The CbcNodeInfo contains information required to maintain the branch-and-cut + search tree structure (links and reference counts) and to recreate the + subproblem for this node (basis, variable bounds, cutting planes). A + CbcNodeInfo object remains in existence until all nodes have been pruned from + the subtree rooted at this node. + + The principle used to maintain the reference count is that the reference + count is always the sum of all potential and actual children of the node. + Specifically, + <ul> + <li> Once it's determined how the node will branch, the reference count + is set to the number of potential children (<i>i.e.</i>, the number + of arms of the branch). + <li> As each child is created by CbcNode::branch() (converting a potential + child to the active subproblem), the reference count is decremented. + <li> If the child survives and will become a node in the search tree + (converting the active subproblem into an actual child), increment the + reference count. + </ul> + Notice that the active subproblem lives in a sort of limbo, neither a + potential or an actual node in the branch-and-cut tree. + + CbcNodeInfo objects come in two flavours. A CbcFullNodeInfo object contains + a full record of the information required to recreate a subproblem. + A CbcPartialNodeInfo object expresses this information in terms of + differences from the parent. +*/ + +class CbcNodeInfo { + +public: + + /** \name Constructors & destructors */ +//@{ + /** Default Constructor + + Creates an empty NodeInfo object. + */ + CbcNodeInfo (); + + /// Copy constructor + CbcNodeInfo ( const CbcNodeInfo &); + +#ifdef JJF_ZERO + /** Construct with parent + + Creates a NodeInfo object which knows its parent and assumes it will + in turn have two children. + */ + CbcNodeInfo (CbcNodeInfo * parent); +#endif + + /** Construct with parent and owner + + As for `construct with parent', and attached to \p owner. + */ + CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner); + + /** Destructor + + Note that the destructor will recursively delete the parent if this + nodeInfo is the last child. + */ + virtual ~CbcNodeInfo(); +//@} + + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound and basis + information at node and adds any cuts to the addCuts array. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const = 0 ; + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) = 0; + + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const = 0; + /// Clone + virtual CbcNodeInfo * clone() const = 0; + /// Called when number branches left down to zero + virtual void allBranchesGone() {} +#ifndef JJF_ONE + /// Increment number of references + inline void increment(int amount = 1) { + numberPointingToThis_ += amount;/*printf("CbcNodeInfo %x incremented by %d to %d\n",this,amount,numberPointingToThis_);*/ + } + + /// Decrement number of references and return number left + inline int decrement(int amount = 1) { + numberPointingToThis_ -= amount;/*printf("CbcNodeInfo %x decremented by %d to %d\n",this,amount,numberPointingToThis_);*/ + return numberPointingToThis_; + } +#else + /// Increment number of references + void increment(int amount = 1); + /// Decrement number of references and return number left + int decrement(int amount = 1); +#endif + /** Initialize reference counts + + Initialize the reference counts used for tree maintenance. + */ + + inline void initializeInfo(int number) { + numberPointingToThis_ = number; + numberBranchesLeft_ = number; + } + + /// Return number of branches left in object + inline int numberBranchesLeft() const { + return numberBranchesLeft_; + } + + /// Set number of branches left in object + inline void setNumberBranchesLeft(int value) { + numberBranchesLeft_ = value; + } + + /// Return number of objects pointing to this + inline int numberPointingToThis() const { + return numberPointingToThis_; + } + + /// Set number of objects pointing to this + inline void setNumberPointingToThis(int number) { + numberPointingToThis_ = number; + } + + /// Increment number of objects pointing to this + inline void incrementNumberPointingToThis() { + numberPointingToThis_ ++; + } + + /// Say one branch taken + inline int branchedOn() { + numberPointingToThis_--; + numberBranchesLeft_--; + return numberBranchesLeft_; + } + + /// Say thrown away + inline void throwAway() { + numberPointingToThis_ -= numberBranchesLeft_; + numberBranchesLeft_ = 0; + } + + /// Parent of this + CbcNodeInfo * parent() const { + return parent_; + } + /// Set parent null + inline void nullParent() { + parent_ = NULL; + } + + void addCuts(OsiCuts & cuts, int numberToBranch, //int * whichGenerator, + int numberPointingToThis); + void addCuts(int numberCuts, CbcCountRowCut ** cuts, int numberToBranch); + /** Delete cuts (decrements counts) + Slow unless cuts in same order as saved + */ + void deleteCuts(int numberToDelete, CbcCountRowCut ** cuts); + void deleteCuts(int numberToDelete, int * which); + + /// Really delete a cut + void deleteCut(int whichOne); + + /// Decrement active cut counts + void decrementCuts(int change = 1); + + /// Increment active cut counts + void incrementCuts(int change = 1); + + /// Decrement all active cut counts in chain starting at parent + void decrementParentCuts(CbcModel * model, int change = 1); + + /// Increment all active cut counts in parent chain + void incrementParentCuts(CbcModel * model, int change = 1); + + /// Array of pointers to cuts + inline CbcCountRowCut ** cuts() const { + return cuts_; + } + + /// Number of row cuts (this node) + inline int numberCuts() const { + return numberCuts_; + } + inline void setNumberCuts(int value) { + numberCuts_ = value; + } + + /// Set owner null + inline void nullOwner() { + owner_ = NULL; + } + const inline CbcNode * owner() const { + return owner_; + } + inline CbcNode * mutableOwner() const { + return owner_; + } + /// The node number + inline int nodeNumber() const { + return nodeNumber_; + } + inline void setNodeNumber(int node) { + nodeNumber_ = node; + } + /** Deactivate node information. + 1 - bounds + 2 - cuts + 4 - basis! + 8 - just marked + 16 - symmetry branching worked + */ + void deactivate(int mode = 3); + /// Say if normal + inline bool allActivated() const { + return ((active_&7) == 7); + } + /// Say if marked + inline bool marked() const { + return ((active_&8) != 0); + } + /// Mark + inline void mark() { + active_ |= 8; + } + /// Unmark + inline void unmark() { + active_ &= ~8; + } + /// Get symmetry value (true worked at this node) + inline bool symmetryWorked() const + { return (active_&16) !=0;} + /// Say symmetry worked at this node) + inline void setSymmetryWorked() + { active_ |= 16;} + + /// Branching object for the parent + inline const OsiBranchingObject * parentBranch() const { + return parentBranch_; + } + /// If we need to take off parent based data + void unsetParentBasedData(); +protected: + + /** Number of other nodes pointing to this node. + + Number of existing and potential search tree nodes pointing to this node. + `Existing' means referenced by #parent_ of some other CbcNodeInfo. + `Potential' means children still to be created (#numberBranchesLeft_ of + this CbcNodeInfo). + */ + int numberPointingToThis_; + + /// parent + CbcNodeInfo * parent_; + + /// Copy of the branching object of the parent when the node is created + OsiBranchingObject * parentBranch_; + + /// Owner + CbcNode * owner_; + + /// Number of row cuts (this node) + int numberCuts_; + + /// The node number + int nodeNumber_; + + /// Array of pointers to cuts + CbcCountRowCut ** cuts_; + + /** Number of rows in problem (before these cuts). This + means that for top of chain it must be rows at continuous */ + int numberRows_; + + /** Number of branch arms left to explore at this node + + \todo There seems to be redundancy between this field and + CbcBranchingObject::numberBranchesLeft_. It'd be good to sort out if + both are necessary. + */ + int numberBranchesLeft_; + /** Active node information. + 1 - bounds + 2 - cuts + 4 - basis! + */ + int active_; + +private: + + /// Illegal Assignment operator + CbcNodeInfo & operator=(const CbcNodeInfo& rhs); + + /// routine common to constructors + void setParentBasedData(); +}; + +#endif // CbcNodeInfo_H + diff --git a/thirdparty/linux/include/coin/coin/CbcObject.hpp b/thirdparty/linux/include/coin/coin/CbcObject.hpp new file mode 100644 index 0000000..2fb6794 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcObject.hpp @@ -0,0 +1,272 @@ +// $Id: CbcObject.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcObject_H +#define CbcObject_H + +#include <string> +#include <vector> +#include "OsiBranchingObject.hpp" +class OsiSolverInterface; +class OsiSolverBranch; + +class CbcModel; +class CbcNode; +class CbcNodeInfo; +class CbcBranchingObject; +class OsiChooseVariable; +class CbcObjectUpdateData; +//############################################################################# + +/** Abstract base class for `objects'. + It now just has stuff that OsiObject does not have + + The branching model used in Cbc is based on the idea of an <i>object</i>. + In the abstract, an object is something that has a feasible region, can be + evaluated for infeasibility, can be branched on (<i>i.e.</i>, there's some + constructive action to be taken to move toward feasibility), and allows + comparison of the effect of branching. + + This class (CbcObject) is the base class for an object. To round out the + branching model, the class CbcBranchingObject describes how to perform a + branch, and the class CbcBranchDecision describes how to compare two + CbcBranchingObjects. + + To create a new type of object you need to provide three methods: + #infeasibility(), #feasibleRegion(), and #createCbcBranch(), described below. + + This base class is primarily virtual to allow for any form of structure. + Any form of discontinuity is allowed. + + \todo The notion that all branches are binary (two arms) is wired into the + implementation of CbcObject, CbcBranchingObject, and + CbcBranchDecision. Changing this will require a moderate amount of + recoding. + */ +// This can be used if object wants to skip strong branching +typedef struct { + CbcBranchingObject * possibleBranch; // what a branch would do + double upMovement; // cost going up (and initial away from feasible) + double downMovement; // cost going down + int numIntInfeasUp ; // without odd ones + int numObjInfeasUp ; // just odd ones + bool finishedUp; // true if solver finished + int numItersUp ; // number of iterations in solver + int numIntInfeasDown ; // without odd ones + int numObjInfeasDown ; // just odd ones + bool finishedDown; // true if solver finished + int numItersDown; // number of iterations in solver + int objectNumber; // Which object it is + int fix; // 0 if no fix, 1 if we can fix up, -1 if we can fix down +} CbcStrongInfo; + +class CbcObject : public OsiObject { + +public: + + // Default Constructor + CbcObject (); + + // Useful constructor + CbcObject (CbcModel * model); + + // Copy constructor + CbcObject ( const CbcObject &); + + // Assignment operator + CbcObject & operator=( const CbcObject& rhs); + + /// Clone + virtual CbcObject * clone() const = 0; + + /// Destructor + virtual ~CbcObject (); + + /** Infeasibility of the object + + This is some measure of the infeasibility of the object. It should be + scaled to be in the range [0.0, 0.5], with 0.0 indicating the object + is satisfied. + + The preferred branching direction is returned in preferredWay, + + This is used to prepare for strong branching but should also think of + case when no strong branching + + The object may also compute an estimate of cost of going "up" or "down". + This will probably be based on pseudo-cost ideas + */ +#ifdef CBC_NEW_STYLE_BRANCH + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const = 0; +#else + virtual double infeasibility(const OsiBranchingInformation * /*info*/, + int &preferredWay) const { + return infeasibility(preferredWay); + } + virtual double infeasibility(int &/*preferredWay*/) const { + throw CoinError("Need code", "infeasibility", "CbcBranchBase"); + } +#endif + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + */ + virtual void feasibleRegion() = 0; + /// Dummy one for compatibility + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + */ + virtual double feasibleRegion(OsiSolverInterface * solver) const ; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ +#ifdef CBC_NEW_STYLE_BRANCH + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) = 0; +#else + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * + /* solver */, + const OsiBranchingInformation * + /* info */, int /* way */) { + // return createBranch(solver, info, way); + return NULL; + } + virtual OsiBranchingObject * createBranch(OsiSolverInterface * /*solver*/, + const OsiBranchingInformation * /*info*/, int /*way*/) const { + throw CoinError("Need code", "createBranch", "CbcBranchBase"); + } +#endif + /** Create an Osibranching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual OsiBranchingObject * createOsiBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a good direction. + + If the method cannot generate a feasible point (because there aren't + any, or because it isn't bright enough to find one), it should + return null. + */ + virtual CbcBranchingObject * preferredNewFeasible() const { + return NULL; + } + + /** \brief Given a valid solution (with reduced costs, etc.), + return a branching object which would give a new feasible + point in a bad direction. + + If the method cannot generate a feasible point (because there aren't + any, or because it isn't bright enough to find one), it should + return null. + */ + virtual CbcBranchingObject * notPreferredNewFeasible() const { + return NULL; + } + + /** Reset variable bounds to their original values. + + Bounds may be tightened, so it may be good to be able to set this info in object. + */ + virtual void resetBounds(const OsiSolverInterface * ) {} + + /** Returns floor and ceiling i.e. closest valid points + */ + virtual void floorCeiling(double & floorValue, double & ceilingValue, double value, + double tolerance) const; + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & ) {} + + /// Identifier (normally column number in matrix) + inline int id() const { + return id_; + } + + /** Set identifier (normally column number in matrix) + but 1000000000 to 1100000000 means optional branching object + i.e. code would work without it */ + inline void setId(int value) { + id_ = value; + } + + /** Return true if optional branching object + i.e. code would work without it */ + inline bool optionalObject() const { + return (id_ >= 1000000000 && id_ < 1100000000); + } + + /// Get position in object_ list + inline int position() const { + return position_; + } + + /// Set position in object_ list + inline void setPosition(int position) { + position_ = position; + } + + /// update model + inline void setModel(CbcModel * model) { + model_ = model; + } + + /// Return model + inline CbcModel * model() const { + return model_; + } + + /// If -1 down always chosen first, +1 up always, 0 normal + inline int preferredWay() const { + return preferredWay_; + } + /// Set -1 down always chosen first, +1 up always, 0 normal + inline void setPreferredWay(int value) { + preferredWay_ = value; + } + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * , int , const int * ) {} + /// Initialize for branching + virtual void initializeForBranching(CbcModel * ) {} + +protected: + /// data + + /// Model + CbcModel * model_; + /// Identifier (normally column number in matrix) + int id_; + /// Position in object list + int position_; + /// If -1 down always chosen first, +1 up always, 0 normal + int preferredWay_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcObjectUpdateData.hpp b/thirdparty/linux/include/coin/coin/CbcObjectUpdateData.hpp new file mode 100644 index 0000000..997ad9e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcObjectUpdateData.hpp @@ -0,0 +1,64 @@ +// $Id: CbcObjectUpdateData.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/12/2009 carved from CbcBranchBase + +#ifndef CbcObjectUpdateData_H +#define CbcObjectUpdateData_H + +#include "CbcObject.hpp" +/* This stores data so an object can be updated + */ +class CbcObjectUpdateData { + +public: + + /// Default Constructor + CbcObjectUpdateData (); + + /// Useful constructor + CbcObjectUpdateData (CbcObject * object, + int way, + double change, + int status, + int intDecrease_, + double branchingValue); + + /// Copy constructor + CbcObjectUpdateData ( const CbcObjectUpdateData &); + + /// Assignment operator + CbcObjectUpdateData & operator=( const CbcObjectUpdateData& rhs); + + /// Destructor + virtual ~CbcObjectUpdateData (); + + +public: + /// data + + /// Object + CbcObject * object_; + /// Branch as defined by instance of CbcObject + int way_; + /// Object number + int objectNumber_; + /// Change in objective + double change_; + /// Status 0 Optimal, 1 infeasible, 2 unknown + int status_; + /// Decrease in number unsatisfied + int intDecrease_; + /// Branching value + double branchingValue_; + /// Objective value before branching + double originalObjective_; + /// Current cutoff + double cutoff_; + +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcOrClpParam.cpp b/thirdparty/linux/include/coin/coin/CbcOrClpParam.cpp new file mode 100644 index 0000000..86365ca --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcOrClpParam.cpp @@ -0,0 +1,4134 @@ +/* $Id: CbcOrClpParam.cpp 2175 2015-10-06 08:56:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#include "CoinPragma.hpp" +#include "CoinTime.hpp" +#include "CbcOrClpParam.hpp" + +#include <string> +#include <iostream> +#include <cassert> + +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_CLP +#include "OsiClpSolverInterface.hpp" +#include "ClpSimplex.hpp" +#endif +#include "CbcModel.hpp" +#endif +#include "CoinHelperFunctions.hpp" +#ifdef COIN_HAS_CLP +#include "ClpSimplex.hpp" +#include "ClpFactorization.hpp" +#endif +#ifdef COIN_HAS_READLINE +#include <readline/readline.h> +#include <readline/history.h> +#endif +#ifdef COIN_HAS_CBC +// from CoinSolve +static char coin_prompt[] = "Coin:"; +#else +static char coin_prompt[] = "Clp:"; +#endif +#ifdef CLP_CILK +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#if defined(COIN_HAS_WSMP) && ! defined(USE_EKKWSSMP) +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#include "ClpConfig.h" +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +#endif +static bool doPrinting = true; +static std::string afterEquals = ""; +static char printArray[200]; +#if COIN_INT_MAX==0 +#undef COIN_INT_MAX +#define COIN_INT_MAX 2147483647 +#endif +#if FLUSH_PRINT_BUFFER > 2 +int coinFlushBufferFlag=0; +#endif +void setCbcOrClpPrinting(bool yesNo) +{ + doPrinting = yesNo; +} +//############################################################################# +// Constructors / Destructor / Assignment +//############################################################################# + +//------------------------------------------------------------------- +// Default Constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam () + : type_(CBC_PARAM_NOTUSED_INVALID), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + lengthName_(0), + lengthMatch_(0), + definedKeyWords_(), + name_(), + shortHelp_(), + longHelp_(), + action_(CBC_PARAM_NOTUSED_INVALID), + currentKeyWord_(-1), + display_(0), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ +} +// Other constructors +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + lowerDoubleValue_ = lower; + upperDoubleValue_ = upper; + gutsOfConstructor(); +} +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + lowerIntValue_ = lower; + upperIntValue_ = upper; +} +// Other strings will be added by append +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + std::string firstValue, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(0), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(whereUsed), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + definedKeyWords_.push_back(firstValue); +} +// Action +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + fakeKeyWord_(-1), + fakeValue_(0) +{ + whereUsed_ = whereUsed; + gutsOfConstructor(); +} + +//------------------------------------------------------------------- +// Copy constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) +{ + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; +} + +//------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------- +CbcOrClpParam::~CbcOrClpParam () +{ +} + +//---------------------------------------------------------------- +// Assignment operator +//------------------------------------------------------------------- +CbcOrClpParam & +CbcOrClpParam::operator=(const CbcOrClpParam & rhs) +{ + if (this != &rhs) { + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; + } + return *this; +} +void +CbcOrClpParam::gutsOfConstructor() +{ + std::string::size_type shriekPos = name_.find('!'); + lengthName_ = static_cast<unsigned int>(name_.length()); + if ( shriekPos == std::string::npos ) { + //does not contain '!' + lengthMatch_ = lengthName_; + } else { + lengthMatch_ = static_cast<unsigned int>(shriekPos); + name_ = name_.substr(0, shriekPos) + name_.substr(shriekPos + 1); + lengthName_--; + } +} +// Sets value of fake keyword to current size of keywords +void +CbcOrClpParam::setFakeKeyWord(int fakeValue) +{ + fakeKeyWord_ = static_cast<int>(definedKeyWords_.size()); + assert (fakeKeyWord_>0); + fakeValue_ = fakeValue; + assert (fakeValue_>=0); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ +*/ +int +CbcOrClpParam::currentOptionAsInteger ( ) const +{ + int fakeInteger; + return currentOptionAsInteger(fakeInteger); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ and sets + fakeInteger to value +*/ +int +CbcOrClpParam::currentOptionAsInteger ( int & fakeInteger ) const +{ + fakeInteger=-COIN_INT_MAX; + if (fakeKeyWord_<0) { + return currentKeyWord_; + } else if (currentKeyWord_>=0&¤tKeyWord_<fakeKeyWord_){ + return currentKeyWord_; + } else { + // fake + if (currentKeyWord_<0) + fakeInteger = currentKeyWord_ + 1000; + else + fakeInteger = currentKeyWord_ - 1000; + return fakeValue_; + } +} +// Returns length of name for printing +int +CbcOrClpParam::lengthMatchName ( ) const +{ + if (lengthName_ == lengthMatch_) + return lengthName_; + else + return lengthName_ + 2; +} +// Insert string (only valid for keywords) +void +CbcOrClpParam::append(std::string keyWord) +{ + definedKeyWords_.push_back(keyWord); +} + +int +CbcOrClpParam::matches (std::string input) const +{ + // look up strings to do more elegantly + if (input.length() > lengthName_) { + return 0; + } else { + unsigned int i; + for (i = 0; i < input.length(); i++) { + if (tolower(name_[i]) != tolower(input[i])) + break; + } + if (i < input.length()) { + return 0; + } else if (i >= lengthMatch_) { + return 1; + } else { + // matched but too short + return 2; + } + } +} +// Returns name which could match +std::string +CbcOrClpParam::matchName ( ) const +{ + if (lengthMatch_ == lengthName_) + return name_; + else + return name_.substr(0, lengthMatch_) + "(" + name_.substr(lengthMatch_) + ")"; +} + +// Returns parameter option which matches (-1 if none) +int +CbcOrClpParam::parameterOption ( std::string check ) const +{ + int numberItems = static_cast<int>(definedKeyWords_.size()); + if (!numberItems) { + return -1; + } else { + int whichItem = 0; + unsigned int it; + for (it = 0; it < definedKeyWords_.size(); it++) { + std::string thisOne = definedKeyWords_[it]; + std::string::size_type shriekPos = thisOne.find('!'); + size_t length1 = thisOne.length(); + size_t length2 = length1; + if ( shriekPos != std::string::npos ) { + //contains '!' + length2 = shriekPos; + thisOne = thisOne.substr(0, shriekPos) + + thisOne.substr(shriekPos + 1); + length1 = thisOne.length(); + } + if (check.length() <= length1 && length2 <= check.length()) { + unsigned int i; + for (i = 0; i < check.length(); i++) { + if (tolower(thisOne[i]) != tolower(check[i])) + break; + } + if (i < check.length()) { + whichItem++; + } else if (i >= length2) { + break; + } + } else { + whichItem++; + } + } + if (whichItem < numberItems) { + return whichItem; + } else { + if (fakeKeyWord_<=0) + return -1; + // allow plus or minus + int n; + if (check.substr(0,4)=="plus"||check.substr(0,4)=="PLUS") { + n = 4; + } else if (check.substr(0,5)=="minus"||check.substr(0,5)=="MINUS") { + n = 5; + } else { + return -1; + } + int value = 0; + std::string field=check.substr(n); + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = static_cast<int>(strtol(start, &endPointer, 10)); + if (*endPointer != '\0') { + return -1; + } + if (n==4) + return value + 1000; + else + return -value - 1000; + } else { + return -1; + } + } + } +} +// Prints parameter options +void +CbcOrClpParam::printOptions ( ) const +{ + std::cout << "<Possible options for " << name_ << " are:"; + unsigned int it; + for (it = 0; it < definedKeyWords_.size(); it++) { + std::string thisOne = definedKeyWords_[it]; + std::string::size_type shriekPos = thisOne.find('!'); + if ( shriekPos != std::string::npos ) { + //contains '!' + thisOne = thisOne.substr(0, shriekPos) + + "(" + thisOne.substr(shriekPos + 1) + ")"; + } + std::cout << " " << thisOne; + } + assert (currentKeyWord_ >= 0 && currentKeyWord_ < static_cast<int>(definedKeyWords_.size())); + std::string current = definedKeyWords_[currentKeyWord_]; + std::string::size_type shriekPos = current.find('!'); + if ( shriekPos != std::string::npos ) { + //contains '!' + current = current.substr(0, shriekPos) + + "(" + current.substr(shriekPos + 1) + ")"; + } + std::cout << ";\n\tcurrent " << current << ">" << std::endl; +} +// Print action and string +void +CbcOrClpParam::printString() const +{ + if (name_ == "directory") + std::cout << "Current working directory is " << stringValue_ << std::endl; + else if (name_.substr(0, 6) == "printM") + std::cout << "Current value of printMask is " << stringValue_ << std::endl; + else + std::cout << "Current default (if $ as parameter) for " << name_ + << " is " << stringValue_ << std::endl; +} +void CoinReadPrintit(const char * input) +{ + int length = static_cast<int>(strlen(input)); + char temp[101]; + int i; + int n = 0; + for (i = 0; i < length; i++) { + if (input[i] == '\n') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n >= 65 && input[i] == ' ') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n || input[i] != ' ') { + temp[n++] = input[i]; + } + } + if (n) { + temp[n] = '\0'; + std::cout << temp << std::endl; + } +} +// Print Long help +void +CbcOrClpParam::printLongHelp() const +{ + if (type_ >= 1 && type_ < 400) { + CoinReadPrintit(longHelp_.c_str()); + if (type_ < CLP_PARAM_INT_SOLVERLOGLEVEL) { + printf("<Range of values is %g to %g;\n\tcurrent %g>\n", lowerDoubleValue_, upperDoubleValue_, doubleValue_); + assert (upperDoubleValue_ > lowerDoubleValue_); + } else if (type_ < CLP_PARAM_STR_DIRECTION) { + printf("<Range of values is %d to %d;\n\tcurrent %d>\n", lowerIntValue_, upperIntValue_, intValue_); + assert (upperIntValue_ > lowerIntValue_); + } else if (type_ < CLP_PARAM_ACTION_DIRECTORY) { + printOptions(); + } + } +} +#ifdef COIN_HAS_CBC +int +CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->getDblParam(OsiDualTolerance, oldValue); + model->setDblParam(OsiDualTolerance, value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->getDblParam(OsiPrimalTolerance, oldValue); + model->setDblParam(OsiPrimalTolerance, value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +#endif +#ifdef COIN_HAS_CLP +int +CbcOrClpParam::setDoubleParameter (ClpSimplex * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode) +{ + double oldValue = doubleValue_; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->setDualTolerance(value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->setPrimalTolerance(value); + break; + case CLP_PARAM_DBL_ZEROTOLERANCE: + model->setSmallElementValue(value); + break; + case CLP_PARAM_DBL_DUALBOUND: + model->setDualBound(value); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + model->setInfeasibilityCost(value); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + model->setMaximumSeconds(value); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + model->setObjectiveScale(value); + break; + case CLP_PARAM_DBL_RHSSCALE: + model->setRhsScale(value); + break; + case CLP_PARAM_DBL_PRESOLVETOLERANCE: + model->setDblParam(ClpPresolveTolerance, value); + break; + default: + break; + } + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (ClpSimplex * model) const +{ + double value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_DUALTOLERANCE: + value = model->dualTolerance(); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = model->primalTolerance(); + break; +#endif + case CLP_PARAM_DBL_ZEROTOLERANCE: + value = model->getSmallElementValue(); + break; + case CLP_PARAM_DBL_DUALBOUND: + value = model->dualBound(); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + value = model->infeasibilityCost(); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + value = model->maximumSeconds(); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + value = model->objectiveScale(); + break; + case CLP_PARAM_DBL_RHSSCALE: + value = model->rhsScale(); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (ClpSimplex * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode) +{ + int oldValue = intValue_; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + intValue_ = value; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->setLogLevel(value); + if (value > 2) + model->factorization()->messageLevel(8); + else + model->factorization()->messageLevel(0); + break; + case CLP_PARAM_INT_MAXFACTOR: + model->factorization()->maximumPivots(value); + break; + case CLP_PARAM_INT_PERTVALUE: + model->setPerturbation(value); + break; + case CLP_PARAM_INT_MAXITERATION: + model->setMaximumIterations(value); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + model->setSpecialOptions(value); + break; + case CLP_PARAM_INT_RANDOMSEED: + { + if (value==0) { + double time = fabs(CoinGetTimeOfDay()); + while (time>=COIN_INT_MAX) + time *= 0.5; + value = static_cast<int>(time); + sprintf(printArray, "using time of day %s was changed from %d to %d", + name_.c_str(), oldValue, value); + } + model->setRandomSeed(value); + } + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + model->setMoreSpecialOptions(value); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + model->setNumberThreads(value); + break; +#endif +#endif + default: + break; + } + } + return printArray; +} +int +CbcOrClpParam::intParameter (ClpSimplex * model) const +{ + int value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->logLevel(); + break; +#endif + case CLP_PARAM_INT_MAXFACTOR: + value = model->factorization()->maximumPivots(); + break; + break; + case CLP_PARAM_INT_PERTVALUE: + value = model->perturbation(); + break; + case CLP_PARAM_INT_MAXITERATION: + value = model->maximumIterations(); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + value = model->specialOptions(); + break; + case CLP_PARAM_INT_RANDOMSEED: + value = model->randomNumberGenerator()->getSeed(); + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + value = model->moreSpecialOptions(); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model->numberThreads(); + break; +#endif +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +int +CbcOrClpParam::checkDoubleParameter (double value) const +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + return 1; + } else { + return 0; + } +} +#ifdef COIN_HAS_CBC +double +CbcOrClpParam::doubleParameter (OsiSolverInterface * +#ifndef NDEBUG + model +#endif + ) const +{ + double value = 0.0; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + assert(model->getDblParam(OsiDualTolerance, value)); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + assert(model->getDblParam(OsiPrimalTolerance, value)); + break; + default: + return doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (OsiSolverInterface * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + int oldValue = intValue_; + intValue_ = oldValue; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->messageHandler()->setLogLevel(value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (OsiSolverInterface * model) const +{ + int value = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->messageHandler()->logLevel(); + break; + default: + value = intValue_; + break; + } + return value; +} +int +CbcOrClpParam::setDoubleParameter (CbcModel &model, double value) +{ + int returnCode=0; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + oldValue = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + model.setDblParam(CbcModel::CbcInfeasibilityWeight, value); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + oldValue = model.getDblParam(CbcModel::CbcIntegerTolerance); + model.setDblParam(CbcModel::CbcIntegerTolerance, value); + break; + case CBC_PARAM_DBL_INCREMENT: + oldValue = model.getDblParam(CbcModel::CbcCutoffIncrement); + model.setDblParam(CbcModel::CbcCutoffIncrement, value); + case CBC_PARAM_DBL_ALLOWABLEGAP: + oldValue = model.getDblParam(CbcModel::CbcAllowableGap); + model.setDblParam(CbcModel::CbcAllowableGap, value); + break; + case CBC_PARAM_DBL_GAPRATIO: + oldValue = model.getDblParam(CbcModel::CbcAllowableFractionGap); + model.setDblParam(CbcModel::CbcAllowableFractionGap, value); + break; + case CBC_PARAM_DBL_CUTOFF: + oldValue = model.getCutoff(); + model.setCutoff(value); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + { + //OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver()); + //ClpSimplex * lpSolver = clpSolver->getModelPtr(); + //lpSolver->setMaximumSeconds(value); + model.setDblParam(CbcModel::CbcMaximumSeconds, value) ; + } + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + setDoubleParameter(model.solver(), value); + return 0; // to avoid message + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (CbcModel &model) const +{ + double value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + value = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + value = model.getDblParam(CbcModel::CbcIntegerTolerance); + break; + case CBC_PARAM_DBL_INCREMENT: + value = model.getDblParam(CbcModel::CbcCutoffIncrement); + break; + case CBC_PARAM_DBL_ALLOWABLEGAP: + value = model.getDblParam(CbcModel::CbcAllowableGap); + break; + case CBC_PARAM_DBL_GAPRATIO: + value = model.getDblParam(CbcModel::CbcAllowableFractionGap); + break; + case CBC_PARAM_DBL_CUTOFF: + value = model.getCutoff(); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + value = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = doubleParameter(model.solver()); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (CbcModel &model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + printArray[0] = '\0'; + if (value==intValue_) + return printArray; + int oldValue = intValue_; + intValue_ = value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + oldValue = model.messageHandler()->logLevel(); + model.messageHandler()->setLogLevel(CoinAbs(value)); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + oldValue = model.solver()->messageHandler()->logLevel(); + model.solver()->messageHandler()->setLogLevel(value); + break; + case CBC_PARAM_INT_MAXNODES: + oldValue = model.getIntParam(CbcModel::CbcMaxNumNode); + model.setIntParam(CbcModel::CbcMaxNumNode, value); + break; + case CBC_PARAM_INT_MAXSOLS: + oldValue = model.getIntParam(CbcModel::CbcMaxNumSol); + model.setIntParam(CbcModel::CbcMaxNumSol, value); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + oldValue = model.maximumSavedSolutions(); + model.setMaximumSavedSolutions(value); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + oldValue = model.numberStrong(); + model.setNumberStrong(value); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + oldValue = model.numberBeforeTrust(); + model.setNumberBeforeTrust(value); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + oldValue = model.numberAnalyzeIterations(); + model.setNumberAnalyzeIterations(value); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + oldValue = model.getMaximumCutPasses(); + model.setMaximumCutPasses(value); + break; + case CBC_PARAM_INT_CUTPASS: + oldValue = model.getMaximumCutPassesAtRoot(); + model.setMaximumCutPassesAtRoot(value); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + oldValue = model.getNumberThreads(); + model.setNumberThreads(value); + break; +#endif + case CBC_PARAM_INT_RANDOMSEED: + oldValue = model.getRandomSeed(); + model.setRandomSeed(value); + break; +#endif + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (CbcModel &model) const +{ + int value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + value = model.messageHandler()->logLevel(); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model.solver()->messageHandler()->logLevel(); + break; + case CBC_PARAM_INT_MAXNODES: + value = model.getIntParam(CbcModel::CbcMaxNumNode); + break; + case CBC_PARAM_INT_MAXSOLS: + value = model.getIntParam(CbcModel::CbcMaxNumSol); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + value = model.maximumSavedSolutions(); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + value = model.numberStrong(); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + value = model.numberBeforeTrust(); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + value = model.numberAnalyzeIterations(); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + value = model.getMaximumCutPasses(); + break; + case CBC_PARAM_INT_CUTPASS: + value = model.getMaximumCutPassesAtRoot(); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model.getNumberThreads(); +#endif + case CBC_PARAM_INT_RANDOMSEED: + value = model.getRandomSeed(); + break; +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +// Sets current parameter option using string +void +CbcOrClpParam::setCurrentOption ( const std::string value ) +{ + int action = parameterOption(value); + if (action >= 0) + currentKeyWord_ = action; +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif +} +// Sets current parameter option +void +CbcOrClpParam::setCurrentOption ( int value , bool printIt) +{ + if (printIt && value != currentKeyWord_) + std::cout << "Option for " << name_ << " changed from " + << definedKeyWords_[currentKeyWord_] << " to " + << definedKeyWords_[value] << std::endl; + +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif + currentKeyWord_ = value; +} +// Sets current parameter option and returns printable string +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( int value ) +{ + if (value != currentKeyWord_) { + char current[100]; + char newString[100]; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) + strcpy(current,definedKeyWords_[currentKeyWord_].c_str()); + else if (currentKeyWord_<0) + sprintf(current,"minus%d",-currentKeyWord_-1000); + else + sprintf(current,"plus%d",currentKeyWord_-1000); + if (value>=0&&(fakeKeyWord_<=0||value<fakeKeyWord_) ) + strcpy(newString,definedKeyWords_[value].c_str()); + else if (value<0) + sprintf(newString,"minus%d",-value-1000); + else + sprintf(newString,"plus%d",value-1000); + sprintf(printArray, "Option for %s changed from %s to %s", + name_.c_str(), current, newString); +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=value; +#endif + currentKeyWord_ = value; + } else { + printArray[0] = '\0'; + } + return printArray; +} +// Sets current parameter option using string with message +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( const std::string value ) +{ + int action = parameterOption(value); + char current[100]; + printArray[0] = '\0'; + if (action >= 0) { +#if FLUSH_PRINT_BUFFER > 2 + if (name_=="bufferedMode") + coinFlushBufferFlag=action; +#endif + if (action == currentKeyWord_) + return NULL; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) + strcpy(current,definedKeyWords_[currentKeyWord_].c_str()); + else if (currentKeyWord_<0) + sprintf(current,"minus%d",-currentKeyWord_-1000); + else + sprintf(current,"plus%d",currentKeyWord_-1000); + sprintf(printArray, "Option for %s changed from %s to %s", + name_.c_str(), current, value.c_str()); + currentKeyWord_ = action; + } else { + sprintf(printArray, "Option for %s given illegal value %s", + name_.c_str(), value.c_str()); + } + return printArray; +} +void +CbcOrClpParam::setIntValue ( int value ) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerIntValue_ << " to " << + upperIntValue_ << std::endl; + } else { + intValue_ = value; + } +} +const char * +CbcOrClpParam::setIntValueWithMessage ( int value ) +{ + printArray[0] = '\0'; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value,name_.c_str(),lowerIntValue_,upperIntValue_); + } else { + if (value==intValue_) + return NULL; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), intValue_, value); + intValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setDoubleValue ( double value ) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + } else { + doubleValue_ = value; + } +} +const char * +CbcOrClpParam::setDoubleValueWithMessage ( double value ) +{ + printArray[0] = '\0'; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value,name_.c_str(),lowerDoubleValue_,upperDoubleValue_); + } else { + if (value==doubleValue_) + return NULL; + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), doubleValue_, value); + doubleValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setStringValue ( std::string value ) +{ + stringValue_ = value; +} +static char line[1000]; +static char * where = NULL; +extern int CbcOrClpRead_mode; +int CbcOrClpEnvironmentIndex = -1; +static size_t fillEnv() +{ +#if defined(_MSC_VER) || defined(__MSVCRT__) + return 0; +#else + // Don't think it will work on Windows + char * environ = getenv("CBC_CLP_ENVIRONMENT"); + size_t length = 0; + if (environ) { + length = strlen(environ); + if (CbcOrClpEnvironmentIndex < static_cast<int>(length)) { + // find next non blank + char * whereEnv = environ + CbcOrClpEnvironmentIndex; + // munch white space + while (*whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ') + whereEnv++; + // copy + char * put = line; + while ( *whereEnv != '\0' ) { + if ( *whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ' ) { + break; + } + *put = *whereEnv; + put++; + assert (put - line < 1000); + whereEnv++; + } + CbcOrClpEnvironmentIndex = static_cast<int>(whereEnv - environ); + *put = '\0'; + length = strlen(line); + } else { + length = 0; + } + } + if (!length) + CbcOrClpEnvironmentIndex = -1; + return length; +#endif +} +extern FILE * CbcOrClpReadCommand; +// Simple read stuff +std::string +CoinReadNextField() +{ + std::string field; + if (!where) { + // need new line +#ifdef COIN_HAS_READLINE + if (CbcOrClpReadCommand == stdin) { + // Get a line from the user. + where = readline (coin_prompt); + + // If the line has any text in it, save it on the history. + if (where) { + if ( *where) + add_history (where); + strcpy(line, where); + free(where); + } + } else { + where = fgets(line, 1000, CbcOrClpReadCommand); + } +#else + if (CbcOrClpReadCommand == stdin) { + fputs(coin_prompt,stdout); + fflush(stdout); + } + where = fgets(line, 1000, CbcOrClpReadCommand); +#endif + if (!where) + return field; // EOF + where = line; + // clean image + char * lastNonBlank = line - 1; + while ( *where != '\0' ) { + if ( *where != '\t' && *where < ' ' ) { + break; + } else if ( *where != '\t' && *where != ' ') { + lastNonBlank = where; + } + where++; + } + where = line; + *(lastNonBlank + 1) = '\0'; + } + // munch white space + while (*where == ' ' || *where == '\t') + where++; + char * saveWhere = where; + while (*where != ' ' && *where != '\t' && *where != '\0') + where++; + if (where != saveWhere) { + char save = *where; + *where = '\0'; + //convert to string + field = saveWhere; + *where = save; + } else { + where = NULL; + field = "EOL"; + } + return field; +} + +std::string +CoinReadGetCommand(int argc, const char *argv[]) +{ + std::string field = "EOL"; + // say no = + afterEquals = ""; + while (field == "EOL") { + if (CbcOrClpRead_mode > 0) { + if ((CbcOrClpRead_mode < argc && argv[CbcOrClpRead_mode]) || + CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + field = argv[CbcOrClpRead_mode++]; + } else { + if (fillEnv()) { + field = line; + } else { + // not there + continue; + } + } + if (field == "-") { + std::cout << "Switching to line mode" << std::endl; + CbcOrClpRead_mode = -1; + field = CoinReadNextField(); + } else if (field[0] != '-') { + if (CbcOrClpRead_mode != 2) { + // now allow std::cout<<"skipping non-command "<<field<<std::endl; + // field="EOL"; // skip + } else if (CbcOrClpEnvironmentIndex < 0) { + // special dispensation - taken as -import name + CbcOrClpRead_mode--; + field = "import"; + } + } else { + if (field != "--") { + // take off - + field = field.substr(1); + } else { + // special dispensation - taken as -import -- + CbcOrClpRead_mode--; + field = "import"; + } + } + } else { + field = ""; + } + } else { + field = CoinReadNextField(); + } + } + // if = then modify and save + std::string::size_type found = field.find('='); + if (found != std::string::npos) { + afterEquals = field.substr(found + 1); + field = field.substr(0, found); + } + //std::cout<<field<<std::endl; + return field; +} +std::string +CoinReadGetString(int argc, const char *argv[]) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + if (argv[CbcOrClpRead_mode][0] != '-') { + field = argv[CbcOrClpRead_mode++]; + } else if (!strcmp(argv[CbcOrClpRead_mode], "--")) { + field = argv[CbcOrClpRead_mode++]; + // -- means import from stdin + field = "-"; + } + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + //std::cout<<field<<std::endl; + return field; +} +// valid 0 - okay, 1 bad, 2 not there +int +CoinReadGetIntField(int argc, const char *argv[], int * valid) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + long int value = 0; + //std::cout<<field<<std::endl; + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = strtol(start, &endPointer, 10); + if (*endPointer == '\0') { + *valid = 0; + } else { + *valid = 1; + std::cout << "String of " << field; + } + } else { + *valid = 2; + } + return static_cast<int>(value); +} +double +CoinReadGetDoubleField(int argc, const char *argv[], int * valid) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + double value = 0.0; + //std::cout<<field<<std::endl; + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = strtod(start, &endPointer); + if (*endPointer == '\0') { + *valid = 0; + } else { + *valid = 1; + std::cout << "String of " << field; + } + } else { + *valid = 2; + } + return value; +} +/* + Subroutine to establish the cbc parameter array. See the description of + class CbcOrClpParam for details. Pulled from C..Main() for clarity. +*/ +void +establishParams (int &numberParameters, CbcOrClpParam *const parameters) +{ + numberParameters = 0; + parameters[numberParameters++] = + CbcOrClpParam("?", "For help", CBC_PARAM_GENERALQUERY, 7, 0); + parameters[numberParameters++] = + CbcOrClpParam("???", "For help", CBC_PARAM_FULLGENERALQUERY, 7, 0); + parameters[numberParameters++] = + CbcOrClpParam("-", "From stdin", + CLP_PARAM_ACTION_STDIN, 3, 0); +#ifdef ABC_INHERIT + parameters[numberParameters++] = + CbcOrClpParam("abc", "Whether to visit Aboca", + "off", CLP_PARAM_STR_ABCWANTED, 7, 0); + parameters[numberParameters-1].append("one"); + parameters[numberParameters-1].append("two"); + parameters[numberParameters-1].append("three"); + parameters[numberParameters-1].append("four"); + parameters[numberParameters-1].append("five"); + parameters[numberParameters-1].append("six"); + parameters[numberParameters-1].append("seven"); + parameters[numberParameters-1].append("eight"); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("decide"); + parameters[numberParameters-1].setFakeKeyWord(10); + parameters[numberParameters-1].setLonghelp + ( + "Decide whether to use A Basic Optimization Code (Accelerated?) \ +and whether to try going parallel!" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("allC!ommands", "Whether to print less used commands", + "no", CLP_PARAM_STR_ALLCOMMANDS); + parameters[numberParameters-1].append("more"); + parameters[numberParameters-1].append("all"); + parameters[numberParameters-1].setLonghelp + ( + "For the sake of your sanity, only the more useful and simple commands \ +are printed out on ?." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("allow!ableGap", "Stop when gap between best possible and \ +best less than this", + 0.0, 1.0e20, CBC_PARAM_DBL_ALLOWABLEGAP); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "If the gap between best solution and best possible solution is less than this \ +then the search will be terminated. Also see ratioGap." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("allS!lack", "Set basis back to all slack and reset solution", + CLP_PARAM_ACTION_ALLSLACK, 3); + parameters[numberParameters-1].setLonghelp + ( + "Mainly useful for tuning purposes. Normally the first dual or primal will be using an all slack \ +basis anyway." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("artif!icialCost", "Costs >= this treated as artificials in feasibility pump", + 0.0, COIN_DBL_MAX, CBC_PARAM_DBL_ARTIFICIALCOST, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise variables with costs >= this are treated as artificials and fixed to lower bound in feasibility pump" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("auto!Scale", "Whether to scale objective, rhs and bounds of problem if they look odd", + "off", CLP_PARAM_STR_AUTOSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If you think you may get odd objective values or large equality rows etc then\ + it may be worth setting this true. It is still experimental and you may prefer\ + to use objective!Scale and rhs!Scale." + ); + parameters[numberParameters++] = + CbcOrClpParam("barr!ier", "Solve using primal dual predictor corrector algorithm", + CLP_PARAM_ACTION_BARRIER); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the current model using the primal dual predictor \ +corrector algorithm. You may want to link in an alternative \ +ordering and factorization. It will also solve models \ +with quadratic objectives." + + ); + parameters[numberParameters++] = + CbcOrClpParam("basisI!n", "Import basis from bas file", + CLP_PARAM_ACTION_BASISIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format basis file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libz then it can read compressed\ + files 'xxxxxxxx.gz' or xxxxxxxx.bz2." + ); + parameters[numberParameters++] = + CbcOrClpParam("basisO!ut", "Export basis as bas file", + CLP_PARAM_ACTION_BASISOUT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format basis file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.bas'." + ); + parameters[numberParameters++] = + CbcOrClpParam("biasLU", "Whether factorization biased towards U", + "UU", CLP_PARAM_STR_BIASLU, 2, 0); + parameters[numberParameters-1].append("UX"); + parameters[numberParameters-1].append("LX"); + parameters[numberParameters-1].append("LL"); + parameters[numberParameters-1].setCurrentOption("LX"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("branch!AndCut", "Do Branch and Cut", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "This does branch and cut. There are many parameters which can affect the performance. \ +First just try with default settings and look carefully at the log file. Did cuts help? Did they take too long? \ +Look at output to see which cuts were effective and then do some tuning. You will see that the \ +options for cuts are off, on, root and ifmove, forceon. Off is \ +obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \ +'depth'). Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \ +look as if they are doing some good and moving the objective value. Forceon is same as on but forces code to use \ +cut generator at every node. For probing forceonbut just does fixing probing in tree - not strengthening etc. \ +If pre-processing reduced the size of the \ +problem or strengthened many coefficients then it is probably wise to leave it on. Switch off heuristics \ +which did not provide solutions. The other major area to look at is the search. Hopefully good solutions \ +were obtained fairly early in the search so the important point is to select the best variable to branch on. \ +See whether strong branching did a good job - or did it just take a lot of iterations. Adjust the strongBranching \ +and trustPseudoCosts parameters. If cuts did a good job, then you may wish to \ +have more rounds of cuts - see passC!uts and passT!ree." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("bscale", "Whether to scale in barrier (and ordering speed)", + "off", CLP_PARAM_STR_BARRIERSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("off1"); + parameters[numberParameters-1].append("on1"); + parameters[numberParameters-1].append("off2"); + parameters[numberParameters-1].append("on2"); +#if FLUSH_PRINT_BUFFER > 2 + parameters[numberParameters++] = + CbcOrClpParam("buff!eredMode", "Whether to flush print buffer", + "on", CLP_PARAM_STR_BUFFER_MODE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Default is on, off switches on unbuffered output" + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("chol!esky", "Which cholesky algorithm", + "native", CLP_PARAM_STR_CHOLESKY, 7); + parameters[numberParameters-1].append("dense"); + //#ifdef FOREIGN_BARRIER +#ifdef COIN_HAS_WSMP + parameters[numberParameters-1].append("fudge!Long"); + parameters[numberParameters-1].append("wssmp"); +#else + parameters[numberParameters-1].append("fudge!Long_dummy"); + parameters[numberParameters-1].append("wssmp_dummy"); +#endif +#if defined(COIN_HAS_AMD) || defined(COIN_HAS_CHOLMOD) || defined(COIN_HAS_GLPK) + parameters[numberParameters-1].append("Uni!versityOfFlorida"); +#else + parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy"); +#endif +#ifdef TAUCS_BARRIER + parameters[numberParameters-1].append("Taucs"); +#else + parameters[numberParameters-1].append("Taucs_dummy"); +#endif +#ifdef COIN_HAS_MUMPS + parameters[numberParameters-1].append("Mumps"); +#else + parameters[numberParameters-1].append("Mumps_dummy"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "For a barrier code to be effective it needs a good Cholesky ordering and factorization. \ +The native ordering and factorization is not state of the art, although acceptable. \ +You may want to link in one from another source. See Makefile.locations for some \ +possibilities." + ); + //#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("clique!Cuts", "Whether to use Clique cuts", + "off", CBC_PARAM_STR_CLIQUECUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on clique cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("combine!Solutions", "Whether to use combine solution heuristic", + "off", CBC_PARAM_STR_COMBINE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("onquick"); + parameters[numberParameters-1].append("bothquick"); + parameters[numberParameters-1].append("beforequick"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by just \ +using variables which have appeared in one or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("combine2!Solutions", "Whether to use crossover solution heuristic", + "off", CBC_PARAM_STR_CROSSOVER2); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by \ +fixing variables which have same value in two or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("constraint!fromCutoff", "Whether to use cutoff as constraint", + "off", CBC_PARAM_STR_CUTOFF_CONSTRAINT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("variable"); + parameters[numberParameters-1].append("forcevariable"); + parameters[numberParameters-1].append("conflict"); + parameters[numberParameters-1].setLonghelp + ( + "This adds the objective as a constraint with best solution as RHS" + ); + parameters[numberParameters++] = + CbcOrClpParam("cost!Strategy", "How to use costs as priorities", + "off", CBC_PARAM_STR_COSTSTRATEGY); + parameters[numberParameters-1].append("pri!orities"); + parameters[numberParameters-1].append("column!Order?"); + parameters[numberParameters-1].append("01f!irst?"); + parameters[numberParameters-1].append("01l!ast?"); + parameters[numberParameters-1].append("length!?"); + parameters[numberParameters-1].append("singletons"); + parameters[numberParameters-1].append("nonzero"); + parameters[numberParameters-1].append("general!Force?"); + parameters[numberParameters-1].setLonghelp + ( + "This orders the variables in order of their absolute costs - with largest cost ones being branched on \ +first. This primitive strategy can be surprsingly effective. The column order\ + option is obviously not on costs but easy to code here." + ); + parameters[numberParameters++] = + CbcOrClpParam("cplex!Use", "Whether to use Cplex!", + "off", CBC_PARAM_STR_CPX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + " If the user has Cplex, but wants to use some of Cbc's heuristics \ +then you can! If this is on, then Cbc will get to the root node and then \ +hand over to Cplex. If heuristics find a solution this can be significantly \ +quicker. You will probably want to switch off Cbc's cuts as Cplex thinks \ +they are genuine constraints. It is also probable that you want to switch \ +off preprocessing, although for difficult problems it is worth trying \ +both." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("cpp!Generate", "Generates C++ code", + -1, 50000, CLP_PARAM_INT_CPP, 1); + parameters[numberParameters-1].setLonghelp + ( + "Once you like what the stand-alone solver does then this allows \ +you to generate user_driver.cpp which approximates the code. \ +0 gives simplest driver, 1 generates saves and restores, 2 \ +generates saves and restores even for variables at default value. \ +4 bit in cbc generates size dependent code rather than computed values. \ +This is now deprecated as you can call stand-alone solver - see \ +Cbc/examples/driver4.cpp." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("crash", "Whether to create basis for problem", + "off", CLP_PARAM_STR_CRASH); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("so!low_halim"); + parameters[numberParameters-1].append("lots"); +#ifdef CLP_INHERIT_MODE + parameters[numberParameters-1].append("dual"); + parameters[numberParameters-1].append("dw"); + parameters[numberParameters-1].append("idiot"); +#else + parameters[numberParameters-1].append("idiot1"); + parameters[numberParameters-1].append("idiot2"); + parameters[numberParameters-1].append("idiot3"); + parameters[numberParameters-1].append("idiot4"); + parameters[numberParameters-1].append("idiot5"); + parameters[numberParameters-1].append("idiot6"); + parameters[numberParameters-1].append("idiot7"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If crash is set on and there is an all slack basis then Clp will flip or put structural\ + variables into basis with the aim of getting dual feasible. On the whole dual seems to be\ + better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \ +I have also added a variant due to Solow and Halim which is as on but just flip."); + parameters[numberParameters++] = + CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier", + "on", CLP_PARAM_STR_CROSSOVER); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("maybe"); + parameters[numberParameters-1].append("presolve"); + parameters[numberParameters-1].setLonghelp + ( + "Interior point algorithms do not obtain a basic solution (and \ +the feasibility criterion is a bit suspect (JJF)). This option will crossover \ +to a basic solution suitable for ranging or branch and cut. With the current state \ +of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \ +presolve as well) - the option maybe does this." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("csv!Statistics", "Create one line of statistics", + CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1); + parameters[numberParameters-1].setLonghelp + ( + "This appends statistics to given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. Adds header if file empty or does not exist." + ); + parameters[numberParameters++] = + CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts", + -1, 999999, CBC_PARAM_INT_CUTDEPTH); + parameters[numberParameters-1].setLonghelp + ( + "Cut generators may be - off, on only at root, on if they look possible \ +and on. If they are done every node then that is that, but it may be worth doing them \ +every so often. The original method was every so many nodes but it is more logical \ +to do it whenever depth in tree is a multiple of K. This option does that and defaults \ +to -1 (off -> code decides)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cutL!ength", "Length of a cut", + -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH); + parameters[numberParameters-1].setLonghelp + ( + "At present this only applies to Gomory cuts. -1 (default) leaves as is. \ +Any value >0 says that all cuts <= this length can be generated both at \ +root node and in tree. 0 says to use some dynamic lengths. If value >=10,000,000 \ +then the length in tree is value%10000000 - so 10000100 means unlimited length \ +at root and 100 in tree." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cuto!ff", "All solutions must be better than this", + -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF); + parameters[numberParameters-1].setDoubleValue(1.0e50); + parameters[numberParameters-1].setLonghelp + ( + "All solutions must be better than this value (in a minimization sense). \ +This is also set by code whenever it obtains a solution and is set to value of \ +objective for solution minus cutoff increment." + ); + parameters[numberParameters++] = + CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off", + "off", CBC_PARAM_STR_CUTSSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all cuts (apart from Reduce and Split). Then you can do \ +individual ones off or on \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("debug!In", "read valid solution from file", + CLP_PARAM_ACTION_DEBUG, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will read a solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set.\n\n\ +If set to create it will create a file called debug.file after search.\n\n\ +The idea is that if you suspect a bad cut generator \ +you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \ +re-run with debug set to 'debug.file' The create case has same effect as saveSolution." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("decomp!ose", "Whether to try decomposition", + -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1); + parameters[numberParameters-1].setLonghelp + ( + "0 - off, 1 choose blocks >1 use as blocks \ +Dantzig Wolfe if primal, Benders if dual \ +- uses sprint pass for number of passes" + ); + parameters[numberParameters-1].setIntValue(0); +#if CLP_MULTIPLE_FACTORIZATIONS >0 + parameters[numberParameters++] = + CbcOrClpParam("dense!Threshold", "Whether to use dense factorization", + -1, 10000, CBC_PARAM_INT_DENSE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use dense factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "Rather a complicated parameter but can be useful. -1 means off for large problems but on as if -12 for problems where rows+columns<500, -2 \ +means use Cplex if it is linked in. Otherwise if negative then go into depth first complete search fast branch and bound when depth>= -value-2 (so -3 will use this at depth>=1). This mode is only switched on after 500 nodes. If you really want to switch it off for small problems then set this to -999. If >=0 the value doesn't matter very much. The code will do approximately 100 nodes of fast branch and bound every now and then at depth>=5. The actual logic is too twisted to describe here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dextra3", "Extra double parameter 3", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra4", "Extra double parameter 4", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra5", "Extra double parameter 5", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search", + "off", CBC_PARAM_STR_DINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Distance induced neighborhood Search. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("direction", "Minimize or Maximize", + "min!imize", CLP_PARAM_STR_DIRECTION); + parameters[numberParameters-1].append("max!imize"); + parameters[numberParameters-1].append("zero"); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'direction maximize' for maximization.\n\ +You can also use the parameters 'maximize' or 'minimize'." + ); + parameters[numberParameters++] = + CbcOrClpParam("directory", "Set Default directory for import etc.", + CLP_PARAM_ACTION_DIRECTORY); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory which import, export, saveModel, restoreModel etc will use.\ + It is initialized to './'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.", + CLP_PARAM_ACTION_DIRSAMPLE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the COIN-OR sample problems reside. It is\ + used only when -unitTest is passed to clp. clp will pick up the test problems\ + from this directory.\ + It is initialized to '../../Data/Sample'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.", + CLP_PARAM_ACTION_DIRNETLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the netlib problems reside. One can get\ + the netlib problems from COIN-OR or from the main netlib site. This\ + parameter is used only when -netlib is passed to clp. clp will pick up the\ + netlib problems from this directory. If clp is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/Netlib'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.", + CBC_PARAM_ACTION_DIRMIPLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the miplib 2003 problems reside. One can\ + get the miplib problems from COIN-OR or from the main miplib site. This\ + parameter is used only when -miplib is passed to cbc. cbc will pick up the\ + miplib problems from this directory. If cbc is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/miplib3'" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("diveO!pt", "Diving options", + -1, 200000, CBC_PARAM_INT_DIVEOPT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >2 && <20 then modify diving options - \ + \n\t3 only at root and if no solution, \ + \n\t4 only at root and if this heuristic has not got solution, \ + \n\t5 decay only if no solution, \ + \n\t6 if depth <3 or decay, \ + \n\t7 run up to 2 times if solution found 4 otherwise, \ + \n\t>10 All only at root (DivingC normal as value-10), \ + \n\t>20 All with value-20)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("diveS!olves", "Diving solve option", + -1, 200000, CBC_PARAM_INT_DIVEOPTSOLVES, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >0 then do up to this many solves. Last digit is ignored \ +and used for extra options - \ + \n\t1-3 allow fixing of satisfied integers (but not at bound) \ + \n\t1 switch off above for that dive if goes infeasible \ + \n\t2 switch off above permanently if goes infeasible" + ); + parameters[numberParameters-1].setIntValue(100); + parameters[numberParameters++] = + CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics", + "off", CBC_PARAM_STR_DIVINGS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a random diving heuristic at various times. \ +C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \ +You may prefer to use individual on/off \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient", + "off", CBC_PARAM_STR_DIVINGC); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional", + "off", CBC_PARAM_STR_DIVINGF); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided", + "off", CBC_PARAM_STR_DIVINGG); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch", + "off", CBC_PARAM_STR_DIVINGL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost", + "off", CBC_PARAM_STR_DIVINGP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength", + "off", CBC_PARAM_STR_DIVINGV); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing", + CBC_PARAM_ACTION_DOHEURISTIC, 3); + parameters[numberParameters-1].setLonghelp + ( + "Normally heuristics are done in branch and bound. It may be useful to do them outside. \ +Only those heuristics with 'both' or 'before' set will run. \ +Doing this may also set cutoff, which can help with preprocessing." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \ +gap between bounds exceeds this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND); + parameters[numberParameters-1].setLonghelp + ( + "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. If a problem has both upper and\ + lower bounds then it is trivial to get dual feasible by setting non basic variables\ + to correct bound. If the gap between the upper and lower bounds of a variable is more\ + than the value of dualBound Clp introduces fake bounds so that it can make the problem\ + dual feasible. This has the same effect as a composite objective function in the\ + primal algorithm. Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the bounds. OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualize", "Solves dual reformulation", + 0, 4, CLP_PARAM_INT_DUALIZE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Don't even think about it." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("partial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Steepest is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while automatic decides at each iteration based on information\ + about the factorization." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualS!implex", "Do dual simplex algorithm", + CLP_PARAM_ACTION_DUALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\ +The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by dual pivot method, fake bound on variables and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("dualT!olerance", "For an optimal solution \ +no dual infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a dual run seems to be having a hard time. One method which can be faster is \ +to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \ +correct tolerance (remembering to switch off presolve for this final short clean up phase)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic", + "off", CBC_PARAM_STR_DW); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "See Rounding for meaning of on,both,before" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\ + based on a dubious analysis of model." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("end", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops execution ; end, exit, quit and stop are synonyms" + ); + parameters[numberParameters++] = + CbcOrClpParam("environ!ment", "Read commands from environment", + CLP_PARAM_ACTION_ENVIRONMENT, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "This starts reading from environment variable CBC_CLP_ENVIRONMENT." + ); + parameters[numberParameters++] = + CbcOrClpParam("error!sAllowed", "Whether to allow import errors", + "off", CLP_PARAM_STR_ERRORSALLOWED, 3); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "The default is not to use any model which had errors when reading the mps file.\ + Setting this to 'on' will allow all errors from which the code can recover\ + simply by ignoring the error. There are some errors from which the code can not recover \ +e.g. no ENDATA. This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("exit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("exper!iment", "Whether to use testing features", + -1, 200, CBC_PARAM_INT_EXPERIMENT, 0); + parameters[numberParameters-1].setLonghelp + ( + "Defines how adventurous you want to be in using new ideas. \ +0 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!" + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0); + parameters[numberParameters-1].setLonghelp + ( + "Strategy for extra strong branching \n\ +\n\t0 - normal\n\ +\n\twhen to do all fractional\n\ +\n\t1 - root node\n\ +\n\t2 - depth less than modifier\n\ +\n\t4 - if objective == best possible\n\ +\n\t6 - as 2+4\n\ +\n\twhen to do all including satisfied\n\ +\n\t10 - root node etc.\n\ +\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)" + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("export", "Export model as mps file", + CLP_PARAM_ACTION_EXPORT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.mps'. \ +It can be useful to get rid of the original names and go over to using Rnnnnnnn and Cnnnnnnn. This can be done by setting 'keepnames' off before importing mps file." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("extra1", "Extra integer parameter 1", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra2", "Extra integer parameter 2", + -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra3", "Extra integer parameter 3", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra4", "Extra integer parameter 4", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on yet more special options!! \ +The bottom digit is a strategy when to used shadow price stuff e.g. 3 \ +means use until a solution is found. The next two digits say what sort \ +of dual information to use. After that it goes back to powers of 2 so -\n\ +\n\t1000 - switches on experimental hotstart\n\ +\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\ +\n\t8000 - increase minimum drop gradually\n\ +\n\t16000 - switches on alternate gomory criterion" + ); + parameters[numberParameters++] = + CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "This switches on creation of extra integer variables \ +to gather all variables with same cost." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("fact!orization", "Which factorization to use", + "normal", CLP_PARAM_STR_FACTORIZATION); + parameters[numberParameters-1].append("dense"); + parameters[numberParameters-1].append("simple"); + parameters[numberParameters-1].append("osl"); + parameters[numberParameters-1].setLonghelp + ( +#ifndef ABC_INHERIT + "The default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems." +#else + "Normally the default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems. \ +However if at Aboca then the default is CoinAbcFactorization and other choices are \ +a dense one, one designed for small problems or if enabled a long factorization." +#endif + ); + parameters[numberParameters++] = + CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG", + 1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump", + "off", CBC_PARAM_STR_FPUMP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \ +and uses a sequence of Lps to try and get an integer feasible solution. \ +Some fine tuning is available by passFeasibilityPump and also pumpTune. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \ +reduced costs greater than this", + -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1); + parameters[numberParameters-1].setLonghelp + ( + "If this is set integer variables with reduced costs greater than this will be fixed \ +before branch and bound - use with extreme caution!" + ); + parameters[numberParameters++] = + CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts", + "off", CBC_PARAM_STR_FLOWCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setFakeKeyWord(3); + parameters[numberParameters-1].setLonghelp + ( + "This switches on flow cover cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +Can also enter testing values by plusnn (==ifmove)" + ); + parameters[numberParameters++] = + CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB", + -1, 20000000, CLP_PARAM_INT_USESOLUTION); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "-1 off. If 1 then tries to branch to solution given by AMPL or priorities file. \ +If 0 then just tries to set as best solution \ +If >1 then also does that many nodes on fixed problem." + ); + parameters[numberParameters++] = + CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump", + 1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1); + parameters[numberParameters-1].setDoubleValue(0.5); + parameters[numberParameters-1].setLonghelp + ( + "After a pass in feasibility pump, variables which have not moved \ +about are fixed and if the preprocessed model is small enough a few nodes \ +of branch and bound are done on reduced problem. Small problem has to be less than this fraction of original." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier", + "off", CLP_PARAM_STR_GAMMA, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("gamma"); + parameters[numberParameters-1].append("delta"); + parameters[numberParameters-1].append("onstrong"); + parameters[numberParameters-1].append("gammastrong"); + parameters[numberParameters-1].append("deltastrong"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts", + "off", CBC_PARAM_STR_GMICUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].append("longroot"); + parameters[numberParameters-1].append("longifmove"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("longendonly"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on an alternative Gomory cut generator (either at root or in entire tree) \ +This version is by Giacomo Nannicini and may be more robust \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts", + "off", CBC_PARAM_STR_GOMORYCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].setLonghelp + ( + "The original cuts - beware of imitations! Having gone out of favor, they are now more \ +fashionable as LP solvers are more robust and they interact well with other cuts. They will almost always \ +give cuts (although in this executable they are limited as to number of variables in cut). \ +However the cuts may be dense so it is worth experimenting (Long allows any length). \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic", + "off", CBC_PARAM_STR_GREEDY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + //parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].setLonghelp + ( + "Switches on a greedy heuristic which will try and obtain a solution. It may just fix a \ +percentage of variables and then try a small branch and cut run. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gsolu!tion", "Puts glpk solution to file", + CLP_PARAM_ACTION_GMPL_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "Will write a glpk solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout' (this defaults to ordinary solution if stdout). \ +If problem created from gmpl model - will do any reports." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off", + "off", CBC_PARAM_STR_HEURISTICSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all heuristics. Then you can do \ +individual ones off or on. CbcTreeLocal is not included as it dramatically \ +alters search." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("help", "Print out version, non-standard options and some help", + CLP_PARAM_ACTION_HELP, 3); + parameters[numberParameters-1].setLonghelp + ( + "This prints out some help to get user started. If you have printed this then \ +you should be past that stage:-)" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("hOp!tions", "Heuristic options", + -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1); + parameters[numberParameters-1].setLonghelp + ( + "1 says stop heuristic immediately allowable gap reached. \ +Others are for feasibility pump - \ +2 says do exact number of passes given, \ +4 only applies if initial cutoff given and says relax after 50 passes, \ +while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start", + 0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("idiot!Crash", "Whether to try idiot crash", + -1, 99999999, CLP_PARAM_INT_IDIOT); + parameters[numberParameters-1].setLonghelp + ( + "This is a type of 'crash' which works well on some homogeneous problems.\ + It works best on problems with unit elements and rhs but will do something to any model. It should only be\ + used before primal. It can be set to -1 when the code decides for itself whether to use it,\ + 0 to switch off or n > 0 to do n passes." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("import", "Import model from mps file", + CLP_PARAM_ACTION_IMPORT, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libgz then it can read compressed\ + files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'. \ +If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("inc!rement", "A valid solution must be at least this \ +much better than last integer solution", + -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT); + parameters[numberParameters-1].setLonghelp + ( + "Whenever a solution is found the bound on solutions is set to solution (in a minimization\ +sense) plus this. If it is not set then the code will try and work one out e.g. if \ +all objective coefficients are multiples of 0.01 and only integer variables have entries in \ +objective then this can be set to 0.01. Be careful if you set this negative!" + ); + parameters[numberParameters++] = + CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \ +to cost this much", + 0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1); + parameters[numberParameters-1].setLonghelp + ( + "A primitive way of deciding which node to explore next. Satisfying each integer infeasibility is \ +expected to cost this much." + ); + parameters[numberParameters++] = + CbcOrClpParam("initialS!olve", "Solve to continuous", + CLP_PARAM_ACTION_SOLVECONTINUOUS); + parameters[numberParameters-1].setLonghelp + ( + "This just solves the problem to continuous - without adding any cuts" + ); + parameters[numberParameters++] = + CbcOrClpParam("integerT!olerance", "For an optimal solution \ +no integer variable may be this away from an integer value", + 1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Beware of setting this smaller than the primal tolerance." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("keepN!ames", "Whether to keep names from import", + "on", CLP_PARAM_STR_KEEPNAMES); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "It saves space to get rid of names so if you need to you can set this to off. \ +This needs to be set before the import of model - so -keepnames off -import xxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("KKT", "Whether to use KKT factorization", + "off", CLP_PARAM_STR_KKT, 7, 1); + parameters[numberParameters-1].append("on"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts", + "off", CBC_PARAM_STR_KNAPSACKCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on knapsack cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts", + "off", CBC_PARAM_STR_LAGOMORYCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].append("onlyaswellroot"); + parameters[numberParameters-1].append("cleanaswellroot"); + parameters[numberParameters-1].append("bothaswellroot"); + parameters[numberParameters-1].setLonghelp + ( + "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \ +by Matteo Fischetti & Domenico Salvagnin. This simplification \ +just uses original constraints while modifying objective using other cuts. \ +So you don't use messy constraints generated by Gomory etc. \ +A variant is to allow non messy cuts e.g. clique cuts. \ +So 'only' does this while clean also allows integral valued cuts. \ +'End' is recommended which waits until other cuts have finished and then \ +does a few passes. \ +The length options for gomory cuts are used." + ); + parameters[numberParameters++] = + CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts", + "off", CBC_PARAM_STR_LATWOMIRCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("endbothroot"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].setLonghelp + ( + "This is a lagrangean relaxation for TwoMir cuts. See \ +lagomoryCuts for description of options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts", + "off", CBC_PARAM_STR_LANDPCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Lift and project cuts. \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch", + "off", CBC_PARAM_STR_LOCALTREE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a local search algorithm when a solution is found. This is from \ +Fischetti and Lodi and is not really a heuristic although it can be used as one. \ +When used from Coin solve it has limited functionality. It is not switched on when \ +heuristics are switched on." + ); +#endif +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Solver output", + -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL); +#else + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output", + -63, 63, CLP_PARAM_INT_LOGLEVEL); + parameters[numberParameters-1].setIntValue(1); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information." + ); + parameters[numberParameters++] = + CbcOrClpParam("max!imize", "Set optimization direction to maximize", + CLP_PARAM_ACTION_MAXIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +You can also use the parameters 'direction maximize'." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("maxF!actor", "Maximum number of iterations between \ +refactorizations", + 1, 999999, CLP_PARAM_INT_MAXFACTOR); + parameters[numberParameters-1].setLonghelp + ( + "If this is at its initial value of 200 then in this executable clp will guess at a\ + value to use. Otherwise the user can set a value. The code may decide to re-factorize\ + earlier for accuracy." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \ +stopping", + 0, 2147483647, CLP_PARAM_INT_MAXITERATION); + parameters[numberParameters-1].setLonghelp + ( + "This can be used for testing purposes. The corresponding library call\n\ + \tsetMaximumIterations(value)\n can be useful. If the code stops on\ + seconds or by an interrupt this will be treated as stopping on maximum iterations. This is ignored in branchAndCut - use maxN!odes." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("maxN!odes", "Maximum number of nodes to do", + -1, 2147483647, CBC_PARAM_INT_MAXNODES); + parameters[numberParameters-1].setLonghelp + ( + "This is a repeatable way to limit search. Normally using time is easier \ +but then the results may not be repeatable." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save", + 0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS); + parameters[numberParameters-1].setLonghelp + ( + "Number of solutions to save." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get", + 1, 2147483647, CBC_PARAM_INT_MAXSOLS); + parameters[numberParameters-1].setLonghelp + ( + "You may want to stop after (say) two solutions or an hour. \ +This is checked every node in tree, so it is possible to get more solutions from heuristics." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("min!imize", "Set optimization direction to minimize", + CLP_PARAM_ACTION_MINIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +This should only be necessary if you have previously set maximization \ +You can also use the parameters 'direction minimize'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mipO!ptions", "Dubious options for mip", + 0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more!MipOptions", "More dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more2!MipOptions", "More more dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_MIXEDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed", + "off", CLP_PARAM_STR_MESSAGES); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ("The default behavior is to put out messages such as:\n\ + Clp0005 2261 Objective 109.024 Primal infeas 944413 (758)\n\ +but this program turns this off to make it look more friendly. It can be useful\ + to turn them back on if you want to be able to 'grep' for particular messages or if\ + you intend to override the behavior of a particular message. This only affects Clp not Cbc." + ); + parameters[numberParameters++] = + CbcOrClpParam("miplib", "Do some of miplib test set", + CBC_PARAM_ACTION_MIPLIB, 3, 1); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mips!tart", "reads an initial feasible solution from file", + CBC_PARAM_ACTION_MIPSTART); + parameters[numberParameters-1].setLonghelp + ("\ +The MIPStart allows one to enter an initial integer feasible solution \ +to CBC. Values of the main decision variables which are active (have \ +non-zero values) in this solution are specified in a text file. The \ +text file format used is the same of the solutions saved by CBC, but \ +not all fields are required to be filled. First line may contain the \ +solution status and will be ignored, remaining lines contain column \ +indexes, names and values as in this example:\n\ +\n\ +Stopped on iterations - objective value 57597.00000000\n\ + 0 x(1,1,2,2) 1 \n\ + 1 x(3,1,3,2) 1 \n\ + 5 v(5,1) 2 \n\ + 33 x(8,1,5,2) 1 \n\ + ...\n\ +\n\ +Column indexes are also ignored since pre-processing can change them. \ +There is no need to include values for continuous or integer auxiliary \ +variables, since they can be computed based on main decision variables. \ +Starting CBC with an integer feasible solution can dramatically improve \ +its performance: several MIP heuristics (e.g. RINS) rely on having at \ +least one feasible solution available and can start immediately if the \ +user provides one. Feasibility Pump (FP) is a heuristic which tries to \ +overcome the problem of taking too long to find feasible solution (or \ +not finding at all), but it not always succeeds. If you provide one \ +starting solution you will probably save some time by disabling FP. \ +\n\n\ +Knowledge specific to your problem can be considered to write an \ +external module to quickly produce an initial feasible solution - some \ +alternatives are the implementation of simple greedy heuristics or the \ +solution (by CBC for example) of a simpler model created just to find \ +a feasible solution. \ +\n\n\ +Question and suggestions regarding MIPStart can be directed to\n\ +haroldo.santos@gmail.com.\ +"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "Yet more ideas for Feasibility Pump \n\ +\t/100000 == 1 use box constraints and original obj in cleanup\n\ +\t/1000 == 1 Pump will run twice if no solution found\n\ +\t/1000 == 2 Pump will only run after root cuts if no solution found\n\ +\t/1000 >10 as above but even if solution found\n\ +\t/100 == 1,3.. exact 1.0 for objective values\n\ +\t/100 == 2,3.. allow more iterations per pass\n\ +\t n fix if value of variable same for last n iterations." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions", + 0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "Do (in parallel if threads enabled) the root phase this number of times \ + and collect all solutions and cuts generated. The actual format is aabbcc \ +where aa is number of extra passes, if bb is non zero \ +then it is number of threads to use (otherwise uses threads setting) and \ +cc is number of times to do root phase. Yet another one from the Italian idea factory \ +(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \ +and Andrea Tramontani). \ +The solvers do not interact with each other. However if extra passes are specified \ +then cuts are collected and used in later passes - so there is interaction there." + ); + parameters[numberParameters++] = + CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic", + "off", CBC_PARAM_STR_NAIVE, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "Really silly stuff e.g. fix all integers with costs to zero!. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("netlib", "Solve entire netlib test set", + CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier", + CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using barrier.\ +The user can set options before e.g. clp -kkt on -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)", + CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)", + CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using primal.\ +The user can set options before e.g. clp -presolve off -netlibp" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm", + CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using whatever \ +works best. I know this is cheating but it also stresses the code better by doing a \ +mixture of stuff. The best algorithm was chosen on a Linux ThinkPad using native cholesky \ +with University of Florida ordering." + ); + parameters[numberParameters++] = + CbcOrClpParam("network", "Tries to make network matrix", + CLP_PARAM_ACTION_NETWORK, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go faster if the matrix can be converted to a network. The matrix\ + operations may be a bit faster with more efficient storage, but the main advantage\ + comes from using a network factorization. It will probably not be as fast as a \ +specialized network code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file", + CLP_PARAM_ACTION_NEXTBESTSOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "To write best solution, just use solution. This prints next best (if exists) \ + and then deletes it. \ + This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); + parameters[numberParameters++] = + CbcOrClpParam("node!Strategy", "What strategy to use to select nodes", + "hybrid", CBC_PARAM_STR_NODESTRATEGY); + parameters[numberParameters-1].append("fewest"); + parameters[numberParameters-1].append("depth"); + parameters[numberParameters-1].append("upfewest"); + parameters[numberParameters-1].append("downfewest"); + parameters[numberParameters-1].append("updepth"); + parameters[numberParameters-1].append("downdepth"); + parameters[numberParameters-1].setLonghelp + ( + "Normally before a solution the code will choose node with fewest infeasibilities. \ +You can choose depth as the criterion. You can also say if up or down branch must \ +be done first (the up down choice will carry on after solution). \ +Default has now been changed to hybrid which is breadth first on small depth nodes then fewest." + ); + parameters[numberParameters++] = + CbcOrClpParam("numberA!nalyze", "Number of analysis iterations", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0); + parameters[numberParameters-1].setLonghelp + ( + "This says how many iterations to spend at root node analyzing problem. \ +This is a first try and will hopefully become more sophisticated." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("objective!Scale", "Scale factor to apply to objective", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If the objective function has some very large values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. It is applied after scaling. You are unlikely to need this." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_NTY + parameters[numberParameters++] = + CbcOrClpParam("Orbit!alBranching", "Whether to try orbital branching", + "off", CBC_PARAM_STR_ORBITAL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("strong"); + parameters[numberParameters-1].append("force"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Orbital branching. \ +On just adds orbital, strong tries extra fixing in strong branching"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model", + CLP_PARAM_ACTION_OUTDUPROWS, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("output!Format", "Which output format to use", + 1, 6, CLP_PARAM_INT_OUTPUTFORMAT); + parameters[numberParameters-1].setLonghelp + ( + "Normally export will be done using normal representation for numbers and two values\ + per line. You may want to do just one per line (for grep or suchlike) and you may wish\ + to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\ + otherwise odd values gives one value per line, even two. Values 1,2 give normal format, 3,4\ + gives greater precision, while 5,6 give IEEE values. When used for exporting a basis 1 does not save \ +values, 2 saves values, 3 with greater accuracy and 4 in IEEE." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("para!metrics", "Import data from file and do parametrics", + CLP_PARAM_ACTION_PARAMETRICS, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with parametric data from the given file name \ +and then do parametrics. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in modified csv format - a line ROWS will be followed by rows data \ +while a line COLUMNS will be followed by column data. The last line \ +should be ENDATA. The ROWS line must exist and is in the format \ +ROWS, inital theta, final theta, interval theta, n where n is 0 to get \ +CLPI0062 message at interval or at each change of theta \ +and 1 to get CLPI0063 message at each iteration. If interval theta is 0.0 \ +or >= final theta then no interval reporting. n may be missed out when it is \ +taken as 0. If there is Row data then \ +there is a headings line with allowed headings - name, number, \ +lower(rhs change), upper(rhs change), rhs(change). Either the lower and upper \ +fields should be given or the rhs field. \ +The optional COLUMNS line is followed by a headings line with allowed \ +headings - name, number, objective(change), lower(change), upper(change). \ + Exactly one of name and number must be given for either section and \ +missing ones have value 0.0." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passC!uts", "Number of cut passes at root node", + -9999999, 9999999, CBC_PARAM_INT_CUTPASS); + parameters[numberParameters-1].setLonghelp + ( + "The default is 100 passes if less than 500 columns, 100 passes (but \ +stop if drop small if less than 5000 columns, 20 otherwise" + ); + parameters[numberParameters++] = + CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump", + 0, 10000, CBC_PARAM_INT_FPUMPITS); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump by doing more or fewer passes." + ); + parameters[numberParameters-1].setIntValue(20); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("passP!resolve", "How many passes in presolve", + -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve does 10 passes but you may want to do less to make it\ + more lightweight or do more if improvements are still being made. As Presolve will return\ + if nothing is being taken out, you should not normally need to use this fine tuning." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree", + -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE); + parameters[numberParameters-1].setLonghelp + ( + "The default is one pass" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("pertV!alue", "Method of perturbation", + -5000, 102, CLP_PARAM_INT_PERTVALUE, 1); + parameters[numberParameters++] = + CbcOrClpParam("perturb!ation", "Whether to perturb problem", + "on", CLP_PARAM_STR_PERTURBATION); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Perturbation helps to stop cycling, but Clp uses other measures for this.\ + However large problems and especially ones with unit elements and unit rhs or costs\ + benefit from perturbation. Normally Clp tries to be intelligent, but you can switch this off.\ + The Clp library has this off by default. This program has it on by default." + ); + parameters[numberParameters++] = + CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex", + "off", CLP_PARAM_STR_PFI, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "By default clp uses Forrest-Tomlin L-U update. If you are masochistic you can switch it off." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic", + "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic", + "off", CBC_PARAM_STR_PIVOTANDFIX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix", + CLP_PARAM_ACTION_PLUSMINUS, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go slightly faster if the matrix can be converted so that the elements are\ + not stored and are known to be unit. The main advantage is memory use. Clp may automatically\ + see if it can convert the problem so you should not need to use this." + ); + parameters[numberParameters++] = + CbcOrClpParam("pO!ptions", "Dubious print options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "If this is > 0 then presolve will give more information and branch and cut will give statistics" + ); + parameters[numberParameters++] = + CbcOrClpParam("preO!pt", "Presolve options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("presolve", "Whether to presolve problem", + "on", CLP_PARAM_STR_PRESOLVE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("more"); + parameters[numberParameters-1].append("file"); + parameters[numberParameters-1].setLonghelp + ( + "Presolve analyzes the model to find such things as redundant equations, equations\ + which fix some variables, equations which can be transformed into bounds etc etc. For the\ + initial solve of any problem this is worth doing unless you know that it will have no effect. \ +on will normally do 5 passes while using 'more' will do 10. If the problem is very large you may need \ +to write the original to file using 'file'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("preprocess", "Whether to use integer preprocessing", + "off", CBC_PARAM_STR_PREPROCESS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("save"); + parameters[numberParameters-1].append("equal"); + parameters[numberParameters-1].append("sos"); + parameters[numberParameters-1].append("trysos"); + parameters[numberParameters-1].append("equalall"); + parameters[numberParameters-1].append("strategy"); + parameters[numberParameters-1].append("aggregate"); + parameters[numberParameters-1].append("forcesos"); + parameters[numberParameters-1].setLonghelp + ( + "This tries to reduce size of model in a similar way to presolve and \ +it also tries to strengthen the model - this can be very useful and is worth trying. \ + Save option saves on file presolved.mps. equal will turn <= cliques into \ +==. sos will create sos sets if all 0-1 in sets (well one extra is allowed) \ +and no overlaps. trysos is same but allows any number extra. equalall will turn all \ +valid inequalities into equalities with integer slacks. strategy is as \ +on but uses CbcStrategy." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("preT!olerance", "Tolerance to use in presolve", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \ +infeasible and you have awkward numbers and you are sure the problem is really feasible." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1); + parameters[numberParameters-1].append("exa!ct"); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("part!ial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].append("change"); + parameters[numberParameters-1].append("sprint"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Exact devex is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while change initially does dantzig until the factorization\ + becomes denser. This is still a work in progress." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalS!implex", "Do primal simplex algorithm", + CLP_PARAM_ACTION_PRIMALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the primal algorithm.\ + The default is to use exact devex.\ + The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by column selection method, infeasibility weight and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("primalT!olerance", "For an optimal solution \ +no primal infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a primal run seems to be having a hard time" + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \ +costs this much to be infeasible", + 1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT); + parameters[numberParameters-1].setLonghelp + ( + "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. So Clp is minimizing this weight times\ + the sum of primal infeasibilities plus the true objective function (in minimization sense).\ + Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the weight in order to get feasible.\ + OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("printi!ngOptions", "Print options", + "normal", CLP_PARAM_STR_INTPRINT, 3); + parameters[numberParameters-1].append("integer"); + parameters[numberParameters-1].append("special"); + parameters[numberParameters-1].append("rows"); + parameters[numberParameters-1].append("all"); + parameters[numberParameters-1].append("csv"); + parameters[numberParameters-1].append("bound!ranging"); + parameters[numberParameters-1].append("rhs!ranging"); + parameters[numberParameters-1].append("objective!ranging"); + parameters[numberParameters-1].append("stats"); + parameters[numberParameters-1].append("boundsint"); + parameters[numberParameters-1].append("boundsall"); + parameters[numberParameters-1].setLonghelp + ( + "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\ +integer - nonzero integer column variables\n\ +special - in format suitable for OsiRowCutDebugger\n\ +rows - nonzero column variables and row activities\n\ +all - all column variables and row activities.\n\ +\nFor non-integer problems 'integer' and 'special' act like 'normal'. \ +Also see printMask for controlling output." + ); + parameters[numberParameters++] = + CbcOrClpParam("printM!ask", "Control printing of solution on a mask", + CLP_PARAM_ACTION_PRINTMASK, 3); + parameters[numberParameters-1].setLonghelp + ( + "If set then only those names which match mask are printed in a solution. \ +'?' matches any character and '*' matches any set of characters. \ + The default is '' i.e. unset so all variables are printed. \ +This is only active if model has names." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("prio!rityIn", "Import priorities etc from file", + CBC_PARAM_ACTION_PRIORITYIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with priorities from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in csv format with allowed headings - name, number, priority, direction, up, down, solution. Exactly one of\ + name and number must be given." + ); + parameters[numberParameters++] = + CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts", + "off", CBC_PARAM_STR_PROBINGCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceonglobal"); + parameters[numberParameters-1].append("forceOnBut"); + parameters[numberParameters-1].append("forceOnStrong"); + parameters[numberParameters-1].append("forceOnButStrong"); + parameters[numberParameters-1].append("strongRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on probing cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +but strong options do more probing" + ); + parameters[numberParameters++] = + CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic", + "off", CBC_PARAM_STR_PROXIMITY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("10"); + parameters[numberParameters-1].append("100"); + parameters[numberParameters-1].append("300"); + // but allow numbers after this (returning 1) + parameters[numberParameters-1].setFakeKeyWord(1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which looks for a solution close \ +to incumbent solution (Fischetti and Monaci). \ +See Rounding for meaning of on,both,before. \ +Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))." + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise add a constraint forcing objective below this value\ + in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise use as absolute increment to cutoff \ +when solution found in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump \n\ +\t>=10000000 use as objective weight switch\n\ +\t>=1000000 use as accumulate switch\n\ +\t>=1000 use index+1 as number of large loops\n\ +\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\ +\t%100 == 10,20 affects how each solve is done\n\ +\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \ +If accumulate is on then after a major pass, variables which have not moved \ +are fixed and a small branch and bound is tried." + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("quit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc", + -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Cbc \ +- 0 says use time of day, -1 is as now." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic", + "off", CBC_PARAM_STR_RANDROUND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("randomS!eed", "Random seed for Clp", + 0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Clp \ +- 0 says use time of day." + ); + parameters[numberParameters-1].setIntValue(1234567); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \ +best less than this fraction of larger of two", + 0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "If the gap between best solution and best possible solution is less than this fraction \ +of the objective value at the root node then the search will terminate. See 'allowableGap' for a \ +way of using absolute value rather than fraction." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("restoreS!olution", "reads solution from file", + CLP_PARAM_ACTION_RESTORESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will read a binary solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. This reads in a file from saveSolution" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("readSt!ored", "Import stored cuts from file", + CLP_PARAM_ACTION_STOREDFILE, 3, 0); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "You can set this to -1.0 to test maximization or other to stress code" + ); + parameters[numberParameters-1].setDoubleValue(1.0); + parameters[numberParameters++] = + CbcOrClpParam("reallyS!cale", "Scales model in place", + CLP_PARAM_ACTION_REALLY_SCALE, 7, 0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts", + "off", CBC_PARAM_STR_REDSPLITCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree). \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts", + "off", CBC_PARAM_STR_RESIDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Residual capacity cuts. \ +See branchAndCut for information on options." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("restore!Model", "Restore model from binary file", + CLP_PARAM_ACTION_RESTORE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This reads data save by saveModel from the given file. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("reverse", "Reverses sign of objective", + CLP_PARAM_ACTION_REVERSE, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Useful for testing if maximization works correctly" + ); + parameters[numberParameters++] = + CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds", + -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0); + parameters[numberParameters-1].setLonghelp + ( + "If the rhs or bounds have some very large meaningful values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. This should not be needed." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search", + "off", CBC_PARAM_STR_RENS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("200"); + parameters[numberParameters-1].append("1000"); + parameters[numberParameters-1].append("10000"); + parameters[numberParameters-1].append("dj"); + parameters[numberParameters-1].append("djbefore"); + parameters[numberParameters-1].append("usesolution"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxation enforced neighborhood Search. \ +on just does 50 nodes \ +200 or 1000 does that many nodes. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search", + "off", CBC_PARAM_STR_RINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxed induced neighborhood Search. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic", + "off", CBC_PARAM_STR_ROUNDING); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a simple (but effective) rounding heuristic at each node of tree. \ +On means do in solve i.e. after preprocessing, \ +Before means do if doHeuristics used, off otherwise, \ +and both means do if doHeuristics and in solve." + ); + +#endif + parameters[numberParameters++] = + CbcOrClpParam("saveM!odel", "Save model to binary file", + CLP_PARAM_ACTION_SAVE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will save the problem to the given file name for future use\ + by restoreModel. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("saveS!olution", "saves solution to file", + CLP_PARAM_ACTION_SAVESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will write a binary solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. To read the file use fread(int) twice to pick up number of rows \ +and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \ +activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \ +If name contains '_fix_read_' then does not write but reads and will fix all variables" + ); + parameters[numberParameters++] = + CbcOrClpParam("scal!ing", "Whether to scale problem", + "off", CLP_PARAM_STR_SCALING); + parameters[numberParameters-1].append("equi!librium"); + parameters[numberParameters-1].append("geo!metric"); + parameters[numberParameters-1].append("auto!matic"); + parameters[numberParameters-1].append("dynamic"); + parameters[numberParameters-1].append("rows!only"); + parameters[numberParameters-1].setLonghelp + ( + "Scaling can help in solving problems which might otherwise fail because of lack of\ + accuracy. It can also reduce the number of iterations. It is not applied if the range\ + of elements is small. When unscaled it is possible that there may be small primal and/or\ + infeasibilities." + ); + parameters[numberParameters-1].setCurrentOption(3); // say auto +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "Maximum seconds", + -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds clp will act as if maximum iterations had been reached \ +(if value >=0)." + ); +#else + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "maximum seconds", + -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds coin solver will act as if maximum nodes had been reached." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("sleep", "for debug", + CLP_PARAM_ACTION_DUMMY, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts", + -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS); + parameters[numberParameters-1].setLonghelp + ( + "Some cut generators are fairly slow - this limits the number of times they are tried." + ); + parameters[numberParameters-1].setIntValue(10); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("slp!Value", "Number of slp passes before primal", + -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If you are solving a quadratic problem using primal then it may be helpful to do some \ +sequential Lps to get a good approximate solution." + ); +#if CLP_MULTIPLE_FACTORIZATIONS > 0 + parameters[numberParameters++] = + CbcOrClpParam("small!Factorization", "Whether to use small factorization", + -1, 10000, CBC_PARAM_INT_SMALLFACT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use small factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif + parameters[numberParameters++] = + CbcOrClpParam("solu!tion", "Prints solution to file", + CLP_PARAM_ACTION_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); +#ifdef COIN_HAS_CLP +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "If there are no integer variables then this just solves LP. If there are integer variables \ +this does branch and cut." + ); + parameters[numberParameters++] = + CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL", + "off", CBC_PARAM_STR_SOS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setCurrentOption("on"); + parameters[numberParameters-1].setLonghelp + ( + "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\ + be turned off - this does so." + ); + parameters[numberParameters++] = + CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output", + -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL); + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information. This parameter is only used inside MIP - for Clp use 'log'" + ); +#else + // allow solve as synonym for possible dual + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "Just so can use solve for clp as well as in cbc" + ); +#endif +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse", + "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0); + parameters[numberParameters-1].append("off"); + parameters[numberParameters++] = + CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("sprint!Crash", "Whether to try sprint crash", + -1, 5000000, CLP_PARAM_INT_SPRINT); + parameters[numberParameters-1].setLonghelp + ( + "For long and thin problems this program may solve a series of small problems\ + created by taking a subset of the columns. I introduced the idea as 'Sprint' after\ + an LP code of that name of the 60's which tried the same tactic (not totally successfully).\ + Cplex calls it 'sifting'. -1 is automatic choice, 0 is off, n is number of passes" + ); + parameters[numberParameters++] = + CbcOrClpParam("stat!istics", "Print some statistics", + CLP_PARAM_ACTION_STATISTICS); + parameters[numberParameters-1].setLonghelp + ( + "This command prints some statistics for the current model.\ + If log level >1 then more is printed.\ + These are for presolved model if presolve on (and unscaled)." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("stop", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("strat!egy", "Switches on groups of features", + 0, 2, CBC_PARAM_INT_STRATEGY); + parameters[numberParameters-1].setLonghelp + ( + "This turns on newer features. \ +Use 0 for easy problems, 1 is default, 2 is aggressive. \ +1 uses Gomory cuts using tolerance of 0.01 at root, \ +does a possible restart after 100 nodes if can fix many \ +and activates a diving and RINS heuristic and makes feasibility pump \ +more aggressive. \ +This does not apply to unit tests (where 'experiment' may have similar effects)." + ); + parameters[numberParameters-1].setIntValue(1); +#ifdef CBC_KEEP_DEPRECATED + parameters[numberParameters++] = + CbcOrClpParam("strengthen", "Create strengthened problem", + CBC_PARAM_ACTION_STRENGTHEN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This creates a new problem by applying the root node cuts. All tight constraints \ +will be in resulting problem" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING); + parameters[numberParameters-1].setLonghelp + ( + "In order to decide which variable to branch on, the code will choose up to this number \ +of unsatisfied variables to do mini up and down branches on. Then the most effective one is chosen. \ +If a variable is branched on many times then the previous average up and down costs may be used - \ +see number before trust." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve", + 0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve gets rid of 'free' variables when there are no more than 3 \ + variables in column. If you increase this the number of rows may decrease but number of \ + elements may increase." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("testO!si", "Test OsiObject stuff", + -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0); +#endif +#ifdef CBC_THREAD + parameters[numberParameters++] = + CbcOrClpParam("thread!s", "Number of threads to try and use", + -100, 100000, CBC_PARAM_INT_THREADS, 1); + parameters[numberParameters-1].setLonghelp + ( + "To use multiple threads, set threads to number wanted. It may be better \ +to use one or two more than number of cpus available. If 100+n then n threads and \ +search is repeatable (maybe be somewhat slower), \ +if 200+n use threads for root cuts, 400+n threads used in sub-trees." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \ +activity at continuous solution", + 1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0); + parameters[numberParameters-1].setLonghelp + ( + "This sleazy trick can help on some problems." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("tightLP", "Poor person's preSolve for now", + CLP_PARAM_ACTION_TIGHTEN, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time", + "cpu", CLP_PARAM_STR_TIME_MODE); + parameters[numberParameters-1].append("elapsed"); + parameters[numberParameters-1].setLonghelp + ( + "cpu uses CPU time for stopping, while elapsed uses elapsed time. \ +(On Windows, elapsed time is always used)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts", + -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE); + parameters[numberParameters-1].setLonghelp + ( + "Using strong branching computes pseudo-costs. After this many times for a variable we just \ +trust the pseudo costs and do not do any more strong branching." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters", + 0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \ +If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \ +cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \ +2 - 4 As above but even if zero objective value\n \ +7 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \ +10 - 1024 Use a larger feasibility tolerance in presolve\n \ +11 - 2048 Try probing before creating cliques" + ); + parameters[numberParameters++] = + CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_TWOMIRCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on two phase mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("unitTest", "Do unit test", + CLP_PARAM_ACTION_UNITTEST, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp" + ); + parameters[numberParameters++] = + CbcOrClpParam("userClp", "Hand coded Clp stuff", + CLP_PARAM_ACTION_USERCLP, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCLP in main driver and modify sample code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("userCbc", "Hand coded Cbc stuff", + CBC_PARAM_ACTION_USERCBC, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCBC in main driver and modify sample code. \ +It is possible you can get same effect by using example driver4.cpp." + ); + parameters[numberParameters++] = + CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search", + "off", CBC_PARAM_STR_VND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("intree"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on variable neighborhood Search. \ +Doh option does heuristic before preprocessing" ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex", + "off", CLP_PARAM_STR_VECTOR, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If this is on ClpPackedMatrix uses extra column copy in odd format." + ); + parameters[numberParameters++] = + CbcOrClpParam("verbose", "Switches on longer help on single ?", + 0, 31, CLP_PARAM_INT_VERBOSE, 0); + parameters[numberParameters-1].setLonghelp + ( + "Set to 1 to get short help with ? list, 2 to get long help, 3 for both. (add 4 to just get ampl ones)." + ); + parameters[numberParameters-1].setIntValue(0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("vub!heuristic", "Type of vub heuristic", + -2, 20, CBC_PARAM_INT_VUBTRY, 0); + parameters[numberParameters-1].setLonghelp + ( + "If set will try and fix some integer variables" + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts", + "off", CBC_PARAM_STR_ZEROHALFCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on zero-half cuts (either at root or in entire tree) \ +See branchAndCut for information on options. This implementation was written by \ +Alberto Caprara." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("zeroT!olerance", "Kill all coefficients \ +whose absolute value is less than this value", + 1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "This applies to reading mps files (and also lp files \ +if KILL_ZERO_READLP defined)" + ); + parameters[numberParameters-1].setDoubleValue(1.0e-20); + assert(numberParameters < CBCMAXPARAMETERS); +} +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters) +{ + int i; + for (i = 0; i < numberParameters; i++) { + if (parameters[i].type() == name) + break; + } + assert (i < numberParameters); + return i; +} +#ifdef COIN_HAS_CLP +/* Restore a solution from file. + mode 0 normal, 1 swap rows and columns and primal and dual + if 2 set then also change signs +*/ +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode) +{ + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + int numberRowsFile; + int numberColumnsFile; + double objectiveValue; + size_t nRead; + nRead = fread(&numberRowsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&numberColumnsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&objectiveValue, sizeof(double), 1, fp); + if (nRead != 1) + throw("Error in fread"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + if (mode) { + // swap + int k = numberRows; + numberRows = numberColumns; + numberColumns = k; + double * temp; + temp = dualRowSolution; + dualRowSolution = primalColumnSolution; + primalColumnSolution = temp; + temp = dualColumnSolution; + dualColumnSolution = primalRowSolution; + primalRowSolution = temp; + } + if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) { + std::cout << "Mismatch on rows and/or columns - giving up" << std::endl; + } else { + lpSolver->setObjectiveValue(objectiveValue); + if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) { + nRead = fread(primalRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast<size_t>(numberRows)) + throw("Error in fread"); + nRead = fread(dualRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast<size_t>(numberRows)) + throw("Error in fread"); + nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast<size_t>(numberColumns)) + throw("Error in fread"); + nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast<size_t>(numberColumns)) + throw("Error in fread"); + } else { + std::cout << "Mismatch on rows and/or columns - truncating" << std::endl; + double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)]; + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast<size_t>(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, primalRowSolution); + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast<size_t>(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, dualRowSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast<size_t>(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, primalColumnSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast<size_t>(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, dualColumnSolution); + delete [] temp; + } + if (mode == 3) { + int i; + for (i = 0; i < numberRows; i++) { + primalRowSolution[i] = -primalRowSolution[i]; + dualRowSolution[i] = -dualRowSolution[i]; + } + for (i = 0; i < numberColumns; i++) { + primalColumnSolution[i] = -primalColumnSolution[i]; + dualColumnSolution[i] = -dualColumnSolution[i]; + } + } + } + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +// Dump a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName) +{ + if (strstr(fileName.c_str(), "_fix_read_")) { + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver); + restoreSolution(solver, fileName, 0); + // fix all + int logLevel = solver->logLevel(); + int iColumn; + int numberColumns = solver->numberColumns(); + double * primalColumnSolution = + solver->primalColumnSolution(); + double * columnLower = solver->columnLower(); + double * columnUpper = solver->columnUpper(); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = primalColumnSolution[iColumn]; + if (value > columnUpper[iColumn]) { + if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnUpper[iColumn]; + } else if (value < columnLower[iColumn]) { + if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnLower[iColumn]; + } + columnLower[iColumn] = value; + columnUpper[iColumn] = value; + } + return; + } + } + FILE * fp = fopen(fileName.c_str(), "wb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + double objectiveValue = lpSolver->objectiveValue(); + size_t nWrite; + nWrite = fwrite(&numberRows, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&numberColumns, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast<size_t>(numberRows)) + throw("Error in fwrite"); + nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast<size_t>(numberRows)) + throw("Error in fwrite"); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast<size_t>(numberColumns)) + throw("Error in fwrite"); + nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast<size_t>(numberColumns)) + throw("Error in fwrite"); + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +#endif diff --git a/thirdparty/linux/include/coin/coin/CbcOrClpParam.hpp b/thirdparty/linux/include/coin/coin/CbcOrClpParam.hpp new file mode 100644 index 0000000..5e0794a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcOrClpParam.hpp @@ -0,0 +1,532 @@ + +/* $Id: CbcOrClpParam.hpp 2175 2015-10-06 08:56:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifdef USE_CBCCONFIG +# include "CbcConfig.h" +#else +# include "ClpConfig.h" +#endif + +#ifndef CbcOrClpParam_H +#define CbcOrClpParam_H +/** + This has parameter handling stuff which can be shared between Cbc and Clp (and Dylp etc). + + This (and .cpp) should be copied so that it is the same in Cbc/Test and Clp/Test. + I know this is not elegant but it seems simplest. + + It uses COIN_HAS_CBC for parameters wanted by CBC + It uses COIN_HAS_CLP for parameters wanted by CLP (or CBC using CLP) + It could use COIN_HAS_DYLP for parameters wanted by DYLP + It could use COIN_HAS_DYLP_OR_CLP for parameters wanted by DYLP or CLP etc etc + + */ +class OsiSolverInterface; +class CbcModel; +class ClpSimplex; +/*! \brief Parameter codes + + Parameter type ranges are allocated as follows + <ul> + <li> 1 -- 100 double parameters + <li> 101 -- 200 integer parameters + <li> 201 -- 250 string parameters + <li> 251 -- 300 cuts etc(string but broken out for clarity) + <li> 301 -- 400 `actions' + </ul> + + `Actions' do not necessarily invoke an immediate action; it's just that they + don't fit neatly into the parameters array. + + This coding scheme is in flux. +*/ + +enum CbcOrClpParameterType + +{ + CBC_PARAM_GENERALQUERY = -100, + CBC_PARAM_FULLGENERALQUERY, + + CLP_PARAM_DBL_PRIMALTOLERANCE = 1, + CLP_PARAM_DBL_DUALTOLERANCE, + CLP_PARAM_DBL_TIMELIMIT, + CLP_PARAM_DBL_DUALBOUND, + CLP_PARAM_DBL_PRIMALWEIGHT, + CLP_PARAM_DBL_OBJSCALE, + CLP_PARAM_DBL_RHSSCALE, + CLP_PARAM_DBL_ZEROTOLERANCE, + + CBC_PARAM_DBL_INFEASIBILITYWEIGHT = 51, + CBC_PARAM_DBL_CUTOFF, + CBC_PARAM_DBL_INTEGERTOLERANCE, + CBC_PARAM_DBL_INCREMENT, + CBC_PARAM_DBL_ALLOWABLEGAP, + CBC_PARAM_DBL_TIMELIMIT_BAB, + CBC_PARAM_DBL_GAPRATIO, + + CBC_PARAM_DBL_DJFIX = 81, + CBC_PARAM_DBL_TIGHTENFACTOR, + CLP_PARAM_DBL_PRESOLVETOLERANCE, + CLP_PARAM_DBL_OBJSCALE2, + CBC_PARAM_DBL_FAKEINCREMENT, + CBC_PARAM_DBL_FAKECUTOFF, + CBC_PARAM_DBL_ARTIFICIALCOST, + CBC_PARAM_DBL_DEXTRA3, + CBC_PARAM_DBL_SMALLBAB, + CBC_PARAM_DBL_DEXTRA4, + CBC_PARAM_DBL_DEXTRA5, + + CLP_PARAM_INT_SOLVERLOGLEVEL = 101, +#ifndef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL = 101, +#endif + CLP_PARAM_INT_MAXFACTOR, + CLP_PARAM_INT_PERTVALUE, + CLP_PARAM_INT_MAXITERATION, + CLP_PARAM_INT_PRESOLVEPASS, + CLP_PARAM_INT_IDIOT, + CLP_PARAM_INT_SPRINT, + CLP_PARAM_INT_OUTPUTFORMAT, + CLP_PARAM_INT_SLPVALUE, + CLP_PARAM_INT_PRESOLVEOPTIONS, + CLP_PARAM_INT_PRINTOPTIONS, + CLP_PARAM_INT_SPECIALOPTIONS, + CLP_PARAM_INT_SUBSTITUTION, + CLP_PARAM_INT_DUALIZE, + CLP_PARAM_INT_VERBOSE, + CLP_PARAM_INT_CPP, + CLP_PARAM_INT_PROCESSTUNE, + CLP_PARAM_INT_USESOLUTION, + CLP_PARAM_INT_RANDOMSEED, + CLP_PARAM_INT_MORESPECIALOPTIONS, + CLP_PARAM_INT_DECOMPOSE_BLOCKS, + + CBC_PARAM_INT_STRONGBRANCHING = 151, + CBC_PARAM_INT_CUTDEPTH, + CBC_PARAM_INT_MAXNODES, + CBC_PARAM_INT_NUMBERBEFORE, + CBC_PARAM_INT_NUMBERANALYZE, + CBC_PARAM_INT_MIPOPTIONS, + CBC_PARAM_INT_MOREMIPOPTIONS, + CBC_PARAM_INT_MAXHOTITS, + CBC_PARAM_INT_FPUMPITS, + CBC_PARAM_INT_MAXSOLS, + CBC_PARAM_INT_FPUMPTUNE, + CBC_PARAM_INT_TESTOSI, + CBC_PARAM_INT_EXTRA1, + CBC_PARAM_INT_EXTRA2, + CBC_PARAM_INT_EXTRA3, + CBC_PARAM_INT_EXTRA4, + CBC_PARAM_INT_DEPTHMINIBAB, + CBC_PARAM_INT_CUTPASSINTREE, + CBC_PARAM_INT_THREADS, + CBC_PARAM_INT_CUTPASS, + CBC_PARAM_INT_VUBTRY, + CBC_PARAM_INT_DENSE, + CBC_PARAM_INT_EXPERIMENT, + CBC_PARAM_INT_DIVEOPT, + CBC_PARAM_INT_DIVEOPTSOLVES, + CBC_PARAM_INT_STRATEGY, + CBC_PARAM_INT_SMALLFACT, + CBC_PARAM_INT_HOPTIONS, + CBC_PARAM_INT_CUTLENGTH, + CBC_PARAM_INT_FPUMPTUNE2, +#ifdef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL , +#endif + CBC_PARAM_INT_MAXSAVEDSOLS, + CBC_PARAM_INT_RANDOMSEED, + CBC_PARAM_INT_MULTIPLEROOTS, + CBC_PARAM_INT_STRONG_STRATEGY, + CBC_PARAM_INT_EXTRA_VARIABLES, + CBC_PARAM_INT_MAX_SLOW_CUTS, + CBC_PARAM_INT_MOREMOREMIPOPTIONS, + + CLP_PARAM_STR_DIRECTION = 201, + CLP_PARAM_STR_DUALPIVOT, + CLP_PARAM_STR_SCALING, + CLP_PARAM_STR_ERRORSALLOWED, + CLP_PARAM_STR_KEEPNAMES, + CLP_PARAM_STR_SPARSEFACTOR, + CLP_PARAM_STR_PRIMALPIVOT, + CLP_PARAM_STR_PRESOLVE, + CLP_PARAM_STR_CRASH, + CLP_PARAM_STR_BIASLU, + CLP_PARAM_STR_PERTURBATION, + CLP_PARAM_STR_MESSAGES, + CLP_PARAM_STR_AUTOSCALE, + CLP_PARAM_STR_CHOLESKY, + CLP_PARAM_STR_KKT, + CLP_PARAM_STR_BARRIERSCALE, + CLP_PARAM_STR_GAMMA, + CLP_PARAM_STR_CROSSOVER, + CLP_PARAM_STR_PFI, + CLP_PARAM_STR_INTPRINT, + CLP_PARAM_STR_VECTOR, + CLP_PARAM_STR_FACTORIZATION, + CLP_PARAM_STR_ALLCOMMANDS, + CLP_PARAM_STR_TIME_MODE, + CLP_PARAM_STR_ABCWANTED, + CLP_PARAM_STR_BUFFER_MODE, + + CBC_PARAM_STR_NODESTRATEGY = 251, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_STR_CUTSSTRATEGY, + CBC_PARAM_STR_HEURISTICSTRATEGY, + CBC_PARAM_STR_GOMORYCUTS, + CBC_PARAM_STR_PROBINGCUTS, + CBC_PARAM_STR_KNAPSACKCUTS, + CBC_PARAM_STR_REDSPLITCUTS, + CBC_PARAM_STR_ROUNDING, + CBC_PARAM_STR_SOLVER, + CBC_PARAM_STR_CLIQUECUTS, + CBC_PARAM_STR_COSTSTRATEGY, + CBC_PARAM_STR_FLOWCUTS, + CBC_PARAM_STR_MIXEDCUTS, + CBC_PARAM_STR_TWOMIRCUTS, + CBC_PARAM_STR_PREPROCESS, + CBC_PARAM_STR_FPUMP, + CBC_PARAM_STR_GREEDY, + CBC_PARAM_STR_COMBINE, + CBC_PARAM_STR_PROXIMITY, + CBC_PARAM_STR_LOCALTREE, + CBC_PARAM_STR_SOS, + CBC_PARAM_STR_LANDPCUTS, + CBC_PARAM_STR_RINS, + CBC_PARAM_STR_RESIDCUTS, + CBC_PARAM_STR_RENS, + CBC_PARAM_STR_DIVINGS, + CBC_PARAM_STR_DIVINGC, + CBC_PARAM_STR_DIVINGF, + CBC_PARAM_STR_DIVINGG, + CBC_PARAM_STR_DIVINGL, + CBC_PARAM_STR_DIVINGP, + CBC_PARAM_STR_DIVINGV, + CBC_PARAM_STR_DINS, + CBC_PARAM_STR_PIVOTANDFIX, + CBC_PARAM_STR_RANDROUND, + CBC_PARAM_STR_NAIVE, + CBC_PARAM_STR_ZEROHALFCUTS, + CBC_PARAM_STR_CPX, + CBC_PARAM_STR_CROSSOVER2, + CBC_PARAM_STR_PIVOTANDCOMPLEMENT, + CBC_PARAM_STR_VND, + CBC_PARAM_STR_LAGOMORYCUTS, + CBC_PARAM_STR_LATWOMIRCUTS, + CBC_PARAM_STR_REDSPLIT2CUTS, + CBC_PARAM_STR_GMICUTS, + CBC_PARAM_STR_CUTOFF_CONSTRAINT, + CBC_PARAM_STR_DW, + CBC_PARAM_STR_ORBITAL, + + CLP_PARAM_ACTION_DIRECTORY = 301, + CLP_PARAM_ACTION_DIRSAMPLE, + CLP_PARAM_ACTION_DIRNETLIB, + CBC_PARAM_ACTION_DIRMIPLIB, + CLP_PARAM_ACTION_IMPORT, + CLP_PARAM_ACTION_EXPORT, + CLP_PARAM_ACTION_RESTORE, + CLP_PARAM_ACTION_SAVE, + CLP_PARAM_ACTION_DUALSIMPLEX, + CLP_PARAM_ACTION_PRIMALSIMPLEX, + CLP_PARAM_ACTION_EITHERSIMPLEX, + CLP_PARAM_ACTION_MAXIMIZE, + CLP_PARAM_ACTION_MINIMIZE, + CLP_PARAM_ACTION_EXIT, + CLP_PARAM_ACTION_STDIN, + CLP_PARAM_ACTION_UNITTEST, + CLP_PARAM_ACTION_NETLIB_EITHER, + CLP_PARAM_ACTION_NETLIB_DUAL, + CLP_PARAM_ACTION_NETLIB_PRIMAL, + CLP_PARAM_ACTION_SOLUTION, + CLP_PARAM_ACTION_SAVESOL, + CLP_PARAM_ACTION_TIGHTEN, + CLP_PARAM_ACTION_FAKEBOUND, + CLP_PARAM_ACTION_HELP, + CLP_PARAM_ACTION_PLUSMINUS, + CLP_PARAM_ACTION_NETWORK, + CLP_PARAM_ACTION_ALLSLACK, + CLP_PARAM_ACTION_REVERSE, + CLP_PARAM_ACTION_BARRIER, + CLP_PARAM_ACTION_NETLIB_BARRIER, + CLP_PARAM_ACTION_NETLIB_TUNE, + CLP_PARAM_ACTION_REALLY_SCALE, + CLP_PARAM_ACTION_BASISIN, + CLP_PARAM_ACTION_BASISOUT, + CLP_PARAM_ACTION_SOLVECONTINUOUS, + CLP_PARAM_ACTION_CLEARCUTS, + CLP_PARAM_ACTION_VERSION, + CLP_PARAM_ACTION_STATISTICS, + CLP_PARAM_ACTION_DEBUG, + CLP_PARAM_ACTION_DUMMY, + CLP_PARAM_ACTION_PRINTMASK, + CLP_PARAM_ACTION_OUTDUPROWS, + CLP_PARAM_ACTION_USERCLP, + CLP_PARAM_ACTION_MODELIN, + CLP_PARAM_ACTION_CSVSTATISTICS, + CLP_PARAM_ACTION_STOREDFILE, + CLP_PARAM_ACTION_ENVIRONMENT, + CLP_PARAM_ACTION_PARAMETRICS, + CLP_PARAM_ACTION_GMPL_SOLUTION, + CLP_PARAM_ACTION_RESTORESOL, + + CBC_PARAM_ACTION_BAB = 361, + CBC_PARAM_ACTION_MIPLIB, + CBC_PARAM_ACTION_STRENGTHEN, + CBC_PARAM_ACTION_PRIORITYIN, + CBC_PARAM_ACTION_MIPSTART, + CBC_PARAM_ACTION_USERCBC, + CBC_PARAM_ACTION_DOHEURISTIC, + CLP_PARAM_ACTION_NEXTBESTSOLUTION, + + CBC_PARAM_NOTUSED_OSLSTUFF = 401, + CBC_PARAM_NOTUSED_CBCSTUFF, + + CBC_PARAM_NOTUSED_INVALID = 1000 +} ; +#include <vector> +#include <string> + +/// Very simple class for setting parameters + +class CbcOrClpParam { +public: + /**@name Constructor and destructor */ + //@{ + /// Constructors + CbcOrClpParam ( ); + CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, int display = 2); + CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, int display = 2); + // Other strings will be added by insert + CbcOrClpParam (std::string name, std::string help, std::string firstValue, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + // Action + CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + /// Copy constructor. + CbcOrClpParam(const CbcOrClpParam &); + /// Assignment operator. This copies the data + CbcOrClpParam & operator=(const CbcOrClpParam & rhs); + /// Destructor + ~CbcOrClpParam ( ); + //@} + + /**@name stuff */ + //@{ + /// Insert string (only valid for keywords) + void append(std::string keyWord); + /// Adds one help line + void addHelp(std::string keyWord); + /// Returns name + inline std::string name( ) const { + return name_; + } + /// Returns short help + inline std::string shortHelp( ) const { + return shortHelp_; + } + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(CbcModel & model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(CbcModel & model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(CbcModel & model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(CbcModel & model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(ClpSimplex * model, double value) ; + /// Gets a double parameter + double doubleParameter(ClpSimplex * model) const; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode); + /// Sets a int parameter (nonzero code if error) + int setIntParameter(ClpSimplex * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(ClpSimplex * model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(OsiSolverInterface * model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(OsiSolverInterface * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(OsiSolverInterface * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(OsiSolverInterface * model) const; + /// Checks a double parameter (nonzero code if error) + int checkDoubleParameter(double value) const; + /// Returns name which could match + std::string matchName ( ) const; + /// Returns length of name for ptinting + int lengthMatchName ( ) const; + /// Returns parameter option which matches (-1 if none) + int parameterOption ( std::string check ) const; + /// Prints parameter options + void printOptions ( ) const; + /// Returns current parameter option + inline std::string currentOption ( ) const { + return definedKeyWords_[currentKeyWord_]; + } + /// Sets current parameter option + void setCurrentOption ( int value , bool printIt = false); + /// Sets current parameter option and returns printable string + const char * setCurrentOptionWithMessage ( int value ); + /// Sets current parameter option using string + void setCurrentOption (const std::string value ); + /// Sets current parameter option using string with message + const char * setCurrentOptionWithMessage (const std::string value ); + /// Returns current parameter option position + int currentOptionAsInteger ( ) const ; + /** Returns current parameter option position + but if fake keyword returns a fake value and sets + fakeInteger to true value. If not fake then fakeInteger is -COIN_INT_MAX + */ + int currentOptionAsInteger ( int & fakeInteger ) const; + /// Sets int value + void setIntValue ( int value ); + /// Sets int value with message + const char * setIntValueWithMessage ( int value ); + inline int intValue () const { + return intValue_; + } + /// Sets double value + void setDoubleValue ( double value ); + /// Sets double value with message + const char * setDoubleValueWithMessage ( double value ); + inline double doubleValue () const { + return doubleValue_; + } + /// Sets string value + void setStringValue ( std::string value ); + inline std::string stringValue () const { + return stringValue_; + } + /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched + int matches (std::string input) const; + /// type + inline CbcOrClpParameterType type() const { + return type_; + } + /// whether to display + inline int displayThis() const { + return display_; + } + /// Set Long help + inline void setLonghelp(const std::string help) { + longHelp_ = help; + } + /// Print Long help + void printLongHelp() const; + /// Print action and string + void printString() const; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + inline int whereUsed() const { + return whereUsed_; + } + /// Gets value of fake keyword + inline int fakeKeyWord() const + { return fakeKeyWord_;} + /// Sets value of fake keyword + inline void setFakeKeyWord(int value, int fakeValue) + { fakeKeyWord_ = value; fakeValue_ = fakeValue;} + /// Sets value of fake keyword to current size of keywords + void setFakeKeyWord(int fakeValue); + +private: + /// gutsOfConstructor + void gutsOfConstructor(); + //@} +////////////////// data ////////////////// +private: + + /**@name data + We might as well throw all type data in - could derive? + */ + //@{ + // Type see CbcOrClpParameterType + CbcOrClpParameterType type_; + /// If double == okay + double lowerDoubleValue_; + double upperDoubleValue_; + /// If int == okay + int lowerIntValue_; + int upperIntValue_; + // Length of name + unsigned int lengthName_; + // Minimum match + unsigned int lengthMatch_; + /// set of valid strings + std::vector<std::string> definedKeyWords_; + /// Name + std::string name_; + /// Short help + std::string shortHelp_; + /// Long help + std::string longHelp_; + /// Action + CbcOrClpParameterType action_; + /// Current keyWord (if a keyword parameter) + int currentKeyWord_; + /// Display on ? + int display_; + /// Integer parameter - current value + int intValue_; + /// Double parameter - current value + double doubleValue_; + /// String parameter - current value + std::string stringValue_; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + int whereUsed_; + /** If >=0 then integers allowed as a fake keyword + So minusnnnn would got to -nnnn in currentKeyword_ + and plusnnnn would go to fakeKeyword_+nnnn + */ + int fakeKeyWord_; + /// Return this as main value if an integer + int fakeValue_; + //@} +}; +/// Simple read stuff +std::string CoinReadNextField(); + +std::string CoinReadGetCommand(int argc, const char *argv[]); +std::string CoinReadGetString(int argc, const char *argv[]); +// valid 0 - okay, 1 bad, 2 not there +int CoinReadGetIntField(int argc, const char *argv[], int * valid); +double CoinReadGetDoubleField(int argc, const char *argv[], int * valid); +void CoinReadPrintit(const char * input); +void setCbcOrClpPrinting(bool yesNo); +#define CBCMAXPARAMETERS 250 +/* + Subroutine to establish the cbc parameter array. See the description of + class CbcOrClpParam for details. Pulled from C..Main() for clarity. +*/ +void establishParams (int &numberParameters, CbcOrClpParam *const parameters); +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters); +// Dump/restore a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName); +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode); +#endif /* CbcOrClpParam_H */ diff --git a/thirdparty/linux/include/coin/coin/CbcParam.hpp b/thirdparty/linux/include/coin/coin/CbcParam.hpp new file mode 100644 index 0000000..5b37348 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcParam.hpp @@ -0,0 +1,324 @@ +/* $Id: CbcParam.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcParam_H +#define CbcParam_H + +#include "OsiSolverInterface.hpp" +#include "CbcModel.hpp" +class ClpSimplex; +/*! \brief Parameter codes + + Parameter type ranges are allocated as follows + <ul> + <li> 1 -- 100 double parameters + <li> 101 -- 200 integer parameters + <li> 201 -- 250 string parameters + <li> 251 -- 300 cuts etc(string but broken out for clarity) + <li> 301 -- 400 `actions' + </ul> + + `Actions' do not necessarily invoke an immediate action; it's just that they + don't fit neatly into the parameters array. + + This coding scheme is in flux. + CBC_PARAM_STR_NODESTRATEGY, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_NOTUSED_ADDCUTSSTRATEGY, + CLP_PARAM_ACTION_CLEARCUTS, + CBC_PARAM_NOTUSED_OSLSTUFF, + CBC_PARAM_NOTUSED_CBCSTUFF are not used at present (03.10.24). +*/ + +enum CbcParameterType + +{ CBC_PARAM_GENERALQUERY = -100, + CBC_PARAM_FULLGENERALQUERY, + + CLP_PARAM_DBL_PRIMALTOLERANCE = 1, + CLP_PARAM_DBL_DUALTOLERANCE, + CBC_PARAM_DBL_CUTOFF, + CLP_PARAM_DBL_TIMELIMIT, + CLP_PARAM_DBL_DUALBOUND, + CLP_PARAM_DBL_PRIMALWEIGHT, + CLP_PARAM_DBL_OBJSCALE, + CLP_PARAM_DBL_RHSSCALE, + + CBC_PARAM_DBL_INFEASIBILITYWEIGHT = 51, + CBC_PARAM_DBL_INTEGERTOLERANCE, + CBC_PARAM_DBL_INCREMENT, + CBC_PARAM_DBL_ALLOWABLEGAP, + + CBC_PARAM_DBL_DJFIX = 81, + CBC_PARAM_DBL_GAPRATIO, + CBC_PARAM_DBL_TIGHTENFACTOR, + + CLP_PARAM_INT_LOGLEVEL = 101, + CLP_PARAM_INT_SOLVERLOGLEVEL, + CBC_PARAM_INT_MAXNODES, + CBC_PARAM_INT_STRONGBRANCHING, + CLP_PARAM_INT_MAXFACTOR, + CLP_PARAM_INT_PERTVALUE, + CLP_PARAM_INT_MAXITERATION, + CLP_PARAM_INT_PRESOLVEPASS, + CLP_PARAM_INT_IDIOT, + CLP_PARAM_INT_SPRINT, + CLP_PARAM_INT_OUTPUTFORMAT, + CLP_PARAM_INT_SLPVALUE, + CLP_PARAM_INT_PRESOLVEOPTIONS, + CLP_PARAM_INT_PRINTOPTIONS, + CLP_PARAM_INT_SPECIALOPTIONS, + + CLP_PARAM_STR_DIRECTION = 201, + CLP_PARAM_STR_DUALPIVOT, + CLP_PARAM_STR_SCALING, + CLP_PARAM_STR_ERRORSALLOWED, + CLP_PARAM_STR_KEEPNAMES, + CLP_PARAM_STR_SPARSEFACTOR, + CLP_PARAM_STR_PRIMALPIVOT, + CLP_PARAM_STR_PRESOLVE, + CLP_PARAM_STR_CRASH, + CLP_PARAM_STR_BIASLU, + CLP_PARAM_STR_PERTURBATION, + CLP_PARAM_STR_MESSAGES, + CLP_PARAM_STR_AUTOSCALE, + CLP_PARAM_STR_CHOLESKY, + CLP_PARAM_STR_KKT, + CLP_PARAM_STR_BARRIERSCALE, + CLP_PARAM_STR_GAMMA, + CLP_PARAM_STR_CROSSOVER, + CLP_PARAM_STR_PFI, + CLP_PARAM_NOTUSED_ALGORITHM, + + CBC_PARAM_STR_NODESTRATEGY = 251, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_NOTUSED_ADDCUTSSTRATEGY, + CBC_PARAM_STR_GOMORYCUTS, + CBC_PARAM_STR_PROBINGCUTS, + CBC_PARAM_STR_KNAPSACKCUTS, + CBC_PARAM_NOTUSED_ODDHOLECUTS, + CBC_PARAM_STR_ROUNDING, + CBC_PARAM_STR_SOLVER, + CBC_PARAM_STR_CLIQUECUTS, + CBC_PARAM_STR_COSTSTRATEGY, + CBC_PARAM_STR_FLOWCUTS, + CBC_PARAM_STR_MIXEDCUTS, + CBC_PARAM_STR_TWOMIRCUTS, + CBC_PARAM_STR_PREPROCESS, + + CLP_PARAM_ACTION_DIRECTORY = 301, + CLP_PARAM_ACTION_IMPORT, + CLP_PARAM_ACTION_EXPORT, + CLP_PARAM_ACTION_RESTORE, + CLP_PARAM_ACTION_SAVE, + CLP_PARAM_ACTION_DUALSIMPLEX, + CLP_PARAM_ACTION_PRIMALSIMPLEX, + CLP_PARAM_ACTION_MAXIMIZE, + CLP_PARAM_ACTION_MINIMIZE, + CLP_PARAM_ACTION_EXIT, + CLP_PARAM_ACTION_STDIN, + CLP_PARAM_ACTION_UNITTEST, + CLP_PARAM_ACTION_NETLIB_DUAL, + CLP_PARAM_ACTION_NETLIB_PRIMAL, + CLP_PARAM_ACTION_SOLUTION, + CLP_PARAM_ACTION_TIGHTEN, + CLP_PARAM_ACTION_FAKEBOUND, + CLP_PARAM_ACTION_HELP, + CLP_PARAM_ACTION_PLUSMINUS, + CLP_PARAM_ACTION_NETWORK, + CLP_PARAM_ACTION_ALLSLACK, + CLP_PARAM_ACTION_REVERSE, + CLP_PARAM_ACTION_BARRIER, + CLP_PARAM_ACTION_NETLIB_BARRIER, + CLP_PARAM_ACTION_REALLY_SCALE, + CLP_PARAM_ACTION_BASISIN, + CLP_PARAM_ACTION_BASISOUT, + CLP_PARAM_ACTION_SOLVECONTINUOUS, + CBC_PARAM_ACTION_BAB, + CBC_PARAM_ACTION_MIPLIB, + CLP_PARAM_ACTION_CLEARCUTS, + CLP_VERSION_NOTUSED_PRINTVERSION, + + CBC_PARAM_NOTUSED_OSLSTUFF = 401, + CBC_PARAM_NOTUSED_CBCSTUFF, + + CBC_PARAM_NOTUSED_INVALID = 1000 +}; + + +/// Very simple class for setting parameters + +class CbcParam { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructors + CbcParam ( ); + CbcParam (std::string name, std::string help, + double lower, double upper, CbcParameterType type, bool display = true); + CbcParam (std::string name, std::string help, + int lower, int upper, CbcParameterType type, bool display = true); + // Other strings will be added by insert + CbcParam (std::string name, std::string help, std::string firstValue, + CbcParameterType type, int defaultIndex = 0, bool display = true); + // Action + CbcParam (std::string name, std::string help, + CbcParameterType type, int indexNumber = -1, bool display = true); + /// Copy constructor. + CbcParam(const CbcParam &); + /// Assignment operator. This copies the data + CbcParam & operator=(const CbcParam & rhs); + /// Destructor + ~CbcParam ( ); + //@} + + /**@name stuff */ + //@{ + /// Insert string (only valid for keywords) + void append(std::string keyWord); + /// Adds one help line + void addHelp(std::string keyWord); + /// Returns name + inline std::string name( ) const { + return name_; + }; + /// Returns short help + inline std::string shortHelp( ) const { + return shortHelp_; + }; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(CbcModel & model, double value) const; + /// Gets a double parameter + double doubleParameter(CbcModel & model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(CbcModel & model, int value) const; + /// Gets a int parameter + int intParameter(CbcModel & model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(ClpSimplex * model, double value) const; + /// Gets a double parameter + double doubleParameter(ClpSimplex * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(ClpSimplex * model, int value) const; + /// Gets a int parameter + int intParameter(ClpSimplex * model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(OsiSolverInterface * model, double value) const; + /// Gets a double parameter + double doubleParameter(OsiSolverInterface * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(OsiSolverInterface * model, int value) const; + /// Gets a int parameter + int intParameter(OsiSolverInterface * model) const; + /// Checks a double parameter (nonzero code if error) + int checkDoubleParameter(double value) const; + /// Returns name which could match + std::string matchName ( ) const; + /// Returns parameter option which matches (-1 if none) + int parameterOption ( std::string check ) const; + /// Prints parameter options + void printOptions ( ) const; + /// Returns current parameter option + inline std::string currentOption ( ) const { + return definedKeyWords_[currentKeyWord_]; + } + /// Sets current parameter option + inline void setCurrentOption ( int value ) { + currentKeyWord_ = value; + } + /// Sets int value + inline void setIntValue ( int value ) { + intValue_ = value; + } + inline int intValue () const { + return intValue_; + } + /// Sets double value + inline void setDoubleValue ( double value ) { + doubleValue_ = value; + } + inline double doubleValue () const { + return doubleValue_; + } + /// Sets string value + inline void setStringValue ( std::string value ) { + stringValue_ = value; + } + inline std::string stringValue () const { + return stringValue_; + } + /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched + int matches (std::string input) const; + /// type + inline CbcParameterType type() const { + return type_; + } + /// whether to display + inline bool displayThis() const { + return display_; + } + /// Set Long help + inline void setLonghelp(const std::string help) { + longHelp_ = help; + } + /// Print Long help + void printLongHelp() const; + /// Print action and string + void printString() const; + /// type for classification + inline int indexNumber() const { + return indexNumber_; + } +private: + /// gutsOfConstructor + void gutsOfConstructor(); + //@} +////////////////// data ////////////////// +private: + + /**@name data + We might as well throw all type data in - could derive? + */ + //@{ + // Type see CbcParameterType + CbcParameterType type_; + /// If double == okay + double lowerDoubleValue_; + double upperDoubleValue_; + /// If int == okay + int lowerIntValue_; + int upperIntValue_; + // Length of name + unsigned int lengthName_; + // Minimum match + unsigned int lengthMatch_; + /// set of valid strings + std::vector<std::string> definedKeyWords_; + /// Name + std::string name_; + /// Short help + std::string shortHelp_; + /// Long help + std::string longHelp_; + /// Action + CbcParameterType action_; + /// Current keyWord (if a keyword parameter) + int currentKeyWord_; + /// Display on ? + bool display_; + /// Integer parameter - current value + int intValue_; + /// Double parameter - current value + double doubleValue_; + /// String parameter - current value + std::string stringValue_; + /// index number to use for display purposes + int indexNumber_; + //@} +}; +#endif /* CbcParam_H */ + diff --git a/thirdparty/linux/include/coin/coin/CbcPartialNodeInfo.hpp b/thirdparty/linux/include/coin/coin/CbcPartialNodeInfo.hpp new file mode 100644 index 0000000..446a3eb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcPartialNodeInfo.hpp @@ -0,0 +1,110 @@ +// $Id: CbcPartialNodeInfo.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/24/09 carved from CbcNode + +#ifndef CbcPartialNodeInfo_H +#define CbcPartialNodeInfo_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "CoinSearchTree.hpp" +#include "CbcBranchBase.hpp" +#include "CbcNodeInfo.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiCuts; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinWarmStartBasis; +class CbcCountRowCut; +class CbcModel; +class CbcNode; +class CbcSubProblem; +class CbcGeneralBranchingObject; +/** \brief Holds information for recreating a subproblem by incremental change + from the parent. + + A CbcPartialNodeInfo object contains changes to the bounds and basis, and + additional cuts, required to recreate a subproblem by modifying and + augmenting the parent subproblem. +*/ + +class CbcPartialNodeInfo : public CbcNodeInfo { + +public: + + /** \brief Modify model according to information at node + + The routine modifies the model according to bound and basis change + information at node and adds any cuts to the addCuts array. + */ + virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis, + CbcCountRowCut **addCuts, + int ¤tNumberCuts) const ; + + /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible) + virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ; + /** Builds up row basis backwards (until original model). + Returns NULL or previous one to apply . + Depends on Free being 0 and impossible for cuts + */ + virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis ) const ; + // Default Constructor + CbcPartialNodeInfo (); + + // Constructor from current state + CbcPartialNodeInfo (CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds, const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) ; + + // Copy constructor + CbcPartialNodeInfo ( const CbcPartialNodeInfo &); + + // Destructor + ~CbcPartialNodeInfo (); + + /// Clone + virtual CbcNodeInfo * clone() const; + /// Basis diff information + inline const CoinWarmStartDiff *basisDiff() const { + return basisDiff_ ; + } + /// Which variable (top bit if upper bound changing) + inline const int * variables() const { + return variables_; + } + // New bound + inline const double * newBounds() const { + return newBounds_; + } + /// Number of bound changes + inline int numberChangedBounds() const { + return numberChangedBounds_; + } +protected: + /* Data values */ + + /// Basis diff information + CoinWarmStartDiff *basisDiff_ ; + /// Which variable (top bit if upper bound changing) + int * variables_; + // New bound + double * newBounds_; + /// Number of bound changes + int numberChangedBounds_; +private: + + /// Illegal Assignment operator + CbcPartialNodeInfo & operator=(const CbcPartialNodeInfo& rhs); +}; + +#endif //CbcPartialNodeInfo_H + diff --git a/thirdparty/linux/include/coin/coin/CbcSOS.hpp b/thirdparty/linux/include/coin/coin/CbcSOS.hpp new file mode 100644 index 0000000..48ccece --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSOS.hpp @@ -0,0 +1,279 @@ +// $Id: CbcSOS.hpp 2070 2014-09-08 09:24:45Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcSOS_H +#define CbcSOS_H + +/** \brief Branching object for Special Ordered Sets of type 1 and 2. + + SOS1 are an ordered set of variables where at most one variable can be + non-zero. SOS1 are commonly defined with binary variables (interpreted as + selection between alternatives) but this is not necessary. An SOS1 with + all binary variables is a special case of a clique (setting any one + variable to 1 forces all others to 0). + + In theory, the implementation makes no assumptions about integrality in + Type 1 sets. In practice, there are places where the code seems to have been + written with a binary SOS mindset. Current development of SOS branching + objects is proceeding in OsiSOS. + + SOS2 are an ordered set of variables in which at most two consecutive + variables can be non-zero and must sum to 1 (interpreted as interpolation + between two discrete values). By definition the variables are non-integer. +*/ + +class CbcSOS : public CbcObject { + +public: + + // Default Constructor + CbcSOS (); + + /** \brief Constructor with SOS type and member information + + Type specifies SOS 1 or 2. Identifier is an arbitrary value. + + Which should be an array of variable indices with numberMembers entries. + Weights can be used to assign arbitrary weights to variables, in the order + they are specified in which. If no weights are provided, a default array of + 0, 1, 2, ... is generated. + */ + + CbcSOS (CbcModel * model, int numberMembers, + const int * which, const double * weights, int identifier, + int type = 1); + + // Copy constructor + CbcSOS ( const CbcSOS &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSOS & operator=( const CbcSOS& rhs); + + // Destructor + virtual ~CbcSOS (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /// This looks at solution and sets bounds to contain solution + virtual void feasibleRegion(); + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & data) ; + using CbcObject::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + /// Redoes data when sequence numbers change + virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns); + + /// Construct an OsiSOS object + OsiSOS * osiObject(const OsiSolverInterface * solver) const; + /// Number of members + inline int numberMembers() const { + return numberMembers_; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const { + return members_; + } + + /// SOS type + inline int sosType() const { + return sosType_; + } + /// Down number times + inline int numberTimesDown() const { + return numberTimesDown_; + } + /// Up number times + inline int numberTimesUp() const { + return numberTimesUp_; + } + + /** Array of weights */ + inline const double * weights() const { + return weights_; + } + + /// Set number of members + inline void setNumberMembers(int n) { + numberMembers_ = n; + } + + /// Members (indices in range 0 ... numberColumns-1) + inline int * mutableMembers() const { + return members_; + } + + /** Array of weights */ + inline double * mutableWeights() const { + return weights_; + } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const { + return (sosType_ == 1 && integerValued_); + } + /// Set whether set is integer valued or not + inline void setIntegerValued(bool yesNo) { + integerValued_ = yesNo; + } +private: + /// data + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /** \brief Weights for individual members + + Arbitrary weights for members. Can be used to attach meaning to variable + values independent of objective coefficients. For example, if the SOS set + comprises binary variables used to choose a facility of a given size, the + weight could be the corresponding facilty size. Fractional values of the + SOS variables can then be used to estimate ideal facility size. + + Weights cannot be completely arbitrary. From the code, they must be + differ by at least 1.0e-7 + */ + + double * weights_; + /// Current pseudo-shadow price estimate down + mutable double shadowEstimateDown_; + /// Current pseudo-shadow price estimate up + mutable double shadowEstimateUp_; + /// Down pseudo ratio + double downDynamicPseudoRatio_; + /// Up pseudo ratio + double upDynamicPseudoRatio_; + /// Number of times we have gone down + int numberTimesDown_; + /// Number of times we have gone up + int numberTimesUp_; + /// Number of members + int numberMembers_; + /// SOS type + int sosType_; + /// Whether integer valued + bool integerValued_; + /// Whether odd values e.g. negative + bool oddValues_; +}; + +/** Branching object for Special ordered sets + + Variable_ is the set id number (redundant, as the object also holds a + pointer to the set. + */ +class CbcSOSBranchingObject : public CbcBranchingObject { + +public: + + // Default Constructor + CbcSOSBranchingObject (); + + // Useful constructor + CbcSOSBranchingObject (CbcModel * model, const CbcSOS * clique, + int way, + double separator); + + // Copy constructor + CbcSOSBranchingObject ( const CbcSOSBranchingObject &); + + // Assignment operator + CbcSOSBranchingObject & operator=( const CbcSOSBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + // Destructor + virtual ~CbcSOSBranchingObject (); + + using CbcBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(); + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const ; + + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch() { + CbcBranchingObject::previousBranch(); + computeNonzeroRange(); + } + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SoSBranchObj; + } + + /** Compare the original object of \c this with the original object of \c + brObj. Assumes that there is an ordering of the original objects. + This method should be invoked only if \c this and brObj are of the same + type. + Return negative/0/positive depending on whether \c this is + smaller/same/larger than the argument. + */ + virtual int compareOriginalObject(const CbcBranchingObject* brObj) const; + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + + /** Fill out the \c firstNonzero_ and \c lastNonzero_ data members */ + void computeNonzeroRange(); + +private: + /// data + const CbcSOS * set_; + /// separator + double separator_; + /** The following two members describe the range in the members_ of the + original object that whose upper bound is not fixed to 0. This is not + necessary for Cbc to function correctly, this is there for heuristics so + that separate branching decisions on the same object can be pooled into + one branching object. */ + int firstNonzero_; + int lastNonzero_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcSimpleInteger.hpp b/thirdparty/linux/include/coin/coin/CbcSimpleInteger.hpp new file mode 100644 index 0000000..cde7d8c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSimpleInteger.hpp @@ -0,0 +1,286 @@ +// $Id: CbcSimpleInteger.hpp 1943 2013-07-21 09:05:45Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/9/2009-- carved out of CbcBranchActual + +#ifndef CbcSimpleInteger_H +#define CbcSimpleInteger_H + +#include "CbcBranchingObject.hpp" + +/** Simple branching object for an integer variable + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcIntegerBranchingObject : public CbcBranchingObject { + +public: + + /// Default constructor + CbcIntegerBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcIntegerBranchingObject (CbcModel *model, int variable, + int way , double value) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcIntegerBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcIntegerBranchingObject ( const CbcIntegerBranchingObject &); + + /// Assignment operator + CbcIntegerBranchingObject & operator= (const CbcIntegerBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcIntegerBranchingObject (); + + /// Does part of constructor + void fillPart ( int variable, int way , double value) ; + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + Returns change in guessed objective on next branch + */ + virtual double branch(); + /** Update bounds in solver as in 'branch' and update given bounds. + branchState is -1 for 'down' +1 for 'up' */ + virtual void fix(OsiSolverInterface * solver, + double * lower, double * upper, + int branchState) const ; + /** Change (tighten) bounds in object to reflect bounds in solver. + Return true if now fixed */ + virtual bool tighten(OsiSolverInterface * ) ; + +#ifdef JJF_ZERO + // No need to override. Default works fine. + /** Reset every information so that the branching object appears to point to + the previous child. This method does not need to modify anything in any + solver. */ + virtual void previousBranch(); +#endif + + using CbcBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(); + + /// Lower and upper bounds for down branch + inline const double * downBounds() const { + return down_; + } + /// Lower and upper bounds for up branch + inline const double * upBounds() const { + return up_; + } + /// Set lower and upper bounds for down branch + inline void setDownBounds(const double bounds[2]) { + memcpy(down_, bounds, 2*sizeof(double)); + } + /// Set lower and upper bounds for up branch + inline void setUpBounds(const double bounds[2]) { + memcpy(up_, bounds, 2*sizeof(double)); + } +#ifdef FUNNY_BRANCHING + /** Which variable (top bit if upper bound changing, + next bit if on down branch */ + inline const int * variables() const { + return variables_; + } + // New bound + inline const double * newBounds() const { + return newBounds_; + } + /// Number of bound changes + inline int numberExtraChangedBounds() const { + return numberExtraChangedBounds_; + } + /// Just apply extra bounds to one variable - COIN_DBL_MAX ignore + int applyExtraBounds(int iColumn, double lower, double upper, int way) ; + /// Deactivate bounds for branching + void deactivate(); + /// Are active bounds for branching + inline bool active() const { + return (down_[1] != -COIN_DBL_MAX); + } +#endif + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SimpleIntegerBranchObj; + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +#ifdef FUNNY_BRANCHING + /** Which variable (top bit if upper bound changing) + next bit if changing on down branch only */ + int * variables_; + // New bound + double * newBounds_; + /// Number of Extra bound changes + int numberExtraChangedBounds_; +#endif +}; + +/// Define a single integer class + + +class CbcSimpleInteger : public CbcObject { + +public: + + // Default Constructor + CbcSimpleInteger (); + + // Useful constructor - passed model and index + CbcSimpleInteger (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed model and Osi object + CbcSimpleInteger (CbcModel * model, const OsiSimpleInteger * object); + + // Copy constructor + CbcSimpleInteger ( const CbcSimpleInteger &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleInteger & operator=( const CbcSimpleInteger& rhs); + + // Destructor + virtual ~CbcSimpleInteger (); + /// Construct an OsiSimpleInteger object + OsiSimpleInteger * osiObject() const; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + using CbcObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + /// Fills in a created branching object + /*virtual*/ void fillCreateBranch(CbcIntegerBranchingObject * branching, const OsiBranchingInformation * info, int way) ; + + using CbcObject::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. The algorithm takes a bit of care in order to compensate for + minor numerical inaccuracy. + */ + virtual void feasibleRegion(); + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /// Set column number + inline void setColumnNumber(int value) { + columnNumber_ = value; + } + + /** Reset variable bounds to their original values. + + Bounds may be tightened, so it may be good to be able to set this info in object. + */ + virtual void resetBounds(const OsiSolverInterface * solver) ; + + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns) ; + /// Original bounds + inline double originalLowerBound() const { + return originalLower_; + } + inline void setOriginalLowerBound(double value) { + originalLower_ = value; + } + inline double originalUpperBound() const { + return originalUpper_; + } + inline void setOriginalUpperBound(double value) { + originalUpper_ = value; + } + /// Breakeven e.g 0.7 -> >= 0.7 go up first + inline double breakEven() const { + return breakEven_; + } + /// Set breakeven e.g 0.7 -> >= 0.7 go up first + inline void setBreakEven(double value) { + breakEven_ = value; + } + + +protected: + /// data + + /// Original lower bound + double originalLower_; + /// Original upper bound + double originalUpper_; + /// Breakeven i.e. >= this preferred is up + double breakEven_; + /// Column number in model + int columnNumber_; + /// If -1 down always chosen first, +1 up always, 0 normal + int preferredWay_; +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcSimpleIntegerDynamicPseudoCost.hpp b/thirdparty/linux/include/coin/coin/CbcSimpleIntegerDynamicPseudoCost.hpp new file mode 100644 index 0000000..7952d57 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSimpleIntegerDynamicPseudoCost.hpp @@ -0,0 +1,564 @@ +// $Id: CbcSimpleIntegerDynamicPseudoCost.hpp 2094 2014-11-18 11:15:36Z forrest $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/17/2009 - carved out of CbcBranchDynamic + +#ifndef CbcSimpleIntegerDynamicPseudoCost_H +#define CbcSimpleIntegerDynamicPseudoCost_H + +#include "CbcSimpleInteger.hpp" + +#define TYPERATIO 0.9 +#define MINIMUM_MOVEMENT 0.1 +#define TYPE2 0 +// was 1 - but that looks flakey +#define INFEAS 1 +#define MOD_SHADOW 1 +// weight at 1.0 is max min +#define WEIGHT_AFTER 0.8 +#define WEIGHT_BEFORE 0.1 +//Stolen from Constraint Integer Programming book (with epsilon change) +#define WEIGHT_PRODUCT + + +/** Define a single integer class but with dynamic pseudo costs. + Based on work by Achterberg, Koch and Martin. + + It is wild overkill but to keep design all twiddly things are in each. + This could be used for fine tuning. + + */ + + +class CbcSimpleIntegerDynamicPseudoCost : public CbcSimpleInteger { + +public: + + // Default Constructor + CbcSimpleIntegerDynamicPseudoCost (); + + // Useful constructor - passed model index + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed model index and pseudo costs + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn, + double downDynamicPseudoCost, double upDynamicPseudoCost); + + // Useful constructor - passed model index and pseudo costs + CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int dummy, int iColumn, + double downDynamicPseudoCost, double upDynamicPseudoCost); + + // Copy constructor + CbcSimpleIntegerDynamicPseudoCost ( const CbcSimpleIntegerDynamicPseudoCost &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleIntegerDynamicPseudoCost & operator=( const CbcSimpleIntegerDynamicPseudoCost& rhs); + + // Destructor + virtual ~CbcSimpleIntegerDynamicPseudoCost (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + + /// Fills in a created branching object + // void fillCreateBranch(CbcIntegerBranchingObject * branching, const OsiBranchingInformation * info, int way) ; + + + /** Pass in information on branch just done and create CbcObjectUpdateData instance. + If object does not need data then backward pointer will be NULL. + Assumes can get information from solver */ + virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, + const CbcNode * node, + const CbcBranchingObject * branchingObject); + /// Update object by CbcObjectUpdateData + virtual void updateInformation(const CbcObjectUpdateData & data) ; + /// Copy some information i.e. just variable stuff + void copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject); + /// Updates stuff like pseudocosts before threads + virtual void updateBefore(const OsiObject * rhs) ; + /// Updates stuff like pseudocosts after threads finished + virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) ; + /// Updates stuff like pseudocosts after mini branch and bound + void updateAfterMini(int numberDown, int numberDownInfeasible, double sumDown, + int numberUp, int numberUpInfeasible, double sumUp); + + using CbcSimpleInteger::solverBranch ; + /** Create an OsiSolverBranch object + + This returns NULL if branch not represented by bound changes + */ + virtual OsiSolverBranch * solverBranch() const; + + /// Down pseudo cost + inline double downDynamicPseudoCost() const { + return downDynamicPseudoCost_; + } + /// Set down pseudo cost + void setDownDynamicPseudoCost(double value) ; + /// Modify down pseudo cost in a slightly different way + void updateDownDynamicPseudoCost(double value); + + /// Up pseudo cost + inline double upDynamicPseudoCost() const { + return upDynamicPseudoCost_; + } + /// Set up pseudo cost + void setUpDynamicPseudoCost(double value); + /// Modify up pseudo cost in a slightly different way + void updateUpDynamicPseudoCost(double value); + + /// Down pseudo shadow price cost + inline double downShadowPrice() const { + return downShadowPrice_; + } + /// Set down pseudo shadow price cost + inline void setDownShadowPrice(double value) { + downShadowPrice_ = value; + } + /// Up pseudo shadow price cost + inline double upShadowPrice() const { + return upShadowPrice_; + } + /// Set up pseudo shadow price cost + inline void setUpShadowPrice(double value) { + upShadowPrice_ = value; + } + + /// Up down separator + inline double upDownSeparator() const { + return upDownSeparator_; + } + /// Set up down separator + inline void setUpDownSeparator(double value) { + upDownSeparator_ = value; + } + + /// Down sum cost + inline double sumDownCost() const { + return sumDownCost_; + } + /// Set down sum cost + inline void setSumDownCost(double value) { + sumDownCost_ = value; + } + /// Add to down sum cost and set last and square + inline void addToSumDownCost(double value) { + sumDownCost_ += value; + lastDownCost_ = value; + } + + /// Up sum cost + inline double sumUpCost() const { + return sumUpCost_; + } + /// Set up sum cost + inline void setSumUpCost(double value) { + sumUpCost_ = value; + } + /// Add to up sum cost and set last and square + inline void addToSumUpCost(double value) { + sumUpCost_ += value; + lastUpCost_ = value; + } + + /// Down sum change + inline double sumDownChange() const { + return sumDownChange_; + } + /// Set down sum change + inline void setSumDownChange(double value) { + sumDownChange_ = value; + } + /// Add to down sum change + inline void addToSumDownChange(double value) { + sumDownChange_ += value; + } + + /// Up sum change + inline double sumUpChange() const { + return sumUpChange_; + } + /// Set up sum change + inline void setSumUpChange(double value) { + sumUpChange_ = value; + } + /// Add to up sum change and set last and square + inline void addToSumUpChange(double value) { + sumUpChange_ += value; + } + + /// Sum down decrease number infeasibilities from strong or actual + inline double sumDownDecrease() const { + return sumDownDecrease_; + } + /// Set sum down decrease number infeasibilities from strong or actual + inline void setSumDownDecrease(double value) { + sumDownDecrease_ = value; + } + /// Add to sum down decrease number infeasibilities from strong or actual + inline void addToSumDownDecrease(double value) { + sumDownDecrease_ += value;/*lastDownDecrease_ = (int) value;*/ + } + + /// Sum up decrease number infeasibilities from strong or actual + inline double sumUpDecrease() const { + return sumUpDecrease_; + } + /// Set sum up decrease number infeasibilities from strong or actual + inline void setSumUpDecrease(double value) { + sumUpDecrease_ = value; + } + /// Add to sum up decrease number infeasibilities from strong or actual + inline void addToSumUpDecrease(double value) { + sumUpDecrease_ += value;/*lastUpDecrease_ = (int) value;*/ + } + + /// Down number times + inline int numberTimesDown() const { + return numberTimesDown_; + } + /// Set down number times + inline void setNumberTimesDown(int value) { + numberTimesDown_ = value; + } + /// Increment down number times + inline void incrementNumberTimesDown() { + numberTimesDown_++; + } + + /// Up number times + inline int numberTimesUp() const { + return numberTimesUp_; + } + /// Set up number times + inline void setNumberTimesUp(int value) { + numberTimesUp_ = value; + } + /// Increment up number times + inline void incrementNumberTimesUp() { + numberTimesUp_++; + } + + /// Number times branched + inline int numberTimesBranched() const { + return numberTimesDown_ + numberTimesUp_; + } + /// Down number times infeasible + inline int numberTimesDownInfeasible() const { + return numberTimesDownInfeasible_; + } + /// Set down number times infeasible + inline void setNumberTimesDownInfeasible(int value) { + numberTimesDownInfeasible_ = value; + } + /// Increment down number times infeasible + inline void incrementNumberTimesDownInfeasible() { + numberTimesDownInfeasible_++; + } + + /// Up number times infeasible + inline int numberTimesUpInfeasible() const { + return numberTimesUpInfeasible_; + } + /// Set up number times infeasible + inline void setNumberTimesUpInfeasible(int value) { + numberTimesUpInfeasible_ = value; + } + /// Increment up number times infeasible + inline void incrementNumberTimesUpInfeasible() { + numberTimesUpInfeasible_++; + } + + /// Number of times before trusted + inline int numberBeforeTrust() const { + return numberBeforeTrust_; + } + /// Set number of times before trusted + inline void setNumberBeforeTrust(int value) { + numberBeforeTrust_ = value; + } + /// Increment number of times before trusted + inline void incrementNumberBeforeTrust() { + numberBeforeTrust_++; + } + + /// Return "up" estimate + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// method - see below for details + inline int method() const { + return method_; + } + /// Set method + inline void setMethod(int value) { + method_ = value; + } + + /// Pass in information on a down branch + void setDownInformation(double changeObjectiveDown, int changeInfeasibilityDown); + /// Pass in information on a up branch + void setUpInformation(double changeObjectiveUp, int changeInfeasibilityUp); + /// Pass in probing information + void setProbingInformation(int fixedDown, int fixedUp); + + /// Print - 0 -summary, 1 just before strong + void print(int type = 0, double value = 0.0) const; + /// Same - returns true if contents match(ish) + bool same(const CbcSimpleIntegerDynamicPseudoCost * obj) const; +protected: + /// data + + /// Down pseudo cost + double downDynamicPseudoCost_; + /// Up pseudo cost + double upDynamicPseudoCost_; + /** Up/down separator + If >0.0 then do first branch up if value-floor(value) + >= this value + */ + double upDownSeparator_; + /// Sum down cost from strong or actual + double sumDownCost_; + /// Sum up cost from strong or actual + double sumUpCost_; + /// Sum of all changes to x when going down + double sumDownChange_; + /// Sum of all changes to x when going up + double sumUpChange_; + /// Current pseudo-shadow price estimate down + mutable double downShadowPrice_; + /// Current pseudo-shadow price estimate up + mutable double upShadowPrice_; + /// Sum down decrease number infeasibilities from strong or actual + double sumDownDecrease_; + /// Sum up decrease number infeasibilities from strong or actual + double sumUpDecrease_; + /// Last down cost from strong (i.e. as computed by last strong) + double lastDownCost_; + /// Last up cost from strong (i.e. as computed by last strong) + double lastUpCost_; + /// Last down decrease number infeasibilities from strong (i.e. as computed by last strong) + mutable int lastDownDecrease_; + /// Last up decrease number infeasibilities from strong (i.e. as computed by last strong) + mutable int lastUpDecrease_; + /// Number of times we have gone down + int numberTimesDown_; + /// Number of times we have gone up + int numberTimesUp_; + /// Number of times we have been infeasible going down + int numberTimesDownInfeasible_; + /// Number of times we have been infeasible going up + int numberTimesUpInfeasible_; + /// Number of branches before we trust + int numberBeforeTrust_; + /// Number of local probing fixings going down + int numberTimesDownLocalFixed_; + /// Number of local probing fixings going up + int numberTimesUpLocalFixed_; + /// Number of total probing fixings going down + double numberTimesDownTotalFixed_; + /// Number of total probing fixings going up + double numberTimesUpTotalFixed_; + /// Number of times probing done + int numberTimesProbingTotal_; + /// Number of times infeasible when tested + /** Method - + 0 - pseudo costs + 1 - probing + */ + int method_; +}; +/** Simple branching object for an integer variable with pseudo costs + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class CbcIntegerPseudoCostBranchingObject : public CbcIntegerBranchingObject { + +public: + + /// Default constructor + CbcIntegerPseudoCostBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + CbcIntegerPseudoCostBranchingObject (CbcModel *model, int variable, + int way , double value) ; + + /** Create a degenerate branch object + + Specifies a `one-way branch'. Calling branch() for this object will + always result in lowerValue <= x <= upperValue. Used to fix a variable + when lowerValue = upperValue. + */ + + CbcIntegerPseudoCostBranchingObject (CbcModel *model, int variable, int way, + double lowerValue, double upperValue) ; + + /// Copy constructor + CbcIntegerPseudoCostBranchingObject ( const CbcIntegerPseudoCostBranchingObject &); + + /// Assignment operator + CbcIntegerPseudoCostBranchingObject & operator= (const CbcIntegerPseudoCostBranchingObject& rhs); + + /// Clone + virtual CbcBranchingObject * clone() const; + + /// Destructor + virtual ~CbcIntegerPseudoCostBranchingObject (); + + using CbcBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + This version also changes guessed objective value + */ + virtual double branch(); + + /// Change in guessed + inline double changeInGuessed() const { + return changeInGuessed_; + } + /// Set change in guessed + inline void setChangeInGuessed(double value) { + changeInGuessed_ = value; + } + + /** Return the type (an integer identifier) of \c this */ + virtual CbcBranchObjType type() const { + return SimpleIntegerDynamicPseudoCostBranchObj; + } + + /** Compare the \c this with \c brObj. \c this and \c brObj must be os the + same type and must have the same original object, but they may have + different feasible regions. + Return the appropriate CbcRangeCompare value (first argument being the + sub/superset if that's the case). In case of overlap (and if \c + replaceIfOverlap is true) replace the current branching object with one + whose feasible region is the overlap. + */ + virtual CbcRangeCompare compareBranchingObject + (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false); + +protected: + /// Change in guessed objective value for next branch + double changeInGuessed_; +}; +#ifdef SWITCH_VARIABLES +/** Define a single integer class but with associated switched variable + So Binary variable switches on/off a continuous variable + designed for badly scaled problems + */ + + +class CbcSwitchingBinary : public CbcSimpleIntegerDynamicPseudoCost { + +public: + + // Default Constructor + CbcSwitchingBinary (); + + // Useful constructor + CbcSwitchingBinary (CbcSimpleIntegerDynamicPseudoCost * oldObject, + int nOdd,const int * other, const int * otherRow); + + + // Copy constructor + CbcSwitchingBinary ( const CbcSwitchingBinary &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSwitchingBinary & operator=( const CbcSwitchingBinary& rhs); + + // Destructor + virtual ~CbcSwitchingBinary (); + + /// Add in zero switches + void addZeroSwitches(int nAdd,const int * columns); + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Same - returns true if contents match(ish) + bool same(const CbcSwitchingBinary * obj) const; + /// Set associated bounds + virtual int setAssociatedBounds(OsiSolverInterface * solver=NULL, + int cleanBasis=0) const; + /// Check associated bounds + int checkAssociatedBounds(const OsiSolverInterface * solver,const double * solution, + int printLevel, int state[3], int & nBadFixed) const; + /// Lower bound when binary zero + inline const double * zeroLowerBound() const + { return zeroLowerBound_; } + /// Lower bound when binary one + inline const double * oneLowerBound() const + { return oneLowerBound_; } + /// Upper bound when binary zero + inline const double * zeroUpperBound() const + { return zeroUpperBound_; } + /// Upper bound when binary one + inline const double * oneUpperBound() const + { return oneUpperBound_; } + /** Continuous variable - + */ + inline const int * otherVariable() const + { return otherVariable_;} + /// Number of other variables + inline int numberOther() const + { return numberOther_;} + /** Type + 1 - single switch + 2 - double switch + 3 - both + */ + inline int type() const + { return type_;} +protected: + /// data + + /// Lower bound when binary zero + double * zeroLowerBound_; + /// Lower bound when binary one + double * oneLowerBound_; + /// Upper bound when binary zero + double * zeroUpperBound_; + /// Upper bound when binary one + double * oneUpperBound_; + /** Continuous variable - + */ + int * otherVariable_; + /// Number of other variables + int numberOther_; + /** Type + 1 - single switch + 2 - double switch + 3 - both + */ + int type_; +}; +#endif +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcSimpleIntegerPseudoCost.hpp b/thirdparty/linux/include/coin/coin/CbcSimpleIntegerPseudoCost.hpp new file mode 100644 index 0000000..c760bd6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSimpleIntegerPseudoCost.hpp @@ -0,0 +1,114 @@ +// $Id: CbcSimpleIntegerPseudoCost.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcSimpleIntegerPseudoCost_H +#define CbcSimpleIntegerPseudoCost_H + +#include "CbcSimpleInteger.hpp" +/// Define a single integer class but with pseudo costs + +class CbcSimpleIntegerPseudoCost : public CbcSimpleInteger { + +public: + + // Default Constructor + CbcSimpleIntegerPseudoCost (); + + // Useful constructor - passed model index + CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn, double breakEven = 0.5); + + // Useful constructor - passed and model index and pseudo costs + CbcSimpleIntegerPseudoCost (CbcModel * model, int iColumn, + double downPseudoCost, double upPseudoCost); + // Useful constructor - passed and model index and pseudo costs + CbcSimpleIntegerPseudoCost (CbcModel * model, int dummy, int iColumn, + double downPseudoCost, double upPseudoCost); + + // Copy constructor + CbcSimpleIntegerPseudoCost ( const CbcSimpleIntegerPseudoCost &); + + /// Clone + virtual CbcObject * clone() const; + + // Assignment operator + CbcSimpleIntegerPseudoCost & operator=( const CbcSimpleIntegerPseudoCost& rhs); + + // Destructor + virtual ~CbcSimpleIntegerPseudoCost (); + + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, + int &preferredWay) const; + + /// Creates a branching object + virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ; + + /// Down pseudo cost + inline double downPseudoCost() const { + return downPseudoCost_; + } + /// Set down pseudo cost + inline void setDownPseudoCost(double value) { + downPseudoCost_ = value; + } + + /// Up pseudo cost + inline double upPseudoCost() const { + return upPseudoCost_; + } + /// Set up pseudo cost + inline void setUpPseudoCost(double value) { + upPseudoCost_ = value; + } + + /// Up down separator + inline double upDownSeparator() const { + return upDownSeparator_; + } + /// Set up down separator + inline void setUpDownSeparator(double value) { + upDownSeparator_ = value; + } + + /// Return "up" estimate + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// method - see below for details + inline int method() const { + return method_; + } + /// Set method + inline void setMethod(int value) { + method_ = value; + } + +protected: + /// data + + /// Down pseudo cost + double downPseudoCost_; + /// Up pseudo cost + double upPseudoCost_; + /** Up/down separator + If >0.0 then do first branch up if value-floor(value) + >= this value + */ + double upDownSeparator_; + /** Method - + 0 - normal - return min (up,down) + 1 - if before any solution return CoinMax(up,down) + 2 - if before branched solution return CoinMax(up,down) + 3 - always return CoinMax(up,down) + */ + int method_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcSolver.hpp b/thirdparty/linux/include/coin/coin/CbcSolver.hpp new file mode 100644 index 0000000..34052e1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSolver.hpp @@ -0,0 +1,447 @@ +/* $Id: CbcSolver.hpp 1998 2013-12-19 18:11:05Z forrest $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +/*! \file CbcSolver.hpp + \brief Defines CbcSolver, the proposed top-level class for the new-style + cbc solver. + + This class is currently an orphan. With the removal of all code flagged + with the NEW_STYLE_SOLVER, this class is never instantiated (and cannot + be instantiated). It is available to be coopted as a top-level object + wrapping the current CbcMain0 and CbcMain1, should that appear to be a + desireable path forward. -- lh, 091211 -- +*/ + +#ifndef CbcSolver_H +#define CbcSolver_H + +#include <string> +#include <vector> +#include "CoinMessageHandler.hpp" +#include "OsiClpSolverInterface.hpp" + +#if CBC_OTHER_SOLVER==1 +#include "OsiCpxSolverInterface.hpp" +#endif + +#include "CbcModel.hpp" +#include "CbcOrClpParam.hpp" + +class CbcUser; +class CbcStopNow; +class CglCutGenerator; + +//############################################################################# + +/*! \brief This allows the use of the standalone solver in a flexible manner. + + It has an original OsiClpSolverInterface and CbcModel which it can use + repeatedly, e.g., to get a heuristic solution and then start again. + + So I [jjf] will need a primitive scripting language which can then call + solve and manipulate solution value and solution arrays. + + Also provides for user callback functions. Currently two ideas in + gestation, CbcUser and CbcStopNow. The latter seems limited to deciding + whether or not to stop. The former seems completely general, with a notion + of importing and exporting, and a `solve', which should be interpreted as + `do whatever this user function does'. + + Parameter initialisation is at last centralised in fillParameters(). +*/ + +class CbcSolver { + +public: + ///@name Solve method + //@{ + /** This takes a list of commands, does "stuff" and returns + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + int solve(int argc, const char * argv[], int returnMode); + /** This takes a list of commands, does "stuff" and returns + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + int solve(const char * input, int returnMode); + //@} + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcSolver(); + + /// Constructor from solver + CbcSolver(const OsiClpSolverInterface &); + + /// Constructor from model + CbcSolver(const CbcModel &); + + /** Copy constructor . + */ + CbcSolver(const CbcSolver & rhs); + + /// Assignment operator + CbcSolver & operator=(const CbcSolver& rhs); + + /// Destructor + ~CbcSolver (); + /// Fill with standard parameters + void fillParameters(); + /*! \brief Set default values in solvers from parameters + + Misleading. The current code actually reads default values from + the underlying solvers and installs them as default values for a subset of + parameters in #parameters_. + */ + void fillValuesInSolver(); + /// Add user function + void addUserFunction(CbcUser * function); + /// Set user call back + void setUserCallBack(CbcStopNow * function); + /// Add cut generator + void addCutGenerator(CglCutGenerator * generator); + //@} + ///@name miscellaneous methods to line up with old + //@{ + // analyze model + int * analyze(OsiClpSolverInterface * solverMod, int & numberChanged, double & increment, + bool changeInt, CoinMessageHandler * generalMessageHandler); + /** 1 - add heuristics to model + 2 - do heuristics (and set cutoff and best solution) + 3 - for miplib test so skip some + (out model later) + */ + //int doHeuristics(CbcModel * model, int type); + /** Updates model_ from babModel_ according to returnMode + returnMode - + 0 model and solver untouched - babModel updated + 1 model updated - just with solution basis etc + 2 model updated i.e. as babModel (babModel NULL) (only use without preprocessing) + */ + void updateModel(ClpSimplex * model2, int returnMode); + //@} + ///@name useful stuff + //@{ + /// Get int value + int intValue(CbcOrClpParameterType type) const; + /// Set int value + void setIntValue(CbcOrClpParameterType type, int value); + /// Get double value + double doubleValue(CbcOrClpParameterType type) const; + /// Set double value + void setDoubleValue(CbcOrClpParameterType type, double value); + /// User function (NULL if no match) + CbcUser * userFunction(const char * name) const; + /// Return original Cbc model + inline CbcModel * model() { + return &model_; + } + /// Return updated Cbc model + inline CbcModel * babModel() { + return babModel_; + } + /// Number of userFunctions + inline int numberUserFunctions() const { + return numberUserFunctions_; + } + /// User function array + inline CbcUser ** userFunctionArray() const { + return userFunction_; + } + /// Copy of model on initial load (will contain output solutions) + inline OsiClpSolverInterface * originalSolver() const { + return originalSolver_; + } + /// Copy of model on initial load + inline CoinModel * originalCoinModel() const { + return originalCoinModel_; + } + /// Copy of model on initial load (will contain output solutions) + void setOriginalSolver(OsiClpSolverInterface * originalSolver); + /// Copy of model on initial load + void setOriginalCoinModel(CoinModel * originalCoinModel); + /// Number of cutgenerators + inline int numberCutGenerators() const { + return numberCutGenerators_; + } + /// Cut generator array + inline CglCutGenerator ** cutGeneratorArray() const { + return cutGenerator_; + } + /// Start time + inline double startTime() const { + return startTime_; + } + /// Whether to print to std::cout + inline void setPrinting(bool onOff) { + noPrinting_ = !onOff; + } + /// Where to start reading commands + inline void setReadMode(int value) { + readMode_ = value; + } + //@} +private: + ///@name Private member data + //@{ + + /// Reference model + CbcModel model_; + + /// Updated model + CbcModel * babModel_; + + /// User functions + CbcUser ** userFunction_; + /** Status of user functions + 0 - not used + 1 - needs cbc_load + 2 - available - data in coinModel + 3 - data loaded - can do cbc_save + */ + int * statusUserFunction_; + /// Copy of model on initial load (will contain output solutions) + OsiClpSolverInterface * originalSolver_; + /// Copy of model on initial load + CoinModel * originalCoinModel_; + /// Cut generators + CglCutGenerator ** cutGenerator_; + /// Number of user functions + int numberUserFunctions_; + /// Number of cut generators + int numberCutGenerators_; + /// Stop now stuff + CbcStopNow * callBack_; + /// Cpu time at instantiation + double startTime_; + /// Parameters and values + CbcOrClpParam * parameters_; + /// Number of parameters + int numberParameters_ ; + /// Whether to do miplib test + bool doMiplib_; + /// Whether to print to std::cout + bool noPrinting_; + /// Where to start reading commands + int readMode_; + //@} +}; +//############################################################################# + +/// Structure to hold useful arrays +typedef struct { + // Priorities + int * priorities_; + // SOS priorities + int * sosPriority_; + // Direction to branch first + int * branchDirection_; + // Input solution + double * primalSolution_; + // Down pseudo costs + double * pseudoDown_; + // Up pseudo costs + double * pseudoUp_; +} CbcSolverUsefulData2; + +//############################################################################# + +/** + The CbcSolver class was taken out at a 9/12/09 meeting + This is a feeble replacement. + At present everything is public +*/ +class CbcSolverUsefulData { + +public: + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcSolverUsefulData(); + + /** Copy constructor . + */ + CbcSolverUsefulData(const CbcSolverUsefulData & rhs); + + /// Assignment operator + CbcSolverUsefulData & operator=(const CbcSolverUsefulData& rhs); + + /// Destructor + ~CbcSolverUsefulData (); + //@} + + ///@name Member data + //@{ + // For time + double totalTime_; + // Parameters + CbcOrClpParam parameters_[CBCMAXPARAMETERS]; + // Printing + bool noPrinting_; + // Whether to use signal handler + bool useSignalHandler_; + // Number of Parameters + int numberParameters_; + // Default pump tuning + int initialPumpTune_; + //@} +}; +/// And this uses it +// When we want to load up CbcModel with options first +void CbcMain0 (CbcModel & babSolver,CbcSolverUsefulData & solverData); +int CbcMain1 (int argc, const char *argv[], CbcModel & babSolver, int (CbcModel * currentSolver, int whereFrom),CbcSolverUsefulData & solverData); + +//############################################################################# + +/*! \brief A class to allow the use of unknown user functionality + + For example, access to a modelling language (CbcAmpl). +*/ +class CbcUser { + +public: + ///@name import/export methods + //@{ + /*! \brief Import - gets full command arguments + + \return + - -1 - no action + - 0 - data read in without error + - 1 - errors + */ + virtual int importData(CbcSolver * /*model*/, int & /*argc*/, char ** /*argv[]*/) { + return -1; + } + + /*! \brief Export + + Values for mode: + - 1 OsiClpSolver + - 2 CbcModel + - add 10 if infeasible from odd situation + */ + virtual void exportSolution(CbcSolver * /*model*/, + int /*mode*/, const char * /*message*/ = NULL) {} + + /// Export Data (i.e. at very end) + virtual void exportData(CbcSolver * /*model*/) {} + + /// Get useful stuff + virtual void fillInformation(CbcSolver * /*model*/, + CbcSolverUsefulData & /*info*/) {} + //@} + + ///@name usage methods + //@{ + /// CoinModel if valid + inline CoinModel *coinModel() const { + return coinModel_; + } + /// Other info - needs expanding + virtual void * stuff() { + return NULL; + } + /// Name + inline std::string name() const { + return userName_; + } + /// Solve (whatever that means) + virtual void solve(CbcSolver * model, const char * options) = 0; + /// Returns true if function knows about option + virtual bool canDo(const char * options) = 0; + //@} + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcUser(); + + /// Copy constructor + CbcUser(const CbcUser & rhs); + + /// Assignment operator + CbcUser & operator=(const CbcUser& rhs); + + /// Clone + virtual CbcUser * clone() const = 0; + + /// Destructor + virtual ~CbcUser (); + //@} + +protected: + ///@name Private member data + //@{ + + /// CoinModel + CoinModel * coinModel_; + + /// Name of user function + std::string userName_; + +//@} +}; +//############################################################################# + +/*! \brief Support the use of a call back class to decide whether to stop + + Definitely under construction. +*/ + +class CbcStopNow { + +public: + ///@name Decision methods + //@{ + /*! \brief Import + + Values for whereFrom: + - 1 after initial solve by dualsimplex etc + - 2 after preprocessing + - 3 just before branchAndBound (so user can override) + - 4 just after branchAndBound (before postprocessing) + - 5 after postprocessing + - 6 after a user called heuristic phase + + \return 0 if good + nonzero return code to stop + */ + virtual int callBack(CbcModel * /*currentSolver*/, int /*whereFrom*/) { + return 0; + } + //@} + + ///@name Constructors and destructors etc + //@{ + /// Default Constructor + CbcStopNow(); + + /** Copy constructor . + */ + CbcStopNow(const CbcStopNow & rhs); + + /// Assignment operator + CbcStopNow & operator=(const CbcStopNow& rhs); + + /// Clone + virtual CbcStopNow * clone() const; + + /// Destructor + virtual ~CbcStopNow (); + //@} + +private: + ///@name Private member data + //@{ +//@} +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcStrategy.hpp b/thirdparty/linux/include/coin/coin/CbcStrategy.hpp new file mode 100644 index 0000000..a9c8d24 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcStrategy.hpp @@ -0,0 +1,258 @@ +/* $Id: CbcStrategy.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcStrategy_H +#define CbcStrategy_H + +#include "CbcModel.hpp" +class CglPreProcess; +class CbcNodeInfo; +class CbcNode; +class CoinWarmStartDiff; + +//############################################################################# +/** Strategy base class */ + +class CbcStrategy { +public: + // Default Constructor + CbcStrategy (); + + virtual ~CbcStrategy(); + + /// Clone + virtual CbcStrategy * clone() const = 0; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model) = 0; + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model) = 0; + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) = 0; + /// Other stuff e.g. strong branching and preprocessing + virtual void setupOther(CbcModel & model) = 0; + /// Set model depth (i.e. how nested) + inline void setNested(int depth) { + depth_ = depth; + } + /// Get model depth (i.e. how nested) + inline int getNested() const { + return depth_; + } + /// Say preProcessing done + inline void setPreProcessState(int state) { + preProcessState_ = state; + } + /// See what sort of preprocessing was done + inline int preProcessState() const { + return preProcessState_; + } + /// Pre-processing object + inline CglPreProcess * process() const { + return process_; + } + /// Delete pre-processing object to save memory + void deletePreProcess(); + /// Return a new Full node information pointer (descendant of CbcFullNodeInfo) + virtual CbcNodeInfo * fullNodeInfo(CbcModel * model, int numberRowsAtContinuous) const; + /// Return a new Partial node information pointer (descendant of CbcPartialNodeInfo) + virtual CbcNodeInfo * partialNodeInfo(CbcModel * model, CbcNodeInfo * parent, CbcNode * owner, + int numberChangedBounds, const int * variables, + const double * boundChanges, + const CoinWarmStartDiff *basisDiff) const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + /** After a CbcModel::resolve this can return a status + -1 no effect + 0 treat as optimal + 1 as 0 but do not do any more resolves (i.e. no more cuts) + 2 treat as infeasible + */ + virtual int status(CbcModel * model, CbcNodeInfo * parent, int whereFrom); +private: + + /// Illegal Assignment operator + CbcStrategy & operator=(const CbcStrategy& rhs); +protected: + // Data + /// Model depth + int depth_; + /** PreProcessing state - + -1 infeasible + 0 off + 1 was done (so need post-processing) + */ + int preProcessState_; + /// If preprocessing then this is object + CglPreProcess * process_; +}; + +/** Null class + */ + +class CbcStrategyNull : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyNull () {} + + // Copy constructor + CbcStrategyNull ( const CbcStrategyNull & rhs) : CbcStrategy(rhs) {} + + // Destructor + ~CbcStrategyNull () {} + + /// Clone + virtual CbcStrategy * clone() const { + return new CbcStrategyNull(*this); + } + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & ) {} + /// Setup heuristics + virtual void setupHeuristics(CbcModel & ) {} + /// Do printing stuff + virtual void setupPrinting(CbcModel & , int ) {} + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & ) {} + +protected: + // Data +private: + /// Illegal Assignment operator + CbcStrategyNull & operator=(const CbcStrategyNull& rhs); +}; + +/** Default class + */ + +class CbcStrategyDefault : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyDefault (int cutsOnlyAtRoot = 1, + int numberStrong = 5, + int numberBeforeTrust = 0, + int printLevel = 0); + + // Copy constructor + CbcStrategyDefault ( const CbcStrategyDefault &); + + // Destructor + ~CbcStrategyDefault (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) ; + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & model); + /// Set up preProcessing - see below + inline void setupPreProcessing(int desired = 1, int passes = 10) { + desiredPreProcess_ = desired; + preProcessPasses_ = passes; + } + /// See what sort of preprocessing wanted + inline int desiredPreProcess() const { + return desiredPreProcess_; + } + /// See how many passes wanted + inline int preProcessPasses() const { + return preProcessPasses_; + } + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + +protected: + // Data + + // Whether to do cuts only at root (-1 -> switch off totally) + int cutsOnlyAtRoot_; + + // How much strong branching to do + int numberStrong_; + + // Number branches needed to trust with dynamic pseudo costs + int numberBeforeTrust_; + + // Print level 0 little, 1 medium + int printLevel_; + + /** Desired pre-processing + 0 - none + 1 - ordinary + 2 - find sos + 3 - find cliques + 4 - more aggressive sos + 5 - add integer slacks + */ + int desiredPreProcess_; + /// Number of pre-processing passes + int preProcessPasses_; + +private: + /// Illegal Assignment operator + CbcStrategyDefault & operator=(const CbcStrategyDefault& rhs); +}; + + +/** Default class for sub trees + */ + +class CbcStrategyDefaultSubTree : public CbcStrategy { +public: + + // Default Constructor + CbcStrategyDefaultSubTree (CbcModel * parent = NULL, int cutsOnlyAtRoot = 1, + int numberStrong = 5, + int numberBeforeTrust = 0, + int printLevel = 0); + + // Copy constructor + CbcStrategyDefaultSubTree ( const CbcStrategyDefaultSubTree &); + + // Destructor + ~CbcStrategyDefaultSubTree (); + + /// Clone + virtual CbcStrategy * clone() const; + + /// Setup cut generators + virtual void setupCutGenerators(CbcModel & model); + /// Setup heuristics + virtual void setupHeuristics(CbcModel & model); + /// Do printing stuff + virtual void setupPrinting(CbcModel & model, int modelLogLevel) ; + /// Other stuff e.g. strong branching + virtual void setupOther(CbcModel & model); +protected: + // Data + // Parent model + CbcModel * parentModel_; + // Whether to do cuts only at root (-1 -> switch off totally) + int cutsOnlyAtRoot_; + + // How much strong branching to do + int numberStrong_; + + // Number branches needed to trust with dynamic pseudo costs + int numberBeforeTrust_; + + // Print level 0 little, 1 medium + int printLevel_; + +private: + /// Illegal Assignment operator + CbcStrategyDefaultSubTree & operator=(const CbcStrategyDefaultSubTree& rhs); +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcSubProblem.hpp b/thirdparty/linux/include/coin/coin/CbcSubProblem.hpp new file mode 100644 index 0000000..4a7a580 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcSubProblem.hpp @@ -0,0 +1,83 @@ +// $Id: CbcSubProblem.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// Edwin 11/10/2009-- carved out of CbcBranchActual + +#ifndef CbcSubProblem_H +#define CbcSubProblem_H + +#ifdef COIN_HAS_CLP +#include "ClpSimplex.hpp" +#include "ClpNode.hpp" + +/** Defines a general subproblem + Basis will be made more compact later +*/ +class CoinWarmStartDiff; +class CbcSubProblem { + +public: + + /// Default constructor + CbcSubProblem (); + + /// Constructor from model + CbcSubProblem (const OsiSolverInterface * solver, + const double * lowerBefore, + const double * upperBefore, + const unsigned char * status, + int depth); + + /// Copy constructor + CbcSubProblem ( const CbcSubProblem &); + + /// Assignment operator + CbcSubProblem & operator= (const CbcSubProblem& rhs); + + /// Destructor + virtual ~CbcSubProblem (); + + /// Take over + void takeOver ( CbcSubProblem &, bool cleanup); + /// Apply subproblem (1=bounds, 2=basis, 3=both) + void apply(OsiSolverInterface * model, int what = 3) const; + +public: + /// Value of objective + double objectiveValue_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Branch value + double branchValue_; + /// Dj on branching variable at end + double djValue_; + /** Which variable (top bit if upper bound changing) + next bit if changing on down branch only */ + int * variables_; + /// New bound + double * newBounds_; + /// Status + mutable CoinWarmStartBasis * status_; + /// Depth + int depth_; + /// Number of Extra bound changes + int numberChangedBounds_; + /// Number of infeasibilities + int numberInfeasibilities_; + /** Status 1 bit going up on first, 2 bit set first branch infeasible on second, 4 bit redundant branch, + bits after 256 give reason for stopping (just last node) + 0 - solution + 1 - infeasible + 2 - maximum depth + >2 - error or max time or something + */ + int problemStatus_; + /// Variable branched on + int branchVariable_; +}; + +#endif //COIN_HAS_CLP +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcTree.hpp b/thirdparty/linux/include/coin/coin/CbcTree.hpp new file mode 100644 index 0000000..92ea2bf --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcTree.hpp @@ -0,0 +1,490 @@ +/* $Id: CbcTree.hpp 1943 2013-07-21 09:05:45Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcTree_H +#define CbcTree_H + +#include <vector> +#include <algorithm> +#include <cmath> + +#include "CoinHelperFunctions.hpp" +#include "CbcCompare.hpp" + +/*! \brief Using MS heap implementation + + It's unclear if this is needed any longer, or even if it should be allowed. + Cbc occasionally tries to do things to the tree (typically tweaking the + comparison predicate) that can cause a violation of the heap property (parent better + than either child). In a debug build, Microsoft's heap implementation does checks that + detect this and fail. This symbol switched to an alternate implementation of CbcTree, + and there are clearly differences, but no explanation as to why or what for. + + As of 100921, the code is cleaned up to make it through `cbc -unitTest' without + triggering `Invalid heap' in an MSVS debug build. The method validateHeap() can + be used for debugging if this turns up again. +*/ +//#define CBC_DUBIOUS_HEAP +#if defined(_MSC_VER) || defined(__MNO_CYGWIN) +//#define CBC_DUBIOUS_HEAP +#endif +#if 1 //ndef CBC_DUBIOUS_HEAP + +/*! \brief Controls search tree debugging + + In order to have validateHeap() available, set CBC_DEBUG_HEAP + to 1 or higher. + + - 1 calls validateHeap() after each change to the heap + - 2 will print a line for major operations (clean, set comparison, etc.) + - 3 will print information about each push and pop + +#define CBC_DEBUG_HEAP 1 +*/ + + +/*! \class CbcTree + \brief Implementation of the live set as a heap. + + This class is used to hold the set of live nodes in the search tree. +*/ +class CbcTree { + +public: + /*! \name Constructors and related */ +//@{ + /// Default Constructor + CbcTree (); + + /// Copy constructor + CbcTree (const CbcTree &rhs); + + /// = operator + CbcTree & operator=(const CbcTree &rhs); + + /// Destructor + virtual ~CbcTree(); + + /// Clone + virtual CbcTree * clone() const; + + /// Create C++ lines to get to current state + virtual void generateCpp(FILE *) {} +//@} + + /*! \name Heap access and maintenance methods */ +//@{ + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode *x); + + /// Remove the top node from the heap + virtual void pop() ; + + /*! \brief Gets best node and takes off heap + + Before returning the node from the top of the heap, the node + is offered an opportunity to reevaluate itself. Callers should + be prepared to check that the node returned is suitable for use. + */ + virtual CbcNode * bestNode(double cutoff); + + /*! \brief Rebuild the heap */ + virtual void rebuild() ; +//@} + + /*! \name Direct node access methods */ +//@{ + /// Test for an empty tree + virtual bool empty() ; + + /// Return size + virtual int size() const { return static_cast<int>(nodes_.size()); } + + /// Return a node pointer + inline CbcNode * operator [] (int i) const { return nodes_[i]; } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { return nodes_[i]; } + void realpop(); + /** After changing data in the top node, fix the heap */ + void fixTop(); + void realpush(CbcNode * node); +//@} + + /*! \name Search tree maintenance */ +//@{ + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worse than the + specified cutoff value. It also sets bestPossibleObjective to + the best objective over remaining nodes. + */ + virtual void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} + + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); + + /// Reset maximum node number + inline void resetNodeNumbers() { maximumNodeNumber_ = 0; } + + /// Get maximum node number + inline int maximumNodeNumber() const { return maximumNodeNumber_; } + + /// Set number of branches + inline void setNumberBranching(int value) { numberBranching_ = value; } + + /// Get number of branches + inline int getNumberBranching() const { return numberBranching_; } + + /// Set maximum branches + inline void setMaximumBranching(int value) { maximumBranching_ = value; } + + /// Get maximum branches + inline int getMaximumBranching() const { return maximumBranching_; } + + /// Get branched variables + inline unsigned int * branched() const { return branched_; } + + /// Get bounds + inline int * newBounds() const { return newBound_; } + + /// Last objective in branch-and-cut search tree + inline double lastObjective() const { + return lastObjective_; + } + /// Last depth in branch-and-cut search tree + inline int lastDepth() const { + return lastDepth_; + } + /// Last number of objects unsatisfied + inline int lastUnsatisfied() const { + return lastUnsatisfied_; + } + /// Adds branching information to complete state + void addBranchingInformation(const CbcModel * model, const CbcNodeInfo * nodeInfo, + const double * currentLower, + const double * currentUpper); + /// Increase space for data + void increaseSpace(); +//@} + +# if CBC_DEBUG_HEAP > 0 + /*! \name Debugging methods */ + //@{ + /*! \brief Check that the heap property is satisfied. */ + void validateHeap() ; + //@} +# endif + +protected: + /// Storage vector for the heap + std::vector <CbcNode *> nodes_; + /// Sort predicate for heap ordering. + CbcCompare comparison_; + /// Maximum "node" number so far to split ties + int maximumNodeNumber_; + /// Size of variable list + int numberBranching_; + /// Maximum size of variable list + int maximumBranching_; + /// Objective of last node pushed on tree + double lastObjective_; + /// Depth of last node pushed on tree + int lastDepth_; + /// Number unsatisfied of last node pushed on tree + int lastUnsatisfied_; + /** Integer variables branched or bounded + top bit set if new upper bound + next bit set if a branch + */ + unsigned int * branched_; + /// New bound + int * newBound_; +}; + +#ifdef JJF_ZERO // not used +/*! \brief Implementation of live set as a managed array. + + This class is used to hold the set of live nodes in the search tree. +*/ +class CbcTreeArray : public CbcTree { + +public: + + // Default Constructor + CbcTreeArray (); + + // Copy constructor + CbcTreeArray ( const CbcTreeArray & rhs); + // = operator + CbcTreeArray & operator=(const CbcTreeArray & rhs); + + virtual ~CbcTreeArray(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + virtual bool empty() ; + +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + /// Get best possible objective function in the tree + virtual double getBestPossibleObjective(); +//@} +protected: + /// Returns + /// Last node + CbcNode * lastNode_; + /// Last node popped + CbcNode * lastNodePopped_; + /// Not used yet + int switches_; + +}; + +/// New style +#include "CoinSearchTree.hpp" +/*! \class tree + \brief Implementation of live set as a heap. + + This class is used to hold the set of live nodes in the search tree. +*/ + +class CbcNewTree : public CbcTree, public CoinSearchTreeManager { + +public: + + // Default Constructor + CbcNewTree (); + + // Copy constructor + CbcNewTree ( const CbcNewTree & rhs); + // = operator + CbcNewTree & operator=(const CbcNewTree & rhs); + + virtual ~CbcNewTree(); + + /// Clone + virtual CbcNewTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * ) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// Return size + inline int size() const { + return nodes_.size(); + } + + /// [] operator + inline CbcNode * operator [] (int i) const { + return nodes_[i]; + } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { + return nodes_[i]; + } + +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} +//@} +protected: + + +}; +#endif +#else +/* CBC_DUBIOUS_HEAP is defined + + See note at top of file. This code is highly suspect. + -- lh, 100921 -- +*/ +class CbcTree { + +public: + + // Default Constructor + CbcTree (); + + // Copy constructor + CbcTree ( const CbcTree & rhs); + // = operator + CbcTree & operator=(const CbcTree & rhs); + + virtual ~CbcTree(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) {} + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Set comparison function and resort heap + void setComparison(CbcCompareBase &compare); + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + /// Gets best node and takes off heap + virtual CbcNode * bestNode(double cutoff); + +//@} + /*! \name vector methods */ +//@{ + + /// Test if empty *** note may be overridden + //virtual bool empty() ; + + /// Return size + inline int size() const { + return nodes_.size(); + } + + /// [] operator + inline CbcNode * operator [] (int i) const { + return nodes_[i]; + } + + /// Return a node pointer + inline CbcNode * nodePointer (int i) const { + return nodes_[i]; + } + + virtual bool empty(); + //inline int size() const { return size_; } + void realpop(); + /** After changing data in the top node, fix the heap */ + void fixTop(); + void realpush(CbcNode * node); +//@} + + /*! \name Search tree maintenance */ +//@{ + + /*! \brief Prune the tree using an objective function cutoff + + This routine removes all nodes with objective worst than the + specified cutoff value. + It also sets bestPossibleObjective to best + of all on tree before deleting. + */ + + void cleanTree(CbcModel * model, double cutoff, double & bestPossibleObjective); + + /// Get best on list using alternate method + CbcNode * bestAlternate(); + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() {} + /// Reset maximum node number + inline void resetNodeNumbers() { + maximumNodeNumber_ = 0; + } + + /// Get maximum node number + inline int maximumNodeNumber() const { return maximumNodeNumber_; } +//@} +protected: + std::vector <CbcNode *> nodes_; + CbcCompare comparison_; ///> Sort function for heap ordering. + /// Maximum "node" number so far to split ties + int maximumNodeNumber_; + + +}; +#endif +#endif + diff --git a/thirdparty/linux/include/coin/coin/CbcTreeLocal.hpp b/thirdparty/linux/include/coin/coin/CbcTreeLocal.hpp new file mode 100644 index 0000000..efff91c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CbcTreeLocal.hpp @@ -0,0 +1,372 @@ +/* $Id: CbcTreeLocal.hpp 1573 2011-01-05 01:12:36Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CbcTreeLocal_H +#define CbcTreeLocal_H + +//############################################################################# +/* This implements (approximately) local branching as in the 2002 paper by + Matteo Fischetti and Andrea Lodi. + + The very simple version of the algorithm for problems with + 0-1 variables and continuous is as follows: + + Obtain a feasible solution (one can be passed in). + + Add a cut which limits search to a k neighborhood of this solution. + (At most k 0-1 variables may change value) + Do branch and bound on this problem. + + If finished search and proven optimal then we can reverse cut so + any solutions must be at least k+1 away from solution and we can + add a new cut limiting search to a k neighborhood of new solution + repeat. + + If finished search and no new solution then the simplest version + would reverse last cut and complete search. The version implemented + here can use time and node limits and can widen search (increase effective k) + .... and more + +*/ + +#include "CbcTree.hpp" +#include "CbcNode.hpp" +#include "OsiRowCut.hpp" +class CbcModel; + + +class CbcTreeLocal : public CbcTree { + +public: + + // Default Constructor + CbcTreeLocal (); + + /* Constructor with solution. + If solution NULL no solution, otherwise must be integer + range is initial upper bound (k) on difference from given solution. + typeCuts - + 0 means just 0-1 cuts and will need to refine 0-1 solution + 1 uses weaker cuts on all integer variables + maxDiversification is maximum number of range widenings to try + timeLimit is seconds in subTree + nodeLimit is nodes in subTree + refine is whether to see if we can prove current solution is optimal + when we fix all 0-1 (in case typeCuts==0 and there are general integer variables) + if false then no refinement but reverse cuts weaker + */ + CbcTreeLocal (CbcModel * model, const double * solution , int range = 10, + int typeCuts = 0, int maxDiversification = 0, + int timeLimit = 1000000, int nodeLimit = 1000000, bool refine = true); + // Copy constructor + CbcTreeLocal ( const CbcTreeLocal & rhs); + + // = operator + CbcTreeLocal & operator=(const CbcTreeLocal & rhs); + + virtual ~CbcTreeLocal(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + +//@} + /*! \name Other stuff */ +//@{ + + /// Create cut - return -1 if bad, 0 if okay and 1 if cut is everything + int createCut(const double * solution, OsiRowCut & cut); + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() ; + /// Other side of last cut branch (if bias==rhs_ will be weakest possible) + void reverseCut(int state, double bias = 0.0); + /// Delete last cut branch + void deleteCut(OsiRowCut & cut); + /// Pass in solution (so can be used after heuristic) + void passInSolution(const double * solution, double solutionValue); + // range i.e. k + inline int range() const { + return range_; + } + // setrange i.e. k + inline void setRange(int value) { + range_ = value; + } + // Type of cuts - 0=just 0-1, 1=all + inline int typeCuts() const { + return typeCuts_; + } + // Type of cuts - 0=just 0-1, 1=all + inline void setTypeCuts(int value) { + typeCuts_ = value; + } + // maximum number of diversifications + inline int maxDiversification() const { + return maxDiversification_; + } + // maximum number of diversifications + inline void setMaxDiversification(int value) { + maxDiversification_ = value; + } + // time limit per subtree + inline int timeLimit() const { + return timeLimit_; + } + // time limit per subtree + inline void setTimeLimit(int value) { + timeLimit_ = value; + } + // node limit for subtree + inline int nodeLimit() const { + return nodeLimit_; + } + // node limit for subtree + inline void setNodeLimit(int value) { + nodeLimit_ = value; + } + // Whether to do refinement step + inline bool refine() const { + return refine_; + } + // Whether to do refinement step + inline void setRefine(bool yesNo) { + refine_ = yesNo; + } + +//@} +private: + // Node for local cuts + CbcNode * localNode_; + // best solution + double * bestSolution_; + // saved solution + double * savedSolution_; + // solution number at start of pass + int saveNumberSolutions_; + /* Cut. If zero size then no solution yet. Otherwise is left hand branch */ + OsiRowCut cut_; + // This cut fixes all 0-1 variables + OsiRowCut fixedCut_; + // Model + CbcModel * model_; + // Original lower bounds + double * originalLower_; + // Original upper bounds + double * originalUpper_; + // range i.e. k + int range_; + // Type of cuts - 0=just 0-1, 1=all + int typeCuts_; + // maximum number of diversifications + int maxDiversification_; + // current diversification + int diversification_; + // Whether next will be strong diversification + bool nextStrong_; + // Current rhs + double rhs_; + // Save allowable gap + double savedGap_; + // Best solution + double bestCutoff_; + // time limit per subtree + int timeLimit_; + // time when subtree started + int startTime_; + // node limit for subtree + int nodeLimit_; + // node count when subtree started + int startNode_; + // -1 not started, 0 == stop on first solution, 1 don't stop on first, 2 refinement step + int searchType_; + // Whether to do refinement step + bool refine_; + +}; + +class CbcTreeVariable : public CbcTree { + +public: + + // Default Constructor + CbcTreeVariable (); + + /* Constructor with solution. + If solution NULL no solution, otherwise must be integer + range is initial upper bound (k) on difference from given solution. + typeCuts - + 0 means just 0-1 cuts and will need to refine 0-1 solution + 1 uses weaker cuts on all integer variables + maxDiversification is maximum number of range widenings to try + timeLimit is seconds in subTree + nodeLimit is nodes in subTree + refine is whether to see if we can prove current solution is optimal + when we fix all 0-1 (in case typeCuts==0 and there are general integer variables) + if false then no refinement but reverse cuts weaker + */ + CbcTreeVariable (CbcModel * model, const double * solution , int range = 10, + int typeCuts = 0, int maxDiversification = 0, + int timeLimit = 1000000, int nodeLimit = 1000000, bool refine = true); + // Copy constructor + CbcTreeVariable ( const CbcTreeVariable & rhs); + + // = operator + CbcTreeVariable & operator=(const CbcTreeVariable & rhs); + + virtual ~CbcTreeVariable(); + + /// Clone + virtual CbcTree * clone() const; + /// Create C++ lines to get to current state + virtual void generateCpp( FILE * fp) ; + + /*! \name Heap access and maintenance methods */ +//@{ + + /// Return the top node of the heap + virtual CbcNode * top() const; + + /// Add a node to the heap + virtual void push(CbcNode * x); + + /// Remove the top node from the heap + virtual void pop() ; + +//@} + /*! \name Other stuff */ +//@{ + + /// Create cut - return -1 if bad, 0 if okay and 1 if cut is everything + int createCut(const double * solution, OsiRowCut & cut); + + /// Test if empty *** note may be overridden + virtual bool empty() ; + + /// We may have got an intelligent tree so give it one more chance + virtual void endSearch() ; + /// Other side of last cut branch (if bias==rhs_ will be weakest possible) + void reverseCut(int state, double bias = 0.0); + /// Delete last cut branch + void deleteCut(OsiRowCut & cut); + /// Pass in solution (so can be used after heuristic) + void passInSolution(const double * solution, double solutionValue); + // range i.e. k + inline int range() const { + return range_; + } + // setrange i.e. k + inline void setRange(int value) { + range_ = value; + } + // Type of cuts - 0=just 0-1, 1=all + inline int typeCuts() const { + return typeCuts_; + } + // Type of cuts - 0=just 0-1, 1=all + inline void setTypeCuts(int value) { + typeCuts_ = value; + } + // maximum number of diversifications + inline int maxDiversification() const { + return maxDiversification_; + } + // maximum number of diversifications + inline void setMaxDiversification(int value) { + maxDiversification_ = value; + } + // time limit per subtree + inline int timeLimit() const { + return timeLimit_; + } + // time limit per subtree + inline void setTimeLimit(int value) { + timeLimit_ = value; + } + // node limit for subtree + inline int nodeLimit() const { + return nodeLimit_; + } + // node limit for subtree + inline void setNodeLimit(int value) { + nodeLimit_ = value; + } + // Whether to do refinement step + inline bool refine() const { + return refine_; + } + // Whether to do refinement step + inline void setRefine(bool yesNo) { + refine_ = yesNo; + } + +//@} +private: + // Node for local cuts + CbcNode * localNode_; + // best solution + double * bestSolution_; + // saved solution + double * savedSolution_; + // solution number at start of pass + int saveNumberSolutions_; + /* Cut. If zero size then no solution yet. Otherwise is left hand branch */ + OsiRowCut cut_; + // This cut fixes all 0-1 variables + OsiRowCut fixedCut_; + // Model + CbcModel * model_; + // Original lower bounds + double * originalLower_; + // Original upper bounds + double * originalUpper_; + // range i.e. k + int range_; + // Type of cuts - 0=just 0-1, 1=all + int typeCuts_; + // maximum number of diversifications + int maxDiversification_; + // current diversification + int diversification_; + // Whether next will be strong diversification + bool nextStrong_; + // Current rhs + double rhs_; + // Save allowable gap + double savedGap_; + // Best solution + double bestCutoff_; + // time limit per subtree + int timeLimit_; + // time when subtree started + int startTime_; + // node limit for subtree + int nodeLimit_; + // node count when subtree started + int startNode_; + // -1 not started, 0 == stop on first solution, 1 don't stop on first, 2 refinement step + int searchType_; + // Whether to do refinement step + bool refine_; + +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/Cbc_C_Interface.h b/thirdparty/linux/include/coin/coin/Cbc_C_Interface.h new file mode 100644 index 0000000..fc15774 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/Cbc_C_Interface.h @@ -0,0 +1,381 @@ +/* $Id: Cbc_C_Interface.h 2091 2014-10-03 00:46:49Z mlubin $ */ +/* + Copyright (C) 2004 International Business Machines Corporation and others. + All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef CbcModelC_H +#define CbcModelC_H + +/* include all defines and ugly stuff */ +#include "Coin_C_defines.h" +#include <stddef.h> + +/* + * Original verison contributed by Bob Entriken, + * significantly updated by Miles Lubin. +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + /**@name Constructors and destructor + This is a "C" interface to Cbc. + The user does not need to know structure of Cbc_Model. + */ + /*@{*/ + + /** Default Cbc_Model constructor */ + COINLIBAPI Cbc_Model * COINLINKAGE + Cbc_newModel(void) + ; + /** Cbc_Model Destructor */ + COINLIBAPI void COINLINKAGE + Cbc_deleteModel(Cbc_Model * model) + ; + /** Current version of Cbc */ + COINLIBAPI const char* COINLINKAGE Cbc_getVersion(void) + ; + /*@}*/ + + /**@name Getting and setting model data + Note that problem access and modification methods, + such as getColLower and setColLower, + are *not valid* after calling Cbc_solve(). + Therefore it is not recommended to reuse a Cbc_Model + object for multiple solves. A workaround is to call Cbc_clone() + before solving. + * */ + /*@{*/ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + The constraint matrix is + given in standard compressed sparse column (without gaps). + <ul> + <li> <code>start[i]</code> stores the starting index of the ith column + <li> <code>index[k]</code> stores the row index of the kth nonzero element + <li> <code>value[k]</code> stores the coefficient of the kth nonzero element + </ul> + */ + COINLIBAPI void COINLINKAGE + Cbc_loadProblem (Cbc_Model * model, const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) + ; + /** Read an mps file from the given filename */ + COINLIBAPI int COINLINKAGE + Cbc_readMps(Cbc_Model * model, const char *filename) + ; + /** Write an mps file from the given filename */ + COINLIBAPI void COINLINKAGE + Cbc_writeMps(Cbc_Model * model, const char *filename) + ; + /** Provide an initial feasible solution to accelerate branch-and-bound + Note that feasibility of the solution is *not* verified. + */ + COINLIBAPI void COINLINKAGE + Cbc_setInitialSolution(Cbc_Model *model, const double * sol) + ; + /** Fills in array with problem name */ + COINLIBAPI void COINLINKAGE + Cbc_problemName(Cbc_Model * model, int maxNumberCharacters, char * array) + ; + /** Sets problem name. + + \p array must be a null-terminated string. + */ + COINLIBAPI int COINLINKAGE + Cbc_setProblemName(Cbc_Model * model, const char * array) + ; + + /** Number of nonzero elements in constraint matrix */ + COINLIBAPI int COINLINKAGE + Cbc_getNumElements(Cbc_Model * model) + ; + /** "Column start" vector of constraint matrix. Same format as Cbc_loadProblem() */ + COINLIBAPI const CoinBigIndex * COINLINKAGE + Cbc_getVectorStarts(Cbc_Model * model) + ; + /** "Row index" vector of constraint matrix */ + COINLIBAPI const int * COINLINKAGE + Cbc_getIndices(Cbc_Model * model) + ; + /** Coefficient vector of constraint matrix */ + COINLIBAPI const double * COINLINKAGE + Cbc_getElements(Cbc_Model * model) + ; + + /** Maximum lenght of a row or column name */ + COINLIBAPI size_t COINLINKAGE + Cbc_maxNameLength(Cbc_Model * model) + ; + /** Fill in first maxLength bytes of name array with a row name */ + COINLIBAPI void COINLINKAGE + Cbc_getRowName(Cbc_Model * model, int iRow, char * name, size_t maxLength) + ; + /** Fill in first maxLength bytes of name array with a column name */ + COINLIBAPI void COINLINKAGE + Cbc_getColName(Cbc_Model * model, int iColumn, char * name, size_t maxLength) + ; + /** Set the name of a column */ + COINLIBAPI void COINLINKAGE + Cbc_setColName(Cbc_Model * model, int iColumn, const char * name) + ; + /** Set the name of a row */ + COINLIBAPI void COINLINKAGE + Cbc_setRowName(Cbc_Model * model, int iRow, const char * name) + ; + /** Number of constraints in the model */ + COINLIBAPI int COINLINKAGE + Cbc_getNumRows(Cbc_Model * model) + ; + /** Number of variables in the model */ + COINLIBAPI int COINLINKAGE + Cbc_getNumCols(Cbc_Model * model) + ; + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore) */ + COINLIBAPI void COINLINKAGE + Cbc_setObjSense(Cbc_Model * model, double sense) + ; + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore) */ + COINLIBAPI double COINLINKAGE + Cbc_getObjSense(Cbc_Model * model) + ; + /** Constraint lower bounds */ + COINLIBAPI const double* COINLINKAGE + Cbc_getRowLower(Cbc_Model * model) + ; + /** Set the lower bound of a single constraint */ + COINLIBAPI void COINLINKAGE + Cbc_setRowLower(Cbc_Model * model, int index, double value) + ; + /** Constraint upper bounds */ + COINLIBAPI const double* COINLINKAGE + Cbc_getRowUpper(Cbc_Model * model) + ; + /** Set the upper bound of a single constraint */ + COINLIBAPI void COINLINKAGE + Cbc_setRowUpper(Cbc_Model * model, int index, double value) + ; + /** Objective vector */ + COINLIBAPI const double * COINLINKAGE + Cbc_getObjCoefficients(Cbc_Model * model) + ; + /** Set the objective coefficient of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setObjCoeff(Cbc_Model * model, int index, double value) + ; + /** Variable lower bounds */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColLower(Cbc_Model * model) + ; + /** Set the lower bound of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setColLower(Cbc_Model * model, int index, double value) + ; + /** Variable upper bounds */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColUpper(Cbc_Model * model) + ; + /** Set the upper bound of a single variable */ + COINLIBAPI void COINLINKAGE + Cbc_setColUpper(Cbc_Model * model, int index, double value) + ; + /** Determine whether the ith variable is integer restricted */ + COINLIBAPI int COINLINKAGE + Cbc_isInteger(Cbc_Model * model, int i) + ; + /** Set this variable to be continuous */ + COINLIBAPI void COINLINKAGE + Cbc_setContinuous(Cbc_Model * model, int iColumn) + ; + /** Set this variable to be integer */ + COINLIBAPI void COINLINKAGE + Cbc_setInteger(Cbc_Model * model, int iColumn) + ; + /** Add SOS constraints to the model using row-order matrix */ + COINLIBAPI void COINLINKAGE + Cbc_addSOS(Cbc_Model * model, int numRows, const int * rowStarts, + const int * colIndices, const double * weights, const int type) + ; + /** Print the model */ + COINLIBAPI void COINLINKAGE + Cbc_printModel(Cbc_Model * model, const char * argPrefix) + ; + /** Return a copy of this model */ + COINLIBAPI Cbc_Model * COINLINKAGE + Cbc_clone(Cbc_Model * model) + ; + /*@}*/ + /**@name Solver parameters */ + /*@{*/ + /** Set parameter "name" to value "value". Note that this + * translates directly to using "-name value" as a + * command-line argument to Cbc.*/ + COINLIBAPI void COINLINKAGE + Cbc_setParameter(Cbc_Model * model, const char * name, const char * value) + ; + + + /*@}*/ + /**@name Message handling. Call backs are handled by ONE function */ + /*@{*/ + /** Pass in Callback function. + Message numbers up to 1000000 are Clp, Coin ones have 1000000 added */ + COINLIBAPI void COINLINKAGE + Cbc_registerCallBack(Cbc_Model * model, + cbc_callback userCallBack) + ; + /** Unset Callback function */ + COINLIBAPI void COINLINKAGE + Cbc_clearCallBack(Cbc_Model * model) + ; + + /*@}*/ + + + /**@name Solving the model */ + /*@{*/ + /* Solve the model with Cbc (using CbcMain1). + */ + COINLIBAPI int COINLINKAGE + Cbc_solve(Cbc_Model * model) + ; + /*@}*/ + + + /**@name Accessing the solution and solution status */ + /*@{*/ + + /** Sum of primal infeasibilities */ + COINLIBAPI double COINLINKAGE + Cbc_sumPrimalInfeasibilities(Cbc_Model * model) + ; + /** Number of primal infeasibilities */ + COINLIBAPI int COINLINKAGE + Cbc_numberPrimalInfeasibilities(Cbc_Model * model) + ; + + /** Just check solution (for external use) - sets sum of + infeasibilities etc */ + COINLIBAPI void COINLINKAGE + Cbc_checkSolution(Cbc_Model * model) + ; + + /** Number of iterations */ + COINLIBAPI int COINLINKAGE + Cbc_getIterationCount(Cbc_Model * model) + ; + /** Are there a numerical difficulties? */ + COINLIBAPI int COINLINKAGE + Cbc_isAbandoned(Cbc_Model * model) + ; + /** Is optimality proven? */ + COINLIBAPI int COINLINKAGE + Cbc_isProvenOptimal(Cbc_Model * model) + ; + /** Is infeasiblity proven (or none better than cutoff)? */ + COINLIBAPI int COINLINKAGE + Cbc_isProvenInfeasible(Cbc_Model * model) + ; + /** Was continuous solution unbounded? */ + COINLIBAPI int COINLINKAGE + Cbc_isContinuousUnbounded(Cbc_Model * model) + ; + /** Node limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isNodeLimitReached(Cbc_Model * model) + ; + /** Time limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isSecondsLimitReached(Cbc_Model * model) + ; + /** Solution limit reached? */ + COINLIBAPI int COINLINKAGE + Cbc_isSolutionLimitReached(Cbc_Model * model) + ; + /** Are there numerical difficulties (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveAbandoned(Cbc_Model * model) + ; + /** Is optimality proven (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveProvenOptimal(Cbc_Model * model) + ; + /** Is primal infeasiblity proven (for initialSolve) ? */ + COINLIBAPI int COINLINKAGE + Cbc_isInitialSolveProvenPrimalInfeasible(Cbc_Model * model) + ; + /** "row" solution + * This is the vector A*x, where A is the constraint matrix + * and x is the current solution. */ + COINLIBAPI const double * COINLINKAGE + Cbc_getRowActivity(Cbc_Model * model) + ; + /** Best feasible solution vector */ + COINLIBAPI const double * COINLINKAGE + Cbc_getColSolution(Cbc_Model * model) + ; + /** Objective value of best feasible solution */ + COINLIBAPI double COINLINKAGE + Cbc_getObjValue(Cbc_Model * model) + ; + /** Best known bound on the optimal objective value */ + COINLIBAPI double COINLINKAGE + Cbc_getBestPossibleObjValue(Cbc_Model * model) + ; + /** Number of nodes explored in B&B tree */ + COINLIBAPI int COINLINKAGE + Cbc_getNodeCount(Cbc_Model * model) + ; + /** Print the solution */ + COINLIBAPI void COINLINKAGE + Cbc_printSolution(Cbc_Model * model) + ; + /** Final status of problem + Some of these can be found out by is...... functions + -1 before branchAndBound + 0 finished - check isProvenOptimal or isProvenInfeasible to see if solution found + (or check value of best solution) + 1 stopped - on maxnodes, maxsols, maxtime + 2 difficulties so run was abandoned + (5 event user programmed event occurred) + */ + COINLIBAPI int COINLINKAGE + Cbc_status(Cbc_Model * model) + ; + /** Secondary status of problem + -1 unset (status_ will also be -1) + 0 search completed with solution + 1 linear relaxation not feasible (or worse than cutoff) + 2 stopped on gap + 3 stopped on nodes + 4 stopped on time + 5 stopped on user event + 6 stopped on solutions + 7 linear relaxation unbounded + 8 stopped on iteration limit + */ + COINLIBAPI int COINLINKAGE + Cbc_secondaryStatus(Cbc_Model * model) + ; + /*@}*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/Cgl012cut.hpp b/thirdparty/linux/include/coin/coin/Cgl012cut.hpp new file mode 100644 index 0000000..2814b0a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/Cgl012cut.hpp @@ -0,0 +1,464 @@ +// $Id: Cgl012cut.hpp 1149 2013-10-21 18:23:53Z tkr $ +// Copyright (C) 2010, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/** @file 012cut.h Include file for C coded 0-1/2 separator */ +#ifndef CGL012CUT +#define CGL012CUT +#include <cstdio> +#include <cstdlib> +#include <cmath> + +#define CGL_NEW_SHORT +#ifndef CGL_NEW_SHORT +typedef /* arc */ + struct arc_st +{ + int len; /* length of the arc */ + struct node_st *head; /* head node */ +} + arc; + +typedef /* node */ + struct node_st +{ + arc *first; /* first outgoing arc */ + int dist; /* tentative shortest path length */ + struct node_st *parent; /* parent pointer */ + struct node_st *next; /* next node in queue */ + struct node_st *prev; /* previous node in queue */ + int status; /* status of node */ + int temp; /* for temporary labels */ + int index; /* index of the node in the graph */ +} node; +#endif +typedef struct +{ + int length; // Length of arc + int to; // To node +} cgl_arc; + +typedef struct +{ + cgl_arc * firstArc; // First outgoing arc + int parentNode; // Parent node in shortest path + int index; // Which node I am + int distanceBack; // Distance back to source +} cgl_node; + +typedef struct +{ + int nnodes; // Number of nodes in graph + int narcs; // Number of arcs in graph + cgl_node * nodes; + cgl_arc * arcs; +} cgl_graph; +/* #define PRINT */ +/* #define PRINT_CUTS */ +#define REDUCTION + +typedef struct { +int mr; /* number of rows in the ILP matrix */ +int mc; /* number of columns in the ILP matrix */ +int mnz; /* number of nonzero's in the ILP matrix */ +int *mtbeg; /* starting position of each row in arrays mtind and mtval */ +int *mtcnt; /* number of entries of each row in arrays mtind and mtval */ +int *mtind; /* column indices of the nonzero entries of the ILP matrix */ +int *mtval; /* values of the nonzero entries of the ILP matrix */ +int *vlb; /* lower bounds on the variables */ +int *vub; /* upper bounds on the variables */ +int *mrhs; /* right hand sides of the constraints */ +char *msense; /* senses of the constraints: 'L', 'G' or 'E' */ +const double *xstar; /* current optimal solution of the LP relaxation */ +} ilp; + +typedef struct { +int mr; /* number of rows in the parity ILP matrix */ +int mc; /* number of columns in the parity ILP matrix */ +int mnz; /* number of 1's in the parity ILP matrix */ +int *mtbeg; /* starting position of each row in arrays mtind and mtval */ +int *mtcnt; /* number of entries of each row in arrays mtind and mtval */ +int *mtind; /* column indices of the 1's of the parity ILP matrix */ +short int *mrhs; /* right hand side parity of the constraints */ +double *xstar; /* current optimal solution of the LP relaxation */ +double *slack; /* slack of the constraints w.r.t. xstar */ +short int *row_to_delete; /* flag for marking rows not to be considered */ +short int *col_to_delete; /* flag for marking columns not to be considered */ +int *gcd; /* greatest common divisor of each row in the input ILP matrix */ +short int *possible_weak; /* possible weakening types of each column */ +short int *type_even_weak; /* type of even weakening of each column + (lower or upper bound weakening) */ +short int *type_odd_weak; /* type of odd weakening of each column + (lower or upper bound weakening) */ +double *loss_even_weak; /* loss for the even weakening of each column */ +double *loss_odd_weak; /* loss for the odd weakening of each column */ +double *min_loss_by_weak; /* minimum loss for the weakening of each column */ +} parity_ilp; + +typedef struct { +int nweak; /* number of variables weakened */ +int *var; /* list of variables weakened */ +short int *type; /* type of weakening (lower or upper bound weakening) */ +} info_weak; + +typedef struct { +int endpoint1, endpoint2; /* endpoints of the edge */ +double weight; /* edge weight */ +short int parity; /* edge parity (even or odd) */ +int constr; /* constraint associated with the edge */ +info_weak *weak; /* weakening information */ +} edge; + +typedef struct { +int nnodes; /* number of nodes */ +int nedges; /* number of edges */ +int *nodes; /* indexes of the ILP columns corresponding to the nodes */ +int *ind; /* indexes of the nodes corresponding to the ILP columns */ +edge **even_adj_list; /* pointers to the even edges */ +edge **odd_adj_list; /* pointers to the odd edges */ +} separation_graph; + +#ifndef CGL_NEW_SHORT +typedef struct { +int nnodes; /* number of nodes */ +int narcs; /* number of arcs */ +node *nodes; /* array of the nodes - see "types_db.h" */ +arc *arcs; /* array of the arcs - see "types_db.h" */ +} auxiliary_graph; +#else +typedef struct { +int nnodes; /* number of nodes */ +int narcs; /* number of arcs */ +cgl_node *nodes; /* array of the nodes - see "types_db.h" */ +cgl_arc *arcs; /* array of the arcs - see "types_db.h" */ +} auxiliary_graph; +#endif + +typedef struct { +long dist; /* distance from/to root */ +int pred; /* index of the predecessor */ +} short_path_node; + +typedef struct { +double weight; /* overall weight of the cycle */ +int length; /* number of edges in the cycle */ +edge **edge_list; /* list of edges in the cycle */ +} cycle; + +typedef struct { +int cnum; /* overall number of cycles */ +cycle **list; /* pointers to the cycles in the list */ +} cycle_list; + +typedef struct { +int n_of_constr; /* number of constraints combined to get the cut */ +int *constr_list; /* list of the constraints combined */ +short int *in_constr_list; /* flag saying whether a given constraint is + in the list of constraints of the cut (IN) + or not (OUT) */ +int cnzcnt; /* overall number of nonzero's in the cut */ +int *cind; /* column indices of the nonzero entries of the cut */ +int *cval; /* values of the nonzero entries of the cut */ +int crhs; /* right hand side of the cut */ +char csense; /* sense of the cut: 'L', 'G' or 'E' */ +double violation; /* violation of the cut w.r.t. the current LP solution */ +} cut; + +typedef struct { +int cnum; /* overall number of cuts */ +cut **list; /* pointers to the cuts in the list */ +} cut_list; + +typedef struct { +int n_of_constr; /* number of constraints combined to get the cut */ +int *constr_list; /* list of the constraints combined */ +int code; /* identifier of the cut */ +int n_it_violated; /* number of consecutive iterations (starting from the + last and going backward) in which the cut was + violated by the LP solution */ +int it_found; /* iteration in which the cut was separated */ +double score; /* score of the cut, used to choose wich cut should be + added to the current LP (if any) */ +} pool_cut; + +typedef struct { +int cnum; /* overall number of cuts */ +pool_cut **list; /* pointers to the cuts in the list */ +int *ncod; /* number of cuts with a given code in the pool */ +} pool_cut_list; + +typedef struct { +int *ccoef; /* coefficients of the cut */ +int crhs; /* right hand side of the cut */ +int pool_index; /* index of the cut in the pool */ +double score; /* cut score (to be maximized) */ +} select_cut; + +typedef struct { +int n_it_zero; /* number of consecutive iterations (starting from the + last and going backward) in which each variable took + the value 0 in the LP solution */ +} log_var; +/** 012Cut Generator Class + + This class is to make Cgl01cut thread safe etc +*/ + +class Cgl012Cut { + +public: + + /**@name Generate Cuts */ + //@{ +int sep_012_cut( +/* + INPUT parameters: +*/ +int mr, /* number of rows in the ILP matrix */ +int mc, /* number of columns in the ILP matrix */ +int mnz, /* number of nonzero's in the ILP matrix */ +int *mtbeg, /* starting position of each row in arrays mtind and mtval */ +int *mtcnt, /* number of entries of each row in arrays mtind and mtval */ +int *mtind, /* column indices of the nonzero entries of the ILP matrix */ +int *mtval, /* values of the nonzero entries of the ILP matrix */ +int *vlb, /* lower bounds on the variables */ +int *vub, /* upper bounds on the variables */ +int *mrhs, /* right hand sides of the constraints */ +char *msense, /* senses of the constraints: 'L', 'G' or 'E' */ +const double *xstar, /* current optimal solution of the LP relaxation */ +bool aggressive, /* flag asking whether as many cuts as possible are + required on output (TRUE) or not (FALSE) */ +/* + OUTPUT parameters (the memory for the vectors is allocated INTERNALLY + by the procedure: if some memory is already allocated, it is FREED): +*/ +int *cnum, /* number of violated 0-1/2 cuts identified by the procedure */ +int *cnzcnt, /* overall number of nonzero's in the cuts */ +int **cbeg, /* starting position of each cut in arrays cind and cval */ +int **ccnt, /* number of entries of each cut in arrays cind and cval */ +int **cind, /* column indices of the nonzero entries of the cuts */ +int **cval, /* values of the nonzero entries of the cuts */ +int **crhs, /* right hand sides of the cuts */ +char **csense /* senses of the cuts: 'L', 'G' or 'E' */ +/* + NOTE that all the numerical input/output vectors are INTEGER (with + the exception of xstar), since the procedure is intended to work + with pure ILP's, and that the ILP matrix has to be given on input + in ROW format. +*/ + ); +void ilp_load( + int mr, /* number of rows in the ILP matrix */ + int mc, /* number of columns in the ILP matrix */ + int mnz, /* number of nonzero's in the ILP matrix */ + int *mtbeg, /* starting position of each row in arrays mtind and mtval */ + int *mtcnt, /* number of entries of each row in arrays mtind and mtval */ + int *mtind, /* column indices of the nonzero entries of the ILP matrix */ + int *mtval, /* values of the nonzero entries of the ILP matrix */ + int *vlb, /* lower bounds on the variables */ + int *vub, /* upper bounds on the variables */ + int *mrhs, /* right hand sides of the constraints */ + char *msense /* senses of the constraints: 'L', 'G' or 'E' */ + ); +void free_ilp(); +/* alloc_parity_ilp: allocate the memory for the parity ILP data structure */ + +void alloc_parity_ilp( + int mr, /* number of rows in the ILP matrix */ + int mc, /* number of columns in the ILP matrix */ + int mnz /* number of nonzero's in the ILP matrix */ + ); +void free_parity_ilp(); + void initialize_log_var(); +/* free_log_var */ + void free_log_var(); +private: +/* best_weakening: find the best upper/lower bound weakening of a set + of variables */ + +int best_weakening( + int n_to_weak, /* number of variables to weaken */ +int *vars_to_weak, /* indices of the variables to weaken */ +short int original_parity, /* original parity of the constraint to weaken */ +double original_slack, /* original slack of the constraint to weaken */ +double *best_even_slack, /* best possible slack of a weakened constraint + with even right-hand-side */ +double *best_odd_slack, /* best possible slack of a weakened constraint + with odd right-hand-side */ +info_weak **info_even_weak, /* weakening information about the best possible + even weakened constraint */ +info_weak **info_odd_weak, /* weakening information about the best possible + odd weakened constraint */ +short int only_odd, /* flag which tells whether only an odd weakening is of + interest (TRUE) or both weakenings are (FALSE) */ +short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); + +/* best_cut: find the coefficients, the rhs and the violation of the + best possible cut that can be obtained by weakening a given set of + coefficients to even and a rhs to odd, dividing by 2 and rounding */ + +short int best_cut( + int *ccoef, /* vector of the coefficients */ + int *crhs, /* pointer to rhs value */ + double *violation, /* violation of the cut */ + short int update, /* TRUE/FALSE: if TRUE, the new ccoef and crhs are + given on output */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* get_cut: extract a hopefully violated cut from an odd cycle of the + separation graph */ + +cut *get_cut( + cycle *s_cyc /* shortest odd cycles identified in the separation graph */ + ); + +/* update_log_var: update the log information for the problem variables */ + void update_log_var(); + +/* basic_separation: try to identify violated 0-1/2 cuts by using the + original procedure described in Caprara and Fischetti's MP paper */ + + cut_list *basic_separation(); + +/* score_by_moving: compute the score of the best cut obtainable from + the current local search solution by inserting/deleting a constraint */ + +double score_by_moving( + int i, /* constraint to be moved */ + short int itype, /* type of move - ADD or DEL */ + double thresh /* minimum value of an interesting score */ + ); +/* modify_current: update the current local search solution by inserting/ + deleting a constraint */ + +void modify_current( + int i, /* constraint to be moved */ + short int itype /* type of move - ADD or DEL */ + ); + +/* best neighbour: find the cut to be added/deleted from the current + solution among those allowed by the tabu rules */ + + short int best_neighbour(cut_list *out_cuts /* list of the violated cuts found */); + +/* add_tight_constraint: initialize the current cut by adding a tight + constraint to it */ + + void add_tight_constraint(); + +/* tabu_012: try to identify violated 0-1/2 cuts by a simple tabu search + procedure adapted from that used by Battiti and Protasi for finding + large cliques */ + + cut_list *tabu_012(); +/* initialize: initialize the data structures for local search */ + + void initialize(); +/* restart: perform a restart of the search - IMPORTANT: in the current + implementation vector last_moved is not cleared at restart */ + + void restart(short int failure /* flag forcing the restart if some trouble occurred */); + void print_constr(int i /* constraint to be printed */); + void print_parity_ilp(); + +/* get_parity_ilp: construct an internal data structure containing all the + information which can be useful for 0-1/2 cut separation */ + + void get_parity_ilp(); +/* initialize_sep_graph: allocate and initialize the data structure + to contain the information associated with a separation graph */ + + separation_graph *initialize_sep_graph(); + void print_cut(cut *v_cut); +/* get_ori_cut_coef: get the coefficients of a cut, before dividing by 2 and + rounding, starting from the list of the constraints combined to get + the cut */ + +short int get_ori_cut_coef( + int n_of_constr, /* number of constraints combined */ + int *constr_list, /* list of the constraints combined */ + int *ccoef, /* cut left hand side coefficients */ + int *crhs, /* cut right hand side */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* define_cut: construct a cut data structure from a vector of + coefficients and a right-hand-side */ + +cut *define_cut( + int *ccoef, /* coefficients of the cut */ + int crhs /* right hand side of the cut */ + ); + +/* cut_score: define the score of a (violated) cut */ + +double cut_score( + int *ccoef, /* cut left hand side coefficients */ + int crhs, /* cut right hand side */ + double viol, /* cut violation */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* get_current_cut: return a cut data type with the information about + the current cut of the search procedure */ + + cut *get_current_cut(); +/* print_cur_cut: display cur_cut on output */ + + void print_cur_cut(); + void print_cut_list(cut_list *cuts); + //@} +public: + /**@name Constructors and destructors */ + //@{ + /// Default constructor + Cgl012Cut (); + + /// Copy constructor + Cgl012Cut ( + const Cgl012Cut &); + + /// Assignment operator + Cgl012Cut & + operator=( + const Cgl012Cut& rhs); + + /// Destructor + virtual ~Cgl012Cut (); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + //@} + + + /**@name Private member data */ + //@{ + +ilp *inp_ilp; /* input ILP data structure */ +parity_ilp *p_ilp; /* parity ILP data structure */ +int iter; +double gap; +double maxgap; +int errorNo; +int sep_iter; /* number of the current separation iteration */ +log_var **vlog; /* information about the value attained + by the variables in the last iterations, + used to possibly set to 0 some coefficient + > 0 in a cut to be added */ +bool aggr; /* flag saying whether as many cuts as possible are required + from the separation procedure (TRUE) or not (FALSE) */ + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglAllDifferent.hpp b/thirdparty/linux/include/coin/coin/CglAllDifferent.hpp new file mode 100644 index 0000000..ed369d1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglAllDifferent.hpp @@ -0,0 +1,115 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglAllDifferent_H +#define CglAllDifferent_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** AllDifferent Cut Generator Class + This has a number of sets. All the members in each set are general integer + variables which have to be different from all others in the set. + + At present this only generates column cuts + + At present it is very primitive compared to proper CSP implementations + */ +class CglAllDifferent : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** This fixes (or reduces bounds) on sets of all different variables + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglAllDifferent (); + + /// Useful constructot + CglAllDifferent(int numberSets, const int * starts, const int * which); + + /// Copy constructor + CglAllDifferent ( + const CglAllDifferent &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglAllDifferent & + operator=( + const CglAllDifferent& rhs); + + /// Destructor + virtual + ~CglAllDifferent (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const + { return false;} + //@} + /**@name Sets and Gets */ + //@{ + /// Set log level + inline void setLogLevel(int value) + { logLevel_=value;} + /// Get log level + inline int getLogLevel() const + { return logLevel_;} + /// Set Maximum number of sets to look at at once + inline void setMaxLook(int value) + { maxLook_=value;} + /// Get Maximum number of sets to look at at once + inline int getMaxLook() const + { return maxLook_;} + //@} + +private: + + // Private member methods + /**@name */ + //@{ + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// Number of sets + int numberSets_; + /// Total number of variables in all different sets + int numberDifferent_; + /// Maximum number of sets to look at at once + int maxLook_; + /// Log level - 0 none, 1 - a bit, 2 - more details + int logLevel_; + /// Start of each set + int * start_; + /// Members (0,1,....) not as in original model + int * which_; + /// Original members + int * originalWhich_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglClique.hpp b/thirdparty/linux/include/coin/coin/CglClique.hpp new file mode 100644 index 0000000..288052d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglClique.hpp @@ -0,0 +1,312 @@ +// $Id: CglClique.hpp 1330 2016-01-26 19:35:16Z forrest $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CglClique_h_ +#define _CglClique_h_ + +#include "CglCutGenerator.hpp" + +//class OsiCuts; +//class OsiSolverInterface; + +class CglClique : public CglCutGenerator { + + friend void CglCliqueUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); +public: + /// Copy constructor + CglClique(const CglClique& rhs); + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglClique& operator=(const CglClique& rhs); + +public: + + virtual void + generateCuts(const OsiSolverInterface& si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /**@name Constructors and destructors */ + //@{ + /** Default constructor. + If the setPacking argument is set to true then CglClique will assume that the + problem in the solverinterface passed to the generateCuts() method + describes a set packing problem, i.e., + - all variables are binary + - the matrix is a 0-1 matrix + - all constraints are '= 1' or '<= 1' + + Otherwise the user can use the considerRows() method to set the list of + clique rows, that is, + - all coeffs corresponding to binary variables at fractional level is 1 + - all other coeffs are non-negative + - the constraint is '= 1' or '<= 1'. + + If the user does not set the list of clique rows then CglClique will + start the generateCuts() methods by scanning the matrix for them. + Also justOriginalRows can be set to true to limit clique creation + */ + CglClique(bool setPacking = false, bool justOriginalRows = false); + /// Destructor + virtual ~CglClique() {} + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + void considerRows(const int numRows, const int* rowInd); + +public: + /** possible choices for selecting the next node in the star clique search + */ + enum scl_next_node_method { + SCL_MIN_DEGREE, + SCL_MAX_DEGREE, + SCL_MAX_XJ_MAX_DEG + }; + + void setStarCliqueNextNodeMethod(scl_next_node_method method) { + scl_next_node_rule = method; + } + + void setStarCliqueCandidateLengthThreshold(int maxlen) { + scl_candidate_length_threshold = maxlen; + } + void setRowCliqueCandidateLengthThreshold(int maxlen) { + rcl_candidate_length_threshold = maxlen; + } + + void setStarCliqueReport(bool yesno = true) { scl_report_result = yesno; } + void setRowCliqueReport(bool yesno = true) { rcl_report_result = yesno; } + + void setDoStarClique(bool yesno = true) { do_star_clique = yesno; } + void setDoRowClique(bool yesno = true) { do_row_clique = yesno; } + + void setMinViolation(double minviol) { petol = minviol; } + double getMinViolation() const { return petol; } + /// Maximum number of binaries for looking at all + inline void setMaxNumber(int value) { maxNumber_ = value; } + +private: + + struct frac_graph ; + friend struct frac_graph ; + + /** A node of the fractional graph. There is a node for every variable at + fractional level. */ + struct fnode { + /** pointer into all_nbr */ + int *nbrs; + /** 1-x_i-x_j, needed for odd holes, in the same order as the adj list, + pointer into all_edgecost */ + double *edgecosts; + /** degree of the node */ + int degree; + /** the fractional value of the variable corresponding to this node */ + double val; + }; + + /** A graph corresponding to a fractional solution of an LP. Two nodes are + adjacent iff their columns are non-orthogonal. */ + struct frac_graph { + /** # of nodes = # of fractional values in the LP solution */ + int nodenum; + /** # of edges in the graph */ + int edgenum; + /** density= edgenum/(nodenum choose 2) */ + double density; + int min_deg_node; + int min_degree; + int max_deg_node; + int max_degree; + /** The array of the nodes in the graph */ + fnode *nodes; + /** The array of all the neighbors. First the indices of the nodes + adjacent to node 0 are listed, then those adjacent to node 1, etc. */ + int *all_nbr; + /** The array of the costs of the edges going to the neighbors */ + double *all_edgecost; + + frac_graph() : + nodenum(0), edgenum(0), density(0), + min_deg_node(0), min_degree(0), max_deg_node(0), max_degree(0), + nodes(0), all_nbr(0), all_edgecost(0) {} + }; + +protected: + /** An indicator showing whether the whole matrix in the solverinterface is + a set packing problem or not */ + bool setPacking_; + /// True if just look at original rows + bool justOriginalRows_; + /** pieces of the set packing part of the solverinterface */ + int sp_numrows; + int* sp_orig_row_ind; + int sp_numcols; + int* sp_orig_col_ind; + double* sp_colsol; + int* sp_col_start; + int* sp_col_ind; + int* sp_row_start; + int* sp_row_ind; + + /** the intersection graph corresponding to the set packing problem */ + frac_graph fgraph; + /** the node-node incidence matrix of the intersection graph. */ + bool* node_node; + + /** The primal tolerance in the solverinterface. */ + double petol; + /// Maximum number of binaries for looking at all + int maxNumber_; + + /** data for the star clique algorithm */ + + /** Parameters */ + /**@{*/ + /** whether to do the row clique algorithm or not. */ + bool do_row_clique; + /** whether to do the star clique algorithm or not. */ + bool do_star_clique; + + /** How the next node to be added to the star clique should be selected */ + scl_next_node_method scl_next_node_rule; + /** In the star clique method the maximal length of the candidate list + (those nodes that are in a star, i.e., connected to the center of the + star) to allow complete enumeration of maximal cliques. Otherwise a + greedy algorithm is used. */ + int scl_candidate_length_threshold; + /** whether to give a detailed statistics on the star clique method */ + bool scl_report_result; + + /** In the row clique method the maximal length of the candidate list + (those nodes that can extend the row clique, i.e., connected to all + nodes in the row clique) to allow complete enumeration of maximal + cliques. Otherwise a greedy algorithm is used. */ + int rcl_candidate_length_threshold; + /** whether to give a detailed statistics on the row clique method */ + bool rcl_report_result; + /**@}*/ + + /** variables/arrays that are used across many methods */ + /**@{*/ + /** List of indices that must be in the to be created clique. This is just + a pointer, it is never new'd and therefore does not need to be + delete[]'d either. */ + const int* cl_perm_indices; + /** The length of cl_perm_indices */ + int cl_perm_length; + + /** List of indices that should be considered for extending the ones listed + in cl_perm_indices. */ + int* cl_indices; + /** The length of cl_indices */ + int cl_length; + + /** An array of nodes discarded from the candidate list. These are + rechecked when a maximal clique is found just to make sure that the + clique is really maximal. */ + int* cl_del_indices; + /** The length of cl_del_indices */ + int cl_del_length; + + /**@}*/ + +private: + /** Scan through the variables and select those that are binary and are at + a fractional level. */ + void selectFractionalBinaries(const OsiSolverInterface& si); + /** Scan through the variables and select those that are at a fractional + level. We already know that everything is binary. */ + void selectFractionals(const OsiSolverInterface& si); + /** */ + void selectRowCliques(const OsiSolverInterface& si,int numOriginalRows); + /** */ + void createSetPackingSubMatrix(const OsiSolverInterface& si); + /** */ + void createFractionalGraph(); + /** */ + int createNodeNode(); + /** */ + void deleteSetPackingSubMatrix(); + /** */ + void deleteFractionalGraph(); + /** */ + void find_scl(OsiCuts& cs); + /** */ + void find_rcl(OsiCuts& cs); + /** */ + int scl_choose_next_node(const int current_nodenum, + const int *current_indices, + const int *current_degrees, + const double *current_values); + /** */ + void scl_delete_node(const int del_ind, int& current_nodenum, + int *current_indices, int *current_degrees, + double *current_values); + /** */ + int enumerate_maximal_cliques(int& pos, bool* scl_label, OsiCuts& cs); + /** */ + int greedy_maximal_clique(OsiCuts& cs); + /** */ + void recordClique(const int len, int* indices, OsiCuts& cs); +}; +//############################################################################# +/** A function that tests the methods in the CglClique class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglCliqueUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +/// This works on a fake solver i.e. invented rows +class CglProbing; +class CglFakeClique : public CglClique { + +public: + /// Copy constructor + CglFakeClique(const CglFakeClique& rhs); + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglFakeClique& operator=(const CglFakeClique& rhs); + + virtual void + generateCuts(const OsiSolverInterface& si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /**@name Constructors and destructors */ + //@{ + /** Default constructor. + If the setPacking argument is set to true then CglFakeClique will assume that the + problem in the solverinterface passed to the generateCuts() method + describes a set packing problem, i.e., + - all variables are binary + - the matrix is a 0-1 matrix + - all constraints are '= 1' or '<= 1' + + Otherwise the user can use the considerRows() method to set the list of + clique rows, that is, + - all coeffs corresponding to binary variables at fractional level is 1 + - all other coeffs are non-negative + - the constraint is '= 1' or '<= 1'. + + If the user does not set the list of clique rows then CglFakeClique will + start the generateCuts() methods by scanning the matrix for them. + */ + CglFakeClique(OsiSolverInterface * solver=NULL,bool setPacking = false); + /// Destructor + virtual ~CglFakeClique(); + /// Assign solver (generator takes over ownership) + void assignSolver(OsiSolverInterface * fakeSolver); +protected: + /// fake solver to use + OsiSolverInterface * fakeSolver_; + /// Probing object + CglProbing * probing_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglConfig.h b/thirdparty/linux/include/coin/coin/CglConfig.h new file mode 100644 index 0000000..a4de202 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglConfig.h @@ -0,0 +1,19 @@ +/* src/config_cgl.h. Generated by configure. */ +/* src/config_cgl.h.in. */ + +#ifndef __CONFIG_CGL_H__ +#define __CONFIG_CGL_H__ + +/* Version number of project */ +#define CGL_VERSION "0.59.9" + +/* Major Version number of project */ +#define CGL_VERSION_MAJOR 0 + +/* Minor Version number of project */ +#define CGL_VERSION_MINOR 59 + +/* Release Version number of project */ +#define CGL_VERSION_RELEASE 9 + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglCutGenerator.hpp b/thirdparty/linux/include/coin/coin/CglCutGenerator.hpp new file mode 100644 index 0000000..7629140 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglCutGenerator.hpp @@ -0,0 +1,121 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglCutGenerator_H +#define CglCutGenerator_H + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" +#include "CglTreeInfo.hpp" + +//------------------------------------------------------------------- +// +// Abstract base class for generating cuts. +// +//------------------------------------------------------------------- +/// +/** Cut Generator Base Class + +This is an abstract base class for generating cuts. A specific cut +generator will inherit from this class. +*/ +class CglCutGenerator { + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate cuts for the model data contained in si. + The generated cuts are inserted into and returned in the + collection of cuts cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo())=0; + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglCutGenerator (); + + /// Copy constructor + CglCutGenerator ( const CglCutGenerator &); + + /// Clone + virtual CglCutGenerator * clone() const = 0; + + /// Assignment operator + CglCutGenerator & operator=(const CglCutGenerator& rhs); + + /// Destructor + virtual ~CglCutGenerator (); + + /** Create C++ lines to set the generator in the current state. + The output must be parsed by the calling code, as each line + starts with a key indicating the following:<BR> + 0: must be kept (for #includes etc)<BR> + 3: Set to changed (not default) values<BR> + 4: Set to default values (redundant)<BR> + + Keys 1, 2, 5, 6, 7, 8 are defined, but not applicable to + cut generators. + */ + virtual std::string generateCpp( FILE * ) {return "";} + + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * ) {} + //@} + + /**@name Gets and Sets */ + //@{ + /** + Get Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + inline int getAggressiveness() const + { return aggressive_;} + + /** + Set Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + inline void setAggressiveness(int value) + { aggressive_=value;} + /// Set whether can do global cuts + inline void setGlobalCuts(bool trueOrFalse) + { canDoGlobalCuts_ = trueOrFalse;} + /// Say whether can do global cuts + inline bool canDoGlobalCuts() const + {return canDoGlobalCuts_;} + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const; + /// Return true if needs optimal basis to do cuts + virtual bool needsOptimalBasis() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const + { return COIN_INT_MAX;} + //@} + + // test this class + //static void unitTest(); + +// private: + + /** + Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + int aggressive_; + /// True if can do global cuts i.e. no general integers + bool canDoGlobalCuts_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglDuplicateRow.hpp b/thirdparty/linux/include/coin/coin/CglDuplicateRow.hpp new file mode 100644 index 0000000..b40f969 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglDuplicateRow.hpp @@ -0,0 +1,189 @@ +// $Id: CglDuplicateRow.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglDuplicateRow_H +#define CglDuplicateRow_H + +#include <string> + +#include "CglCutGenerator.hpp" +class CglStored; + +/** DuplicateRow Cut Generator Class */ +class CglDuplicateRow : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Fix variables and find duplicate/dominated rows for the model of the + solver interface, si. + + This is a very simple minded idea but I (JJF) am using it in a project so thought + I might as well add it. It should really be called before first solve and I may + modify CBC to allow for that. + + This is designed for problems with few rows and many integer variables where the rhs + are <= or == and all coefficients and rhs are small integers. + + If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds + (effective rhs just means original with variables with nonzero lower bounds subtracted out). + + If one row is a subset of another and the effective rhs are same we can fix some variables + and then the two rows are identical. + + The generator marks identical rows so can be taken out in solve + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); +private: + /// Does work for modes 1,2 + void generateCuts12( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Does work for mode 4 + void generateCuts4( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Does work for mode 8 + void generateCuts8( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); +public: + /** Fix variables and find duplicate/dominated rows for the model of the + solver interface, si. + + This is a very simple minded idea but I (JJF) am using it in a project so thought + I might as well add it. It should really be called before first solve and I may + modify CBC to allow for that. + + This is designed for problems with few rows and many integer variables where the rhs + are <= or == and all coefficients and rhs are small integers. + + If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds + (effective rhs just means original with variables with nonzero lower bounds subtracted out). + + If one row is a subset of another and the effective rhs are same we can fix some variables + and then the two rows are identical. + + This version does deletions and fixings and may return stored cuts for + dominated columns + */ + CglStored * outDuplicates( OsiSolverInterface * solver); + + //@} + + /**@name Get information on size of problem */ + //@{ + /// Get duplicate row list, -1 means still in, -2 means out (all fixed), k>= means same as row k + inline const int * duplicate() const + { return duplicate_;} + /// Size of dynamic program + inline int sizeDynamic() const + { return sizeDynamic_;} + /// Number of rows in original problem + inline int numberOriginalRows() const + { return matrix_.getNumRows();} + //@} + + /**@name Get information on size of problem */ + //@{ + /// logLevel + inline int logLevel() const + { return logLevel_;} + inline void setLogLevel(int value) + { logLevel_ = value;} + //@} + + + /**@name We only check for duplicates amongst rows with effective rhs <= this */ + //@{ + /// Get + inline int maximumRhs() const + { return maximumRhs_;} + /// Set + inline void setMaximumRhs(int value) + { maximumRhs_=value;} + //@} + + /**@name We only check for dominated amongst groups of columns whose size <= this */ + //@{ + /// Get + inline int maximumDominated() const + { return maximumDominated_;} + /// Set + inline void setMaximumDominated(int value) + { maximumDominated_=value;} + //@} + /**@name gets and sets */ + //@{ + /// Get mode + inline int mode() const + { return mode_;} + /// Set mode + inline void setMode(int value) + { mode_=value;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglDuplicateRow (); + + /// Useful constructor + CglDuplicateRow (OsiSolverInterface * solver); + + /// Copy constructor + CglDuplicateRow ( + const CglDuplicateRow & rhs); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglDuplicateRow & + operator=( + const CglDuplicateRow& rhs); + + /// Destructor + virtual + ~CglDuplicateRow (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +protected: + + + // Protected member data + + /**@name Protected member data */ + //@{ + /// Matrix + CoinPackedMatrix matrix_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Possible rhs (if 0 then not possible) + int * rhs_; + /// Marks duplicate rows + int * duplicate_; + /// To allow for <= rows + int * lower_; + /// Stored cuts if we found dominance cuts + CglStored * storedCuts_; + /// Check dominated columns if less than this number of candidates + int maximumDominated_; + /// Check duplicates if effective rhs <= this + int maximumRhs_; + /// Size of dynamic program + int sizeDynamic_; + /// 1 do rows, 2 do columns, 3 do both + int mode_; + /// Controls print out + int logLevel_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglFlowCover.hpp b/thirdparty/linux/include/coin/coin/CglFlowCover.hpp new file mode 100644 index 0000000..eea070f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglFlowCover.hpp @@ -0,0 +1,371 @@ +// $Id: CglFlowCover.hpp 1119 2013-04-06 20:24:18Z stefan $ +//----------------------------------------------------------------------------- +// name: Cgl Lifted Simple Generalized Flow Cover Cut Generator +// author: Yan Xu email: yan.xu@sas.com +// Jeff Linderoth email: jtl3@lehigh.edu +// Martin Savelsberg email: martin.savelsbergh@isye.gatech.edu +// date: 05/01/2003 +// comments: please scan this file for '???' and read the comments +//----------------------------------------------------------------------------- +// Copyright (C) 2003, Yan Xu, Jeff Linderoth, Martin Savelsberg and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglFlowCover_H +#define CglFlowCover_H + +#include <iostream> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +//============================================================================= + +/** This enumerative constant describes the various col types.*/ +enum CglFlowColType { + /** The column(variable) is a negative binary variable.*/ + CGLFLOW_COL_BINNEG = -2, + /** The column is a negative continous variable.*/ + CGLFLOW_COL_CONTNEG, + /** The column is a positive continous variable.*/ + CGLFLOW_COL_CONTPOS = 1, + /** The column is a positive binary variable.*/ + CGLFLOW_COL_BINPOS +}; + +enum CglFlowColStatus{ +}; + +/** This enumerative constant describes the various stati of vars in + a cut or not.*/ +enum CglFlowColCut{ + /** The column is NOT in cover.*/ + CGLFLOW_COL_OUTCUT = 0, + /** The column is in cover now. */ + CGLFLOW_COL_INCUT, + /** The column is decided to be in cover. */ + CGLFLOW_COL_INCUTDONE, + /** The column is in L-. */ + CGLFLOW_COL_INLMIN, + /** The column is decided to be in L-. */ + CGLFLOW_COL_INLMINDONE, + /** The column is in L--.*/ + CGLFLOW_COL_INLMINMIN, + /** This enumerative constant describes the various stati of vars in + determining the cover.*/ + /** The column is a prime candidate. */ + CGLFLOW_COL_PRIME, + /** The column is a secondary candidate. */ + CGLFLOW_COL_SECONDARY +}; + +/** This enumerative constant describes the various row types.*/ +enum CglFlowRowType { + /** The row type of this row is NOT defined yet.*/ + CGLFLOW_ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is continous, and the RHS + is zero.*/ + CGLFLOW_ROW_VARUB, + /** After the row is flipped to 'L', the row has exactlytwo variables: + one is positive binary and the other is continous, and the RHS + is zero.*/ + CGLFLOW_ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + CGLFLOW_ROW_VAREQ, + /** Rows can not be classfied into other types and the row sense + is NOT 'E'.*/ + CGLFLOW_ROW_MIXUB, + /** Rows can not be classfied into other types and the row sense is 'E'.*/ + CGLFLOW_ROW_MIXEQ, + /** All variables are NOT binary and the row sense is NOT 'E'. */ + CGLFLOW_ROW_NOBINUB, + /** All variables are NOT binary and the row sense is 'E'. */ + CGLFLOW_ROW_NOBINEQ, + /** The row has one binary and 2 or more other types of variables and + the row sense is NOT 'E'. */ + CGLFLOW_ROW_SUMVARUB, + /** The row has one binary and 2 or more other types of variables and + the row sense is 'E'. */ + CGLFLOW_ROW_SUMVAREQ, + /** All variables are binary. */ + CGLFLOW_ROW_UNINTERSTED +}; + +//============================================================================= + +/** Variable upper bound class. */ +class CglFlowVUB +{ +protected: + int varInd_; /** The index of the associated 0-1 variable.*/ + double upper_; /** The Value of the associated upper bound.*/ + +public: + CglFlowVUB() : varInd_(-1), upper_(-1) {} + + CglFlowVUB(const CglFlowVUB& source) { + varInd_= source.varInd_; + upper_ = source.upper_; + } + + CglFlowVUB& operator=(const CglFlowVUB& rhs) { + if (this == &rhs) + return *this; + varInd_= rhs.varInd_; + upper_ = rhs.upper_; + return *this; + } + + /**@name Query and set functions for associated 0-1 variable index + and value. + */ + //@{ + inline int getVar() const { return varInd_; } + inline double getVal() const { return upper_; } + inline void setVar(const int v) { varInd_ = v; } + inline void setVal(const double v) { upper_ = v; } + //@} +}; + +//============================================================================= + +/** Variable lower bound class, which is the same as vub. */ +typedef CglFlowVUB CglFlowVLB; + +/** Overloaded operator<< for printing VUB and VLB.*/ +std::ostream& operator<<( std::ostream& os, const CglFlowVUB &v ); + +//============================================================================= + +/** + * Lifed Simple Generalized Flow Cover Cut Generator Class. + */ +class CglFlowCover : public CglCutGenerator { + friend void CglFlowCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /** + * Do the following tasks: + * <ul> + * <li> classify row types + * <li> indentify vubs and vlbs + * </ul> + * This function is called by + * <CODE>generateCuts(const OsiSolverInterface & si, OsiCuts & cs)</CODE>. + */ + void flowPreprocess(const OsiSolverInterface& si); + + /**@name Generate Cuts */ + //@{ + /** Generate Lifed Simple Generalized flow cover cuts for the model data + contained in si. The generated cuts are inserted into and returned + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Functions to query and set maximum number of cuts can be + generated. */ + //@{ + inline int getMaxNumCuts() const { return maxNumCuts_; } + inline void setMaxNumCuts(int mc) { maxNumCuts_ = mc; } + //@} + + /**@name Functions to query and set the number of cuts have been + generated. */ + //@{ + static int getNumFlowCuts() { return numFlowCuts_; } + static void setNumFlowCuts(int fc) { numFlowCuts_ = fc; } + static void incNumFlowCuts(int fc = 1) { numFlowCuts_ += fc; } + //@} + + //------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglFlowCover (); + + /// Copy constructor + CglFlowCover ( + const CglFlowCover &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglFlowCover & + operator=( + const CglFlowCover& rhs); + + /// Destructor + virtual + ~CglFlowCover (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + //------------------------------------------------------------------------- + // Private member functions + + /** Based a given row, a LP solution and other model data, this function + tries to generate a violated lifted simple generalized flow cover. + */ + bool generateOneFlowCut( const OsiSolverInterface & si, + const int rowLen, + int* ind, + double* coef, + char sense, + double rhs, + OsiRowCut& flowCut, + double& violation ); + + + /** Transform a row from ">=" to "<=", and vice versa. */ + void flipRow(int rowLen, double* coef, double& rhs) const; + + /** Transform a row from ">=" to "<=", and vice versa. Have 'sense'. */ + void flipRow(int rowLen, double* coef, char& sen, double& rhs) const; + + /** Determine the type of a given row. */ + CglFlowRowType determineOneRowType(const OsiSolverInterface& si, + int rowLen, int* ind, + double* coef, char sen, + double rhs) const; + /** Lift functions */ + void liftMinus(double &movement, /* Output */ + int t, + int r, + double z, + double dPrimePrime, + double lambda, + double ml, + double *M, + double *rho) const; + + bool liftPlus(double &alpha, + double &beta, + int r, + double m_j, + double lambda, + double y_j, + double x_j, + double dPrimePrime, + double *M) const; + + + //------------------------------------------------------------------------- + //**@name Query and set the row type of a givne row. */ + //@{ + inline const CglFlowRowType* getRowTypes() const + { return rowTypes_; } + inline CglFlowRowType getRowType(const int i) const + { return rowTypes_[i]; } + /** Set rowtypes, take over the ownership. */ + inline void setRowTypes(CglFlowRowType* rt) + { rowTypes_ = rt; rt = 0; } + inline void setRowTypes(const CglFlowRowType rt, const int i) { + if (rowTypes_ != 0) + rowTypes_[i] = rt; + else { + std::cout << "ERROR: Should allocate memory for rowType_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for rowType_", + "setRowType", "CglFlowCover"); + } + } + //@} + + //------------------------------------------------------------------------- + //**@name Query and set vubs. */ + //@{ + inline const CglFlowVUB* getVubs() const { return vubs_; } + inline const CglFlowVUB& getVubs(int i) const { return vubs_[i]; } + /** Set CglFlowVUBs,take over the ownership. */ + inline void setVubs(CglFlowVUB* vubs) { vubs_ = vubs; vubs = 0; } + inline void setVubs(const CglFlowVUB& vub, int i) { + if (vubs_ != 0) + vubs_[i] = vub; + else { + std::cout << "ERROR: Should allocate memory for vubs_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for vubs_", "setVubs", + "CglFlowCover"); + } + } + inline void printVubs(std::ostream& os) const { + for (int i = 0; i < numCols_; ++i) { + os << "ix: " << i << ", " << vubs_[i]; + } + } + //@} + + //------------------------------------------------------------------------- + //**@name Query and set vlbs. */ + //@{ + inline const CglFlowVLB* getVlbs() const { return vlbs_; } + inline const CglFlowVLB& getVlbs(int i) const { return vlbs_[i]; } + /** Set CglFlowVLBs,take over the ownership. */ + inline void setVlbs(CglFlowVLB* vlbs) { vlbs_ = vlbs; vlbs = 0; } + inline void setVlbs(const CglFlowVLB& vlb, int i) { + if (vlbs_ != 0) + vlbs_[i] = vlb; + else { + std::cout << "ERROR: Should allocate memory for vlbs_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for vlbs_", "setVlbs", + "CglFlowCover"); + } + } + //@} + +private: + //------------------------------------------------------------------------ + // Private member data + + /** The maximum number of flow cuts to be generated. Default is 1000. */ + int maxNumCuts_; + /** Tolerance used for numerical purpose. */ + double EPSILON_; + /** The variable upper bound of a flow is not indentified yet.*/ + int UNDEFINED_; + /** Very large number. */ + double INFTY_; + /** If violation of a cut is greater that this number, the cut is useful.*/ + double TOLERANCE_; + /** First time preprocessing */ + bool firstProcess_; + /** The number rows of the problem.*/ + int numRows_; + /** The number columns of the problem.*/ + int numCols_; + /** The number flow cuts found.*/ + static int numFlowCuts_; + /** Indicate whether initial flow preprecessing has been done. */ + bool doneInitPre_; + /** The array of CglFlowVUBs. */ + CglFlowVUB* vubs_; + /** The array of CglFlowVLBs. */ + CglFlowVLB* vlbs_; + /** CglFlowRowType of the rows in model. */ + CglFlowRowType* rowTypes_; +}; + +//############################################################################# +/** A function that tests the methods in the CglFlowCover class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglFlowCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglGMI.hpp b/thirdparty/linux/include/coin/coin/CglGMI.hpp new file mode 100644 index 0000000..240f6ad --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglGMI.hpp @@ -0,0 +1,364 @@ +// Last edit: 02/05/2013 +// +// Name: CglGMI.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design, Singapore +// email: nannicini@sutd.edu.sg +// Date: 11/17/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2009, Giacomo Nannicini. All Rights Reserved. + +#ifndef CglGMI_H +#define CglGMI_H + +#include "CglCutGenerator.hpp" +#include "CglGMIParam.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CoinFactorization.hpp" + +/* Enable tracking of rejection of cutting planes. If this is disabled, + the cut generator is slightly faster. If defined, it enables proper use + of setTrackRejection and related functions. */ +//#define TRACK_REJECT + +/* Debug output */ +//#define GMI_TRACE + +/* Debug output: print optimal tableau */ +//#define GMI_TRACETAB + +/* Print reason for cut rejection, whenever a cut is discarded */ +//#define GMI_TRACE_CLEAN + +/** Gomory cut generator with several cleaning procedures, used to test + * the numerical safety of the resulting cuts + */ + +class CglGMI : public CglCutGenerator { + + friend void CglGMIUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + + /** Public enum: all possible reasons for cut rejection */ + enum RejectionType{ + failureFractionality, + failureDynamism, + failureViolation, + failureSupport, + failureScale + }; + + /**@name generateCuts */ + //@{ + /** Generate Gomory Mixed-Integer cuts for the model of the solver + interface si. + + Insert the generated cuts into OsiCuts cs. + + Warning: This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau and + optimal basis inverse and makes assumptions on the way slack variables + are added by the solver. The Osi implementations for Clp and Cplex + verify these assumptions. + + When calling the generator, the solver interface si must contain + an optimized problem and information related to the optimal + basis must be available through the OsiSolverInterface methods + (si->optimalBasisIsAvailable() must return 'true'). It is also + essential that the integrality of structural variable i can be + obtained using si->isInteger(i). + + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const { return true; } + //@} + + /**@name Common Methods */ + //@{ + // Function for checking equality with user tolerance + inline bool areEqual(double x, double y, + double epsAbs = 1e-12, + double epsRel = 1e-12) { + return (fabs((x) - (y)) <= + std::max(epsAbs, epsRel * std::max(fabs(x), fabs(y)))); + } + + // Function for checking is a number is zero + inline bool isZero(double x, double epsZero = 1e-20) { + return (fabs(x) <= epsZero); + } + + + // Function for checking if a number is integer + inline bool isIntegerValue(double x, + double intEpsAbs = 1e-9, + double intEpsRel = 1e-15) { + return (fabs((x) - floor((x)+0.5)) <= + std::max(intEpsAbs, intEpsRel * fabs(x))); + } + + + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglGMIParam object. + void setParam(const CglGMIParam &source); + // Return the CglGMIParam object of the generator. + inline CglGMIParam getParam() const {return param;} + inline CglGMIParam & getParam() {return param;} + + // Compute entries of is_integer. + void computeIsInteger(); + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + /// Set/get tracking of the rejection of cutting planes. + /// Note that all rejection related functions will not do anything + /// unless the generator is compiled with the define GMI_TRACK_REJECTION + void setTrackRejection(bool value); + bool getTrackRejection(); + + /// Get number of cuts rejected for given reason; see above + int getNumberRejectedCuts(RejectionType reason); + + /// Reset counters for cut rejection tracking; see above + void resetRejectionCounters(); + + /// Get total number of generated cuts since last resetRejectionCounters() + int getNumberGeneratedCuts(); + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGMI(); + + /// Constructor with specified parameters + CglGMI(const CglGMIParam ¶m); + + /// Copy constructor + CglGMI(const CglGMI &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglGMI & operator=(const CglGMI& rhs); + + /// Destructor + virtual ~CglGMI(); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglGMI members are properly set. + void generateCuts(OsiCuts & cs); + + /// Compute the fractional part of value, allowing for small error. + inline double aboveInteger(double value) const; + + /// Compute the fractionalities involved in the cut, and the cut rhs. + /// Returns true if cut is accepted, false if discarded + inline bool computeCutFractionality(double varRhs, double& cutRhs); + + /// Compute the cut coefficient on a given variable + inline double computeCutCoefficient(double rowElem, int index); + + /// Use multiples of the initial inequalities to cancel out the coefficient + /// on a slack variables. + inline void eliminateSlack(double cutElem, int cutIndex, double* cut, + double& cutRhs, const double *elements, + const int *rowStart, const int *indices, + const int *rowLength, const double *rhs); + + /// Change the sign of the coefficients of the non basic + /// variables at their upper bound. + inline void flip(double& rowElem, int rowIndex); + + /// Change the sign of the coefficients of the non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. Two functions: one for original variables, one for slacks. + inline void unflipOrig(double& rowElem, int rowIndex, double& rowRhs); + inline void unflipSlack(double& rowElem, int rowIndex, double& rowRhs, + const double* slack_val); + + /// Pack a row of ncol elements + inline void packRow(double* row, double* rowElem, int* rowIndex, + int& rowNz); + + /// Clean the cutting plane; the cleaning procedure does several things + /// like removing small coefficients, scaling, and checks several + /// acceptance criteria. If this returns false, the cut should be discarded. + /// There are several cleaning procedures available, that can be selected + /// via the parameter param.setCLEANING_PROCEDURE(int value) + bool cleanCut(double* cutElem, int* cutIndex, int& cutNz, + double& cutRhs, const double* xbar); + + /// Cut cleaning procedures: return true if successfull, false if + /// cut should be discarded by the caller of if problems encountered + + /// Check the violation + bool checkViolation(const double* cutElem, const int* cutIndex, + int cutNz, double cutrhs, const double* xbar); + + /// Check the dynamism + bool checkDynamism(const double* cutElem, const int* cutIndex, + int cutNz); + + /// Check the support + bool checkSupport(int cutNz); + + /// Remove small coefficients and adjust the rhs accordingly + bool removeSmallCoefficients(double* cutElem, int* cutIndex, + int& cutNz, double& cutRhs); + + /// Adjust the rhs by relaxing by a small amount (relative or absolute) + void relaxRhs(double& rhs); + + /// Scale the cutting plane in different ways; + /// scaling_type possible values: + /// 0 : scale to obtain integral cut + /// 1 : scale based on norm, to obtain cut norm equal to ncol + /// 2 : scale to obtain largest coefficient equal to 1 + bool scaleCut(double* cutElem, int* cutIndex, int cutNz, + double& cutRhs, int scalingType); + + /// Scale the cutting plane in order to generate integral coefficients + bool scaleCutIntegral(double* cutElem, int* cutIndex, int cutNz, + double& cutRhs); + + /// Compute the nearest rational number; used by scale_row_integral + bool nearestRational(double val, double maxdelta, long maxdnom, + long& numerator, long& denominator); + + /// Compute the greatest common divisor + long computeGcd(long a, long b); + + /// print a vector of integers + void printvecINT(const char *vecstr, const int *x, int n) const; + /// print a vector of doubles: dense form + void printvecDBL(const char *vecstr, const double *x, int n) const; + /// print a vector of doubles: sparse form + void printvecDBL(const char *vecstr, const double *elem, const int * index, + int nz) const; + + /// Recompute the simplex tableau for want of a better accuracy. + /// Requires an empty CoinFactorization object to do the computations, + /// and two empty (already allocated) arrays which will contain + /// the basis indices on exit. Returns 0 if successfull. + int factorize(CoinFactorization & factorization, + int* colBasisIndex, int* rowBasisIndex); + + + //@} + + + // Private member data + +/**@name Private member data */ + + //@{ + + /// Object with CglGMIParam members. + CglGMIParam param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + bool *isInteger; + + /// Current basis status: columns + int *cstat; + + /// Current basis status: rows + int *rstat; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + /// Pointer on matrix of coefficient ordered by columns. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byCol; + + /// Fractionality of the cut and related quantities. + double f0; + double f0compl; + double ratiof0compl; + +#if defined(TRACK_REJECT) || defined (TRACK_REJECT_SIMPLE) + /// Should we track the reason of each cut rejection? + bool trackRejection; + /// Number of failures by type + int fracFail; + int dynFail; + int violFail; + int suppFail; + int smallCoeffFail; + int scaleFail; + /// Total number of generated cuts + int numGeneratedCuts; +#endif + + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglGMI class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglGMIUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglGMIParam.hpp b/thirdparty/linux/include/coin/coin/CglGMIParam.hpp new file mode 100644 index 0000000..a1aae41 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglGMIParam.hpp @@ -0,0 +1,313 @@ +// Name: CglGMIParam.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// email: nannicini@sutd.edu.sg +// based on CglRedSplitParam.hpp by Francois Margot +// Date: 11/17/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2009, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglGMIParam_H +#define CglGMIParam_H + +#include "CglParam.hpp" + + + /**@name CglGMI Parameters */ + //@{ + + /** Class collecting parameters for the GMI cut generator. + + Parameters of the generator are listed below. Modifying the default + values for parameters other than the last four might result in + invalid cuts. + + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - USE_INTSLACKS: Use integer slacks to generate cuts. + (not implemented yet, will be in the future). + See method setUSE_INTSLACKS(). + - AWAY: Look only at basic integer variables whose current value is at + least this value away from being integer. See method setAway(). + - CHECK_DUPLICATES: Should we check for duplicates when adding a cut + to the collection? Can be slow. + Default 0 - do not check, add cuts anyway. + - CLEAN_PROC: Cleaning procedure that should be used. Look below at the + enumeration CleaningProcedure for possible values. + - INTEGRAL_SCALE_CONT: If we try to scale cut coefficients so that + they become integral, do we also scale on + continuous variables? + Default 0 - do not scale continuous vars. + Used only if CLEAN_PROC does integral scaling. + - ENFORCE_SCALING: Discard badly scaled cuts, or keep them (unscaled). + Default 1 - yes. + + */ + //@} + +class CglGMIParam : public CglParam { + +public: + + /**@name Enumerations */ + enum CleaningProcedure{ + /* CglLandP procedure I */ + CP_CGLLANDP1, + /* CglLandP procedure II */ + CP_CGLLANDP2, + /* CglRedSplit procedure I */ + CP_CGLREDSPLIT, + /* Only integral cuts, i.e. cuts with integral coefficients */ + CP_INTEGRAL_CUTS, + /* CglLandP procedure I with integral scaling */ + CP_CGLLANDP1_INT, + /* CglLandP procedure I with scaling of the max element to 1 if possible */ + CP_CGLLANDP1_SCALEMAX, + /* CglLandP procedure I with scaling of the rhs to 1 if possible */ + CP_CGLLANDP1_SCALERHS + }; + + /**@name Set/get methods */ + + //@{ + /** Aliases for parameter get/set method in the base class CglParam */ + + /** Value for Infinity. Default: DBL_MAX */ + inline void setInfinity(double value) {setINFINIT(value);} + inline double getInfinity() const {return INFINIT;} + + /** Epsilon for comparing numbers. Default: 1.0e-6 */ + inline void setEps(double value) {setEPS(value);} + inline double getEps() const {return EPS;} + + /** Epsilon for zeroing out coefficients. Default: 1.0e-5 */ + inline void setEpsCoeff(double value) {setEPS_COEFF(value);} + inline double getEpsCoeff() const {return EPS_COEFF;} + + /** Maximum support of the cutting planes. Default: INT_MAX */ + inline void setMaxSupport(int value) {setMAX_SUPPORT(value);} + inline int getMaxSupport() const {return MAX_SUPPORT;} + /** Alias for consistency with our naming scheme */ + inline void setMaxSupportAbs(int value) {setMAX_SUPPORT(value);} + inline int getMaxSupportAbs() const {return MAX_SUPPORT;} + inline int getMAX_SUPPORT_ABS() const {return MAX_SUPPORT;} + + /** Set AWAY, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.005 */ + virtual void setAway(double value); + /** Get value of away */ + inline double getAway() const {return AWAY;} + /// Aliases + inline void setAWAY(double value) {setAway(value);} + inline double getAWAY() const {return AWAY;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 0 */ + virtual void setEPS_ELIM(double value); + /** Get the value of EPS_ELIM */ + inline double getEPS_ELIM() const {return EPS_ELIM;} + /// Aliases + inline void setEpsElim(double value) {setEPS_ELIM(value);} + inline double getEpsElim() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(double value); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + /// Aliases + inline void setEpsRelaxAbs(double value) {setEPS_RELAX_ABS(value);} + inline double getEpsRelaxAbs() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(double value); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + /// Aliases + inline void setEpsRelaxRel(double value) {setEPS_RELAX_REL(value);} + inline double getEpsRelaxRel() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN;} + /// Aliases + inline void setMaxDyn(double value) {setMAXDYN(value);} + inline double getMaxDyn() const {return MAXDYN;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-7 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + /// Aliases + inline void setMinViol(double value) {setMINVIOL(value);} + inline double getMinViol() const {return MINVIOL;} + + /** Set the value of MAX_SUPPORT_REL, the factor contributing to the + maximum support relative to the number of columns. Maximum + allowed support is: MAX_SUPPORT_ABS + + MAX_SUPPORT_REL*ncols. Default: 0.1 */ + virtual void setMAX_SUPPORT_REL(double value); + /** Get the value of MINVIOL */ + inline double getMAX_SUPPORT_REL() const {return MAX_SUPPORT_REL;} + /// Aliases + inline void setMaxSupportRel(double value) {setMAX_SUPPORT_REL(value);} + inline double getMaxSupportRel() const {return MAX_SUPPORT_REL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(bool value); + /** Get the value of USE_INTSLACKS */ + inline bool getUSE_INTSLACKS() const {return USE_INTSLACKS;} + /// Aliases + inline void setUseIntSlacks(bool value) {setUSE_INTSLACKS(value);} + inline int getUseIntSlacks() const {return USE_INTSLACKS;} + + /** Set the value of CHECK_DUPLICATES. Default: 0 */ + virtual void setCHECK_DUPLICATES(bool value); + /** Get the value of CHECK_DUPLICATES */ + inline bool getCHECK_DUPLICATES() const {return CHECK_DUPLICATES;} + /// Aliases + inline void setCheckDuplicates(bool value) {setCHECK_DUPLICATES(value);} + inline bool getCheckDuplicates() const {return CHECK_DUPLICATES;} + + /** Set the value of CLEAN_PROC. Default: CP_CGLLANDP1 */ + virtual void setCLEAN_PROC(CleaningProcedure value); + /** Get the value of CLEAN_PROC. */ + inline CleaningProcedure getCLEAN_PROC() const {return CLEAN_PROC;} + /// Aliases + inline void setCleanProc(CleaningProcedure value) {setCLEAN_PROC(value);} + inline CleaningProcedure getCleaningProcedure() const {return CLEAN_PROC;} + + /** Set the value of INTEGRAL_SCALE_CONT. Default: 0 */ + virtual void setINTEGRAL_SCALE_CONT(bool value); + /** Get the value of INTEGRAL_SCALE_CONT. */ + inline bool getINTEGRAL_SCALE_CONT() const {return INTEGRAL_SCALE_CONT;} + /// Aliases + inline void setIntegralScaleCont(bool value) {setINTEGRAL_SCALE_CONT(value);} + inline bool getIntegralScaleCont() const {return INTEGRAL_SCALE_CONT;} + + /** Set the value of ENFORCE_SCALING. Default: 1 */ + virtual void setENFORCE_SCALING(bool value); + /** Get the value of ENFORCE_SCALING. */ + inline bool getENFORCE_SCALING() const {return ENFORCE_SCALING;} + /// Aliases + inline void setEnforceScaling(bool value) {setENFORCE_SCALING(value);} + inline bool getEnforcescaling() const {return ENFORCE_SCALING;} + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGMIParam(double eps = 1e-12, + double away = 0.005, + double eps_coeff = 1e-11, + double eps_elim = 0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-4, + int max_supp_abs = 1000, + double max_supp_rel = 0.1, + CleaningProcedure clean_proc = CP_CGLLANDP1, + bool use_int_slacks = false, + bool check_duplicates = false, + bool integral_scale_cont = false, + bool enforce_scaling = true); + + /// Constructor from CglParam + CglGMIParam(CglParam &source, + double away = 0.005, + double eps_elim = 1e-12, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-4, + double max_supp_rel = 0.1, + CleaningProcedure clean_proc = CP_CGLLANDP1, + bool use_int_slacks = false, + bool check_duplicates = false, + bool integral_scale_cont = false, + bool enforce_scaling = true); + + /// Copy constructor + CglGMIParam(const CglGMIParam &source); + + /// Clone + virtual CglGMIParam* clone() const; + + /// Assignment operator + virtual CglGMIParam& operator=(const CglGMIParam &rhs); + + /// Destructor + virtual ~CglGMIParam(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Use row only if pivot variable should be integer but is more + than AWAY from being integer. */ + double AWAY; + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 0. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-11 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 1.e-13 */ + double EPS_RELAX_REL; + + /** Maximum ratio between largest and smallest non zero + coefficients in a cut. Default: 1e6. */ + double MAXDYN; + + /** Minimum violation for the current basic solution in a generated cut. + Default: 1e-4. */ + double MINVIOL; + + /** Maximum support relative to number of columns. Must be between 0 + and 1. Default: 0. */ + double MAX_SUPPORT_REL; + + /** Which cleaning procedure should be used? */ + CleaningProcedure CLEAN_PROC; + + /** Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. */ + bool USE_INTSLACKS; + + /** Check for duplicates when adding the cut to the collection? */ + bool CHECK_DUPLICATES; + + /** Should we try to rescale cut coefficients on continuous variables + so that they become integral, or do we only rescale coefficients + on integral variables? Used only by cleaning procedure that try + the integral scaling. */ + bool INTEGRAL_SCALE_CONT; + + /** Should we discard badly scaled cuts (according to the scaling + procedure in use)? If false, CglGMI::scaleCut always returns + true, even though it still scales cuts whenever possible, but + not cut is rejected for scaling. Default true. Used only by + cleaning procedure that try to scale. */ + bool ENFORCE_SCALING; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglGomory.hpp b/thirdparty/linux/include/coin/coin/CglGomory.hpp new file mode 100644 index 0000000..2d7f5c5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglGomory.hpp @@ -0,0 +1,204 @@ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglGomory_H +#define CglGomory_H + +#include <string> + +#include "CglCutGenerator.hpp" + +class CoinWarmStartBasis; +/** Gomory Cut Generator Class */ +class CglGomory : public CglCutGenerator { + friend void CglGomoryUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Gomory cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + There is a limit option, which will only generate cuts with + less than this number of entries. + + We can also only look at 0-1 variables a certain distance + from integer. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /** Generates cuts given matrix and solution etc, + returns number of cuts generated */ + int generateCuts( const OsiRowCutDebugger * debugger, + OsiCuts & cs, + const CoinPackedMatrix & columnCopy, + const CoinPackedMatrix & rowCopy, + const double * colsol, + const double * colLower, const double * colUpper, + const double * rowLower, const double * rowUpper, + const char * intVar , + const CoinWarmStartBasis* warm, + const CglTreeInfo info = CglTreeInfo()); + /** Generates cuts given matrix and solution etc, + returns number of cuts generated (no row copy passed in) */ + int generateCuts( const OsiRowCutDebugger * debugger, + OsiCuts & cs, + const CoinPackedMatrix & columnCopy, + const double * colsol, + const double * colLower, const double * colUpper, + const double * rowLower, const double * rowUpper, + const char * intVar , + const CoinWarmStartBasis* warm, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const { return true; } + //@} + + /**@name Change way Gomory works */ + //@{ + /// Pass in a copy of original solver (clone it) + void passInOriginalSolver(OsiSolverInterface * solver); + /// Returns original solver + inline OsiSolverInterface * originalSolver() const + { return originalSolver_;} + /// Set type - 0 normal, 1 add original matrix one, 2 replace + inline void setGomoryType(int type) + { gomoryType_=type;} + /// Return type + inline int gomoryType() const + { return gomoryType_;} + //@} + + /**@name Change limit on how many variables in cut (default 50) */ + //@{ + /// Set + void setLimit(int limit); + /// Get + int getLimit() const; + /// Set at root (if <normal then use normal) + void setLimitAtRoot(int limit); + /// Get at root + int getLimitAtRoot() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const; + //@} + + /**@name Change criterion on which variables to look at. All ones + more than "away" away from integrality will be investigated + (default 0.05) */ + //@{ + /// Set away + void setAway(double value); + /// Get away + double getAway() const; + /// Set away at root + void setAwayAtRoot(double value); + /// Get away at root + double getAwayAtRoot() const; + //@} + + /**@name Change criterion on which the cut id relaxed if the code + thinks the factorization has inaccuracies. The relaxation to + RHS is smallest of - + 1) 1.0e-4 + 2) conditionNumberMultiplier * condition number of factorization + 3) largestFactorMultiplier * largest (dual*element) forming tableau + row + */ + //@{ + /// Set ConditionNumberMultiplier + void setConditionNumberMultiplier(double value); + /// Get ConditionNumberMultiplier + double getConditionNumberMultiplier() const; + /// Set LargestFactorMultiplier + void setLargestFactorMultiplier(double value); + /// Get LargestFactorMultiplier + double getLargestFactorMultiplier() const; + //@} + + /**@name change factorization */ + //@{ + /// Set/unset alternative factorization + inline void useAlternativeFactorization(bool yes=true) + { alternateFactorization_= (yes) ? 1 : 0;} + /// Get whether alternative factorization being used + inline bool alternativeFactorization() const + { return (alternateFactorization_!=0);} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGomory (); + + /// Copy constructor + CglGomory ( + const CglGomory &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglGomory & + operator=( + const CglGomory& rhs); + + /// Destructor + virtual + ~CglGomory (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + // Private member data + + /**@name Private member data */ + //@{ + /// Only investigate if more than this away from integrality + double away_; + /// Only investigate if more than this away from integrality (at root) + double awayAtRoot_; + /// Multiplier for conditionNumber cut relaxation + double conditionNumberMultiplier_; + /// Multiplier for largest factor cut relaxation + double largestFactorMultiplier_; + /// Original solver + OsiSolverInterface * originalSolver_; + /// Limit - only generate if fewer than this in cut + int limit_; + /// Limit - only generate if fewer than this in cut (at root) + int limitAtRoot_; + /// Dynamic limit in tree + int dynamicLimitInTree_; + /// Number of times stalled + int numberTimesStalled_; + /// nonzero to use alternative factorization + int alternateFactorization_; + /// Type - 0 normal, 1 add original matrix one, 2 replace + int gomoryType_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglGomory class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglGomoryUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglKnapsackCover.hpp b/thirdparty/linux/include/coin/coin/CglKnapsackCover.hpp new file mode 100644 index 0000000..b0e81d6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglKnapsackCover.hpp @@ -0,0 +1,310 @@ +// $Id: CglKnapsackCover.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglKnapsackCover_H +#define CglKnapsackCover_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CglTreeInfo.hpp" + +/** Knapsack Cover Cut Generator Class */ +class CglKnapsackCover : public CglCutGenerator { + friend void CglKnapsackCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + /** A method to set which rows should be tested for knapsack covers */ + void setTestedRowIndices(int num, const int* ind); + + /**@name Generate Cuts */ + //@{ + /** Generate knapsack cover cuts for the model of the solver interface, si. + Insert the generated cuts into OsiCut, cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglKnapsackCover (); + + /// Copy constructor + CglKnapsackCover ( + const CglKnapsackCover &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglKnapsackCover & + operator=( + const CglKnapsackCover& rhs); + + /// Destructor + virtual + ~CglKnapsackCover (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + + + /**@name Sets and gets */ + //@{ + /// Set limit on number in knapsack + inline void setMaxInKnapsack(int value) + { if (value>0) maxInKnapsack_ = value;} + /// get limit on number in knapsack + inline int getMaxInKnapsack() const + {return maxInKnapsack_;} + /// Switch off expensive cuts + inline void switchOffExpensive() + { expensiveCuts_=false;} + /// Switch on expensive cuts + inline void switchOnExpensive() + { expensiveCuts_=true;} +private: + + // Private member methods + + + /**@name Private methods */ + //@{ + + /** deriveAKnapsack + returns 1 if it is able to derive + a (canonical) knapsack inequality + in binary variables of the form ax<=b + from the rowIndex-th row in the model, + returns 0 otherwise. + */ + int deriveAKnapsack( + const OsiSolverInterface & si, + OsiCuts & cs, + CoinPackedVector & krow, + bool treatAsLRow, + double & b, + int * complement, + double * xstar, + int rowIndex, + int numberElements, + const int * index, + const double * element); + + int deriveAKnapsack( + const OsiSolverInterface & si, + OsiCuts & cs, + CoinPackedVector & krow, + double & b, + int * complement, + double * xstar, + int rowIndex, + const CoinPackedVectorBase & matrixRow); + + /** Find a violated minimal cover from + a canonical form knapsack inequality by + solving the -most- violated cover problem + and postprocess to ensure minimality + */ + int findExactMostViolatedMinCover( + int nCols, + int row, + CoinPackedVector & krow, + double b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + + /** Find the most violate minimum cover by solving the lp-relaxation of the + most-violate-min-cover problem + */ + int findLPMostViolatedMinCover( + int nCols, + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + +/// find a minimum cover by a simple greedy approach + int findGreedyCover( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder + ); + + /// lift the cover inequality + int liftCoverCut( + double & b, + int nRowElem, + CoinPackedVector & cover, + CoinPackedVector & remainder, + CoinPackedVector & cut ); + + /// sequence-independent lift and uncomplement and add the resulting cut to the cut set + int liftAndUncomplementAndAdd( + double rowub, + CoinPackedVector & krow, + double & b, + int * complement, + int row, + CoinPackedVector & cover, + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// sequence-dependent lift, uncomplement and add the resulting cut to the cut set +void seqLiftAndUncomplementAndAdd( + int nCols, + double * xstar, + int * complement, + int row, + int nRowElem, + double & b, + CoinPackedVector & cover, // need not be violated + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// sequence-dependent lift binary variables either up or down, uncomplement and add to the cut set +void liftUpDownAndUncomplementAndAdd( + int nCols, + double * xstar, + int * complement, + int row, + int nRowElem, + double & b, + + // the following 3 packed vectors partition the krow: + CoinPackedVector & fracCover, // vars have frac soln values in lp relaxation + // and form cover with the vars atOne + CoinPackedVector & atOne, // vars have soln value of 1 in lp relaxation + // and together with fracCover form minimal (?) cover. + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// find a cover using a variation of the logic found in OSL (w/o SOS) + int findPseudoJohnAndEllisCover ( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + + /// find a cover using the basic logic found in OSL (w/o SOS) + int findJohnAndEllisCover ( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & fracCover, + CoinPackedVector & atOnes, + CoinPackedVector & remainder); + + + /** A C-style implementation of the Horowitz-Sahni exact solution + procedure for solving knapsack problem. + + (ToDo: implement the more efficient dynamic programming approach) + + (Reference: Martello and Toth, Knapsack Problems, Wiley, 1990, p30.) + */ + int exactSolveKnapsack( + int n, + double c, + double const *pp, + double const *ww, + double & z, + int * x); + /// For testing gub stuff + int gubifyCut(CoinPackedVector & cut); +public: + /** Creates cliques for use by probing. + Only cliques >= minimumSize and < maximumSize created + Can also try and extend cliques as a result of probing (root node). + Returns number of cliques found. + */ + int createCliques( OsiSolverInterface & si, + int minimumSize=2, int maximumSize=100, bool extendCliques=false); +private: + /// Delete all clique information + void deleteCliques(); + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// epsilon + double epsilon_; + /// Tolerance to use for violation - bigger than epsilon_ + double epsilon2_; + /// 1-epsilon + double onetol_; + /// Maximum in knapsack + int maxInKnapsack_; + /** which rows to look at. If specified, only these rows will be considered + for generating knapsack covers. Otherwise all rows will be tried */ + int numRowsToCheck_; + int* rowsToCheck_; + /// exactKnapsack can be expensive - this switches off some + bool expensiveCuts_; + /// Cliques + /// **** TEMP so can reference from listing + const OsiSolverInterface * solver_; + int whichRow_; + int * complement_; + double * elements_; + /// Number of cliques + int numberCliques_; + /// Clique type + typedef struct { + unsigned int equality:1; // nonzero if clique is == + } CliqueType; + CliqueType * cliqueType_; + /// Start of each clique + int * cliqueStart_; + /// Entries for clique + CliqueEntry * cliqueEntry_; + /** Start of oneFixes cliques for a column in matrix or -1 if not + in any clique */ + int * oneFixStart_; + /** Start of zeroFixes cliques for a column in matrix or -1 if not + in any clique */ + int * zeroFixStart_; + /// End of fixes for a column + int * endFixStart_; + /// Clique numbers for one or zero fixes + int * whichClique_; + /// Number of columns + int numberColumns_; + /** For each column with nonzero in row copy this gives a clique "number". + So first clique mentioned in row is always 0. If no entries for row + then no cliques. If sequence > numberColumns then not in clique. + */ + //CliqueEntry * cliqueRow_; + /// cliqueRow_ starts for each row + //int * cliqueRowStart_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglKnapsackCover class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglKnapsackCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglLandP.hpp b/thirdparty/linux/include/coin/coin/CglLandP.hpp new file mode 100644 index 0000000..64447e7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglLandP.hpp @@ -0,0 +1,306 @@ +// Copyright (C) 2005-2009, Pierre Bonami and others. All Rights Reserved. +// Author: Pierre Bonami +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// Date: 07/21/05 +// +// $Id: CglLandP.hpp 1122 2013-04-06 20:39:53Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//--------------------------------------------------------------------------- +#ifndef CglLandP_H +#define CglLandP_H + +#include "CglLandPValidator.hpp" +#include "CglCutGenerator.hpp" +#include "CglParam.hpp" + +#include <iostream> +class CoinWarmStartBasis; +/** Performs one round of Lift & Project using CglLandPSimplex + to build cuts +*/ + +namespace LAP +{ +enum LapMessagesTypes +{ + BEGIN_ROUND, + END_ROUND, + DURING_SEP, + CUT_REJECTED, + CUT_FAILED, + CUT_GAP, + LAP_CUT_FAILED_DO_MIG, + LAP_MESSAGES_DUMMY_END +}; +/** Output messages for Cgl */ +class LapMessages : public CoinMessages +{ +public: + /** Constructor */ + LapMessages( ); + /** destructor.*/ + virtual ~LapMessages() {} +}; +class CglLandPSimplex; +} + +class CglLandP : public CglCutGenerator +{ + friend void CglLandPUnitTest(OsiSolverInterface *si, const std::string & mpsDir); + + friend class LAP::CglLandPSimplex; + friend class CftCglp; + +public: + + enum SelectionRules + { + mostNegativeRc /** select most negative reduced cost */, + bestPivot /** select best possible pivot.*/, + initialReducedCosts/** Select only those rows which had initialy a 0 reduced cost.*/ + }; + + enum ExtraCutsMode + { + none/** Generate no extra cuts.*/, + AtOptimalBasis /** Generate cuts from the optimal basis.*/, + WhenEnteringBasis /** Generate cuts as soon as a structural enters the basis.*/, + AllViolatedMigs/** Generate all violated Mixed integer Gomory cuts in the course of the optimization.*/ + }; + + /** Space where cuts are optimized.*/ + enum SeparationSpaces + { + Fractional=0 /** True fractional space.*/, + Fractional_rc/** Use fractional space only for computing reduced costs.*/, + Full /** Work in full space.*/ + }; + + /** Normalization */ + enum Normalization + { + Unweighted = 0, + WeightRHS, + WeightLHS, + WeightBoth + }; + + enum LHSnorm + { + L1 = 0, + L2, + SupportSize, + Infinity, + Average, + Uniform + }; + /** RHS weight in normalization.*/ + enum RhsWeightType + { + Fixed = 0 /** 2*initial number of constraints. */, + Dynamic /** 2 * current number of constraints. */ + }; + /** Class storing parameters. + \remark I take all parameters from Ionut's code */ + class Parameters : public CglParam + { + public: + /** Default constructor (with default values)*/ + Parameters(); + /** Copy constructor */ + Parameters(const Parameters &other); + /** Assignment opertator */ + Parameters & operator=(const Parameters &other); + /// @name integer parameters + ///@{ + + /** Max number of pivots before we generate the cut + \default 20 */ + int pivotLimit; + /** Max number of pivots at regular nodes. Put a value if you want it lower than the global pivot limit. + \default 100.*/ + int pivotLimitInTree; + /** Maximum number of cuts generated at a given round*/ + int maxCutPerRound; + /** Maximum number of failed pivots before aborting */ + int failedPivotLimit; + /** maximum number of consecutive degenerate pivots + \default 0 */ + int degeneratePivotLimit; + /** Maximum number of extra rows to generate per round.*/ + int extraCutsLimit; + ///@} + /// @name double parameters + ///@{ + /** Tolerance for small pivots values (should be the same as the solver */ + double pivotTol; + /** A variable have to be at least away from integrity to be generated */ + double away; + /** Total time limit for cut generation.*/ + double timeLimit; + /** Time limit for generating a single cut.*/ + double singleCutTimeLimit; + /** Weight to put in RHS of normalization if static.*/ + double rhsWeight; + ///@} + + /// @name Flags + ///@{ + /** Do we use tableau row or the disjunction (I don't really get that there should be a way to always use the tableau)*/ + bool useTableauRow; + /** Do we apply Egon Balas's Heuristic for modularized cuts */ + bool modularize; + /** Do we strengthen the final cut (always do if modularize is 1) */ + bool strengthen; + /** Wether to limit or not the number of mistaken RC (when perturbation is applied).*/ + bool countMistakenRc; + /** Work in the reduced space (only non-structurals enter the basis) */ + SeparationSpaces sepSpace; + /** Apply perturbation procedure. */ + bool perturb; + /** How to weight normalization.*/ + Normalization normalization; + /** How to weight RHS of normalization.*/ + RhsWeightType rhsWeightType; + /** How to weight LHS of normalization.*/ + LHSnorm lhs_norm; + /** Generate extra constraints from optimal lift-and-project basis.*/ + ExtraCutsMode generateExtraCuts; + /** Which rule to apply for choosing entering and leaving variables.*/ + SelectionRules pivotSelection; + ///@} + }; + + + /** Constructor for the class*/ + CglLandP(const CglLandP::Parameters ¶ms = CglLandP::Parameters(), + const LAP::Validator &validator = LAP::Validator()); + /** Destructor */ + ~CglLandP(); + /** Copy constructor */ + CglLandP(const CglLandP &source); + /** Assignment operator */ + CglLandP& operator=(const CglLandP &rhs); + /** Clone function */ + CglCutGenerator * clone() const; + + /**@name Generate Cuts */ + //@{ + + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + //@} + + virtual bool needsOptimalBasis() const + { + return true; + } + + LAP::Validator & validator() + { + return validator_; + } + /** set level of log for cut generation procedure : + <ol start=0 > + <li> for none </li> + <li> for log at begin and end of procedure + at some time interval </li> + <li> for log at every cut generated </li> + </ol> + */ + void setLogLevel(int level) + { + handler_->setLogLevel(level); + } + + class NoBasisError : public CoinError + { + public: + NoBasisError(): CoinError("No basis available","LandP","") {} + }; + + class SimplexInterfaceError : public CoinError + { + public: + SimplexInterfaceError(): CoinError("Invalid conversion to simplex interface", "CglLandP","CglLandP") {} + }; + Parameters & parameter() + { + return params_; + } +private: + + + void scanExtraCuts(OsiCuts& cs, const double * colsol) const; + + Parameters params_; + + /** Some informations that will be changed by the pivots and that we want to keep*/ + struct CachedData + { + CachedData(int nBasics = 0 , int nNonBasics = 0); + CachedData(const CachedData & source); + + CachedData& operator=(const CachedData &source); + /** Get the data from a problem */ + void getData(const OsiSolverInterface &si); + + void clean(); + + ~CachedData(); + /** Indices of basic variables in starting basis (ordered if variable basics_[i] s basic in row i)*/ + int * basics_; + /** Indices of non-basic variables */ + int *nonBasics_; + /** number of basics variables */ + int nBasics_; + /** number of non-basics */ + int nNonBasics_; + /** Optimal basis */ + CoinWarmStartBasis * basis_; + /** Stores the value of the solution to cut */ + double * colsol_; + /** Stores the values of the slacks */ + double * slacks_; + /** Stores wheter slacks are integer constrained */ + bool * integers_; + /** Solver before pivots */ + OsiSolverInterface * solver_; + }; + /** Retrieve sorted integer variables which are fractional in the solution. + Return the number of variables.*/ + int getSortedFractionals(CoinPackedVector &xFrac, + const CachedData & data, + const CglLandP::Parameters& params) const; + /** Retrieve sorted integer variables which are fractional in the solution. + Return the number of variables.*/ + void getSortedFractionalIndices(std::vector<int>& indices, + const CachedData &data, + const CglLandP::Parameters & params) const; + /** Cached informations about problem.*/ + CachedData cached_; + /** message handler */ + CoinMessageHandler * handler_; + /** messages */ + CoinMessages messages_; + /** cut validator */ + LAP::Validator validator_; + /** number of rows in the original problems. */ + int numrows_; + /** number of columns in the original problems. */ + int numcols_; + /** Original lower bounds for the problem (for lifting cuts).*/ + double * originalColLower_; + /** Original upper bounds for the problem (for lifting cuts).*/ + double * originalColUpper_; + /** Flag to say if cuts can be lifted.*/ + bool canLift_; + /** Store some extra cut which could be cheaply generated but do not cut current incumbent.*/ + OsiCuts extraCuts_; +}; +void CglLandPUnitTest(OsiSolverInterface *si, const std::string & mpsDir); + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CglLandPValidator.hpp b/thirdparty/linux/include/coin/coin/CglLandPValidator.hpp new file mode 100644 index 0000000..b9e363d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglLandPValidator.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2005-2009, Pierre Bonami and others. All Rights Reserved. +// Author: Pierre Bonami +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// Date: 11/22/05 +// +// $Id: CglLandPValidator.hpp 1302 2015-08-14 15:48:32Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//--------------------------------------------------------------------------- + +#ifndef CglLandPValidator_H +#define CglLandPValidator_H +#include "OsiSolverInterface.hpp" +#include "CglParam.hpp" +#include <vector> + +/** constants describing rejection codes*/ +//[5] = {"Accepted", "violation too small", "small coefficient too small", "big dynamic","too dense"} + + +namespace LAP +{ + +/** Class to validate or reject a cut */ +class Validator +{ +public: + /** Reasons for rejecting a cut */ + enum RejectionsReasons + { + NoneAccepted=0 /**Cut was accepted*/, + SmallViolation /** Violation of the cut is too small */, + SmallCoefficient /** There is a small coefficient we can not get rid off.*/, + BigDynamic /** Dynamic of coefficinet is too important. */, + DenseCut/**cut is too dense */, + EmptyCut/**After cleaning cut has become empty*/, + DummyEnd/** dummy*/ + }; + + /** Constructor with default values */ + Validator(double maxFillIn = 1., + double maxRatio = 1e8, + double minViolation = 0, + bool scale = false, + double rhsScale = 1); + + /** Clean an OsiCut */ + int cleanCut(OsiRowCut & aCut, const double * solCut,const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper); + /** Clean an OsiCut by another method */ + int cleanCut2(OsiRowCut & aCut, const double * solCut, const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper); + /** Call the cut cleaner */ + int operator()(OsiRowCut & aCut, const double * solCut,const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper) + { + return cleanCut(aCut, solCut, si, par, colLower, colUpper); + } + /** @name set functions */ + /** @{ */ + void setMaxFillIn(double value) + { + maxFillIn_ = value; + } + void setMaxRatio(double value) + { + maxRatio_ = value; + } + void setMinViolation(double value) + { + minViolation_ = value; + } + + void setRhsScale(double v) + { + rhsScale_ = v; + } + /** @} */ + /** @name get functions */ + /** @{ */ + double getMaxFillIn() + { + return maxFillIn_; + } + double getMaxRatio() + { + return maxRatio_; + } + double getMinViolation() + { + return minViolation_; + } + /** @} */ + + const char* failureString(RejectionsReasons code) const + { + return rejections_[static_cast<int> (code)]; + } + const char* failureString(int code) const + { + return rejections_[ code]; + } + int numRejected(RejectionsReasons code)const + { + return numRejected_[static_cast<int> (code)]; + } + int numRejected(int code)const + { + return numRejected_[ code]; + } +private: + /** max percentage of given formulation fillIn should be accepted for cut fillin.*/ + double maxFillIn_; + /** max ratio between smallest and biggest coefficient */ + double maxRatio_; + /** minimum violation for accepting a cut */ + double minViolation_; + /** Do we do scaling? */ + bool scale_; + /** Scale of right-hand-side.*/ + double rhsScale_; + /** Strings explaining reason for rejections */ + static const char* rejections_[DummyEnd]; + /** Number of cut rejected for each of the reasons.*/ + std::vector<int> numRejected_; +}; + +}/* Ends namespace LAP.*/ +#endif diff --git a/thirdparty/linux/include/coin/coin/CglLiftAndProject.hpp b/thirdparty/linux/include/coin/coin/CglLiftAndProject.hpp new file mode 100644 index 0000000..364ba5a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglLiftAndProject.hpp @@ -0,0 +1,104 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglLiftAndProject_H +#define CglLiftAndProject_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** Lift And Project Cut Generator Class */ +class CglLiftAndProject : public CglCutGenerator { + friend void CglLiftAndProjectUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + /**@name Generate Cuts */ + //@{ + /** Generate lift-and-project cuts for the + model of the solver interface, si. + Insert the generated cuts into OsiCut, cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /** Get the normalization : Either beta=+1 or beta=-1. + */ + + double getBeta() const { + return beta_; + } + + /** Set the normalization : Either beta=+1 or beta=-1. + Default value is 1. + */ + void setBeta(int oneOrMinusOne){ + if (oneOrMinusOne==1 || oneOrMinusOne==-1){ + beta_= static_cast<double>(oneOrMinusOne); + } + else { + throw CoinError("Unallowable value. Beta must be 1 or -1", + "cutGeneration","CglLiftAndProject"); + } + } + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglLiftAndProject (); + + /// Copy constructor + CglLiftAndProject ( + const CglLiftAndProject &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglLiftAndProject & + operator=( + const CglLiftAndProject& rhs); + + /// Destructor + virtual + ~CglLiftAndProject (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// The normalization is beta_=1 or beta_=-1 + double beta_; + /// epsilon + double epsilon_; + /// 1-epsilon + double onetol_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglLiftAndProject class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglLiftAndProjectUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglMessage.hpp b/thirdparty/linux/include/coin/coin/CglMessage.hpp new file mode 100644 index 0000000..5f080e8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglMessage.hpp @@ -0,0 +1,50 @@ +// $Id: CglMessage.hpp 1105 2013-03-19 12:43:52Z forrest $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglMessage_H +#define CglMessage_H + + +#include "CoinPragma.hpp" + +// This deals with Cgl messages (as against Osi messages etc) + +#include "CoinMessageHandler.hpp" +enum CGL_Message +{ + CGL_INFEASIBLE, + CGL_CLIQUES, + CGL_FIXED, + CGL_PROCESS_STATS, + CGL_SLACKS, + CGL_PROCESS_STATS2, + CGL_PROCESS_SOS1, + CGL_PROCESS_SOS2, + CGL_UNBOUNDED, + CGL_ELEMENTS_CHANGED1, + CGL_ELEMENTS_CHANGED2, + CGL_MADE_INTEGER, + CGL_ADDED_INTEGERS, + CGL_POST_INFEASIBLE, + CGL_POST_CHANGED, + CGL_GENERAL, + CGL_DUMMY_END +}; + +/** This deals with Cgl messages (as against Osi messages etc) + */ +class CglMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + CglMessage(Language language=us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding.hpp b/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding.hpp new file mode 100644 index 0000000..10580cb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding.hpp @@ -0,0 +1,429 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// name: Mixed Integer Rounding Cut Generator +// authors: Joao Goncalves (jog7@lehigh.edu) +// Laszlo Ladanyi (ladanyi@us.ibm.com) +// date: August 11, 2004 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglMixedIntegerRounding_H +#define CglMixedIntegerRounding_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + +// Class to store variable upper bounds (VUB) +class CglMixIntRoundVUB +{ + // Variable upper bounds have the form x_j <= a y_j, where x_j is + // a continuous variable and y_j is an integer variable + +protected: + int var_; // The index of y_j + double val_; // The value of a + +public: + // Default constructor + CglMixIntRoundVUB() : var_(-1), val_(-1) {} + + // Copy constructor + CglMixIntRoundVUB(const CglMixIntRoundVUB& source) { + var_ = source.var_; + val_ = source.val_; + } + + // Assignment operator + CglMixIntRoundVUB& operator=(const CglMixIntRoundVUB& rhs) { + if (this != &rhs) { + var_ = rhs.var_; + val_ = rhs.val_; + } + return *this; + } + + // Destructor + ~CglMixIntRoundVUB() {} + + // Query and set functions + int getVar() const { return var_; } + double getVal() const { return val_; } + void setVar(const int v) { var_ = v; } + void setVal(const double v) { val_ = v; } +}; + +//============================================================================= + +// Class to store variable lower bounds (VLB). +// It is the same as the class to store variable upper bounds +typedef CglMixIntRoundVUB CglMixIntRoundVLB; + +//============================================================================= + +/** Mixed Integer Rounding Cut Generator Class */ + +// Reference: +// Hugues Marchand and Laurence A. Wolsey +// Aggregation and Mixed Integer Rounding to Solve MIPs +// Operations Research, 49(3), May-June 2001. +// Also published as CORE Dicusion Paper 9839, June 1998. + +class CglMixedIntegerRounding : public CglCutGenerator { + + friend void CglMixedIntegerRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + // The row type of this row is NOT defined yet. + ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARUB, + /** After the row is flipped to 'L', the row has exactly two variables: + one is positive binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + ROW_VAREQ, + // The row contains continuous and integer variables; + // the total number of variables is at least 2 + ROW_MIX, + // The row contains only continuous variables + ROW_CONT, + // The row contains only integer variables + ROW_INT, + // The row contains other types of rows + ROW_OTHER + }; + + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Rounding cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglMixedIntegerRounding (); + + /// Alternate Constructor + CglMixedIntegerRounding (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc = -1); + + /// Copy constructor + CglMixedIntegerRounding ( + const CglMixedIntegerRounding &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglMixedIntegerRounding & + operator=( + const CglMixedIntegerRounding& rhs); + + /// Destructor + virtual + ~CglMixedIntegerRounding (); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + + //--------------------------------------------------------------------------- + /**@name Set and get methods */ + //@{ + /// Set MAXAGGR_ + inline void setMAXAGGR_ (int maxaggr) { + if (maxaggr > 0) { + MAXAGGR_ = maxaggr; + } + else { + throw CoinError("Unallowable value. maxaggr must be > 0", + "gutsOfConstruct","CglMixedIntegerRounding"); + } + } + + /// Get MAXAGGR_ + inline int getMAXAGGR_ () const { return MAXAGGR_; } + + /// Set MULTIPLY_ + inline void setMULTIPLY_ (bool multiply) { MULTIPLY_ = multiply; } + + /// Get MULTIPLY_ + inline bool getMULTIPLY_ () const { return MULTIPLY_; } + + /// Set CRITERION_ + inline void setCRITERION_ (int criterion) { + if ((criterion >= 1) && (criterion <= 3)) { + CRITERION_ = criterion; + } + else { + throw CoinError("Unallowable value. criterion must be 1, 2 or 3", + "gutsOfConstruct","CglMixedIntegerRounding"); + } + } + + /// Get CRITERION_ + inline int getCRITERION_ () const { return CRITERION_; } + + + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + + //@} + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglMixedIntegerRounding& rhs); + + // Do preprocessing. + // It determines the type of each row. It also identifies the variable + // upper bounds and variable lower bounds. + // It may change sense and RHS for ranged rows + void mixIntRoundPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs) const; + + // Generate MIR cuts + void generateMirCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + const double* coefByRow, + const int* colInds, + const int* rowStarts, + const int* rowLengths, + //const CoinPackedMatrix& matrixByCol, + const double* coefByCol, + const int* rowInds, + const int* colStarts, + const int* colLengths, + OsiCuts& cs ) const; + + // Copy row selected to CoinPackedVector + void copyRowSelected( const int iAggregate, + const int rowSelected, + std::set<int>& setRowsAggregated, + int* listRowsAggregated, + double* xlpExtra, + const char sen, + const double rhs, + const double lhs, + const CoinPackedMatrix& matrixByRow, + CoinPackedVector& rowToAggregate, + double& rhsToAggregate) const; + + // Select a row to aggregate + bool selectRowToAggregate( const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double* colUpperBound, + const double* colLowerBound, + const std::set<int>& setRowsAggregated, + const double* xlp, const double* coefByCol, + const int* rowInds, const int* colStarts, + const int* colLengths, + int& rowSelected, + int& colSelected ) const; + + // Aggregation heuristic. + // Combines one or more rows of the original matrix + void aggregateRow( const int colSelected, + CoinPackedVector& rowToAggregate, double rhs, + CoinPackedVector& rowAggregated, + double& rhsAggregated ) const; + + // Choose the bound substitution based on the criteria defined by the user + inline bool isLowerSubst(const double inf, + const double aj, + const double xlp, + const double LB, + const double UB) const; + + // Bound substitution heuristic + bool boundSubstitution( const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double* xlp, + const double* xlpExtra, + const double* colUpperBound, + const double* colLowerBound, + CoinPackedVector& mixedKnapsack, + double& rhsMixedKnapsack, double& sStar, + CoinPackedVector& contVariablesInS ) const; + + // c-MIR separation heuristic + bool cMirSeparation ( const OsiSolverInterface& si, + const CoinPackedMatrix& matrixByRow, + const CoinPackedVector& rowAggregated, + const int* listRowsAggregated, + const char* sense, const double* RHS, + //const double* coefByRow, + //const int* colInds, const int* rowStarts, + //const int* rowLengths, + const double* xlp, const double sStar, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedVector& mixedKnapsack, + const double& rhsMixedKnapsack, + const CoinPackedVector& contVariablesInS, + OsiRowCut& flowCut ) const; + + // function to create one c-MIR inequality + void cMirInequality( const int numInt, + const double delta, + const double numeratorBeta, + const int *knapsackIndices, + const double* knapsackElements, + const double* xlp, + const double sStar, + const double* colUpperBound, + const std::set<int>& setC, + CoinPackedVector& cMIR, + double& rhscMIR, + double& sCoef, + double& violation) const; + + // function to compute G + inline double functionG( const double d, const double f ) const; + + // function to print statistics (used only in debug mode) + void printStats( + std::ofstream & fout, + const bool hasCut, + const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double& rhsAggregated, const double* xlp, + const double* xlpExtra, + const int* listRowsAggregated, + const int* listColsSelected, + const int level, + const double* colUpperBound, + const double* colLowerBound ) const; + + +private: + //--------------------------------------------------------------------------- + // Private member data + + // Maximum number of rows to aggregate + int MAXAGGR_; + // Flag that indicates if an aggregated row is also multiplied by -1 + bool MULTIPLY_; + // The criterion to use in the bound substitution + int CRITERION_; + // Tolerance used for numerical purposes + double EPSILON_; + /// There is no variable upper bound or variable lower bound defined + int UNDEFINED_; + // If violation of a cut is greater that this number, the cut is accepted + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // The array of CglMixIntRoundVUBs. + CglMixIntRoundVUB* vubs_; + // The array of CglMixIntRoundVLBs. + CglMixIntRoundVLB* vlbs_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // The number of rows of type ROW_MIX + int numRowMix_; + // The indices of the rows of type ROW_MIX + int* indRowMix_; + // The number of rows of type ROW_CONT + int numRowCont_; + // The indices of the rows of type ROW_CONT + int* indRowCont_; + // The number of rows of type ROW_INT + int numRowInt_; + // The indices of the rows of type ROW_INT + int* indRowInt_; + // The number of rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int numRowContVB_; + // The indices of the rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int* indRowContVB_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + +}; + +//############################################################################# +// A function that tests the methods in the CglMixedIntegerRounding class. The +// only reason for it not to be a member method is that this way it doesn't +// have to be compiled into the library. And that's a gain, because the +// library should be compiled with optimization on, but this method should be +// compiled with debugging. +void CglMixedIntegerRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding2.hpp b/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding2.hpp new file mode 100644 index 0000000..abf2530 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglMixedIntegerRounding2.hpp @@ -0,0 +1,427 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// name: Mixed Integer Rounding Cut Generator +// authors: Joao Goncalves (jog7@lehigh.edu) +// Laszlo Ladanyi (ladanyi@us.ibm.com) +// date: August 11, 2004 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglMixedIntegerRounding2_H +#define CglMixedIntegerRounding2_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" +#include "CoinIndexedVector.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + +// Class to store variable upper bounds (VUB) +class CglMixIntRoundVUB2 +{ + // Variable upper bounds have the form x_j <= a y_j, where x_j is + // a continuous variable and y_j is an integer variable + +protected: + int var_; // The index of y_j + double val_; // The value of a + +public: + // Default constructor + CglMixIntRoundVUB2() : var_(-1), val_(-1) {} + + // Copy constructor + CglMixIntRoundVUB2(const CglMixIntRoundVUB2& source) { + var_ = source.var_; + val_ = source.val_; + } + + // Assignment operator + CglMixIntRoundVUB2& operator=(const CglMixIntRoundVUB2& rhs) { + if (this != &rhs) { + var_ = rhs.var_; + val_ = rhs.val_; + } + return *this; + } + + // Destructor + ~CglMixIntRoundVUB2() {} + + // Query and set functions + int getVar() const { return var_; } + double getVal() const { return val_; } + void setVar(const int v) { var_ = v; } + void setVal(const double v) { val_ = v; } +}; + +//============================================================================= + +// Class to store variable lower bounds (VLB). +// It is the same as the class to store variable upper bounds +typedef CglMixIntRoundVUB2 CglMixIntRoundVLB2; + +//============================================================================= + +/** Mixed Integer Rounding Cut Generator Class */ + +// Reference: +// Hugues Marchand and Laurence A. Wolsey +// Aggregation and Mixed Integer Rounding to Solve MIPs +// Operations Research, 49(3), May-June 2001. +// Also published as CORE Dicusion Paper 9839, June 1998. + +class CglMixedIntegerRounding2 : public CglCutGenerator { + + friend void CglMixedIntegerRounding2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + // The row type of this row is NOT defined yet. + ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARUB, + /** After the row is flipped to 'L', the row has exactly two variables: + one is positive binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + ROW_VAREQ, + // The row contains continuous and integer variables; + // the total number of variables is at least 2 + ROW_MIX, + // The row contains only continuous variables + ROW_CONT, + // The row contains only integer variables + ROW_INT, + // The row contains other types of rows + ROW_OTHER + }; + + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Rounding cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglMixedIntegerRounding2 (); + + /// Alternate Constructor + CglMixedIntegerRounding2 (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc = -1); + + /// Copy constructor + CglMixedIntegerRounding2 ( + const CglMixedIntegerRounding2 &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglMixedIntegerRounding2 & + operator=( + const CglMixedIntegerRounding2& rhs); + + /// Destructor + virtual + ~CglMixedIntegerRounding2 (); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + + //--------------------------------------------------------------------------- + /**@name Set and get methods */ + //@{ + /// Set MAXAGGR_ + inline void setMAXAGGR_ (int maxaggr) { + if (maxaggr > 0) { + MAXAGGR_ = maxaggr; + } + else { + throw CoinError("Unallowable value. maxaggr must be > 0", + "gutsOfConstruct","CglMixedIntegerRounding2"); + } + } + + /// Get MAXAGGR_ + inline int getMAXAGGR_ () const { return MAXAGGR_; } + + /// Set MULTIPLY_ + inline void setMULTIPLY_ (bool multiply) { MULTIPLY_ = multiply; } + + /// Get MULTIPLY_ + inline bool getMULTIPLY_ () const { return MULTIPLY_; } + + /// Set CRITERION_ + inline void setCRITERION_ (int criterion) { + if ((criterion >= 1) && (criterion <= 3)) { + CRITERION_ = criterion; + } + else { + throw CoinError("Unallowable value. criterion must be 1, 2 or 3", + "gutsOfConstruct","CglMixedIntegerRounding2"); + } + } + + /// Get CRITERION_ + inline int getCRITERION_ () const { return CRITERION_; } + + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + //@} + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct ( const int maxaggr, + const bool multiply, + const int criterion, + const int preproc); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglMixedIntegerRounding2& rhs); + + // Do preprocessing. + // It determines the type of each row. It also identifies the variable + // upper bounds and variable lower bounds. + // It may change sense and RHS for ranged rows + void mixIntRoundPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(//const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs) const; + + // Generate MIR cuts + void generateMirCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + //const double* coefByRow, + //const int* colInds, + //const int* rowStarts, + //const CoinPackedMatrix& matrixByCol, + const double* coefByCol, + const int* rowInds, + const int* colStarts, + OsiCuts& cs ) const; + + // Copy row selected to CoinIndexedVector + void copyRowSelected( const int iAggregate, + const int rowSelected, + CoinIndexedVector& setRowsAggregated, + int* listRowsAggregated, + double* xlpExtra, + const char sen, + const double rhs, + const double lhs, + const CoinPackedMatrix& matrixByRow, + CoinIndexedVector& rowToAggregate, + double& rhsToAggregate) const; + + // Select a row to aggregate + bool selectRowToAggregate( //const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double* colUpperBound, + const double* colLowerBound, + const CoinIndexedVector& setRowsAggregated, + const double* xlp, const double* coefByCol, + const int* rowInds, const int* colStarts, + int& rowSelected, + int& colSelected ) const; + + // Aggregation heuristic. + // Combines one or more rows of the original matrix + void aggregateRow( const int colSelected, + CoinIndexedVector& rowToAggregate, double rhs, + CoinIndexedVector& rowAggregated, + double& rhsAggregated ) const; + + // Choose the bound substitution based on the criteria defined by the user + inline bool isLowerSubst(const double inf, + const double aj, + const double xlp, + const double LB, + const double UB) const; + + // Bound substitution heuristic + bool boundSubstitution( const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double* xlp, + const double* xlpExtra, + const double* colUpperBound, + const double* colLowerBound, + CoinIndexedVector& mixedKnapsack, + double& rhsMixedKnapsack, double& sStar, + CoinIndexedVector& contVariablesInS ) const; + + // c-MIR separation heuristic + bool cMirSeparation ( const OsiSolverInterface& si, + const CoinPackedMatrix& matrixByRow, + const CoinIndexedVector& rowAggregated, + const int* listRowsAggregated, + const char* sense, const double* RHS, + //const double* coefByRow, + //const int* colInds, const int* rowStarts, + const double* xlp, const double sStar, + const double* colUpperBound, + const double* colLowerBound, + const CoinIndexedVector& mixedKnapsack, + const double& rhsMixedKnapsack, + const CoinIndexedVector& contVariablesInS, + CoinIndexedVector * workVector, + OsiRowCut& flowCut ) const; + + // function to create one c-MIR inequality + void cMirInequality( const int numInt, + const double delta, + const double numeratorBeta, + const int *knapsackIndices, + const double* knapsackElements, + const double* xlp, + const double sStar, + const double* colUpperBound, + const CoinIndexedVector& setC, + CoinIndexedVector& cMIR, + double& rhscMIR, + double& sCoef, + double& violation) const; + + // function to compute G + inline double functionG( const double d, const double f ) const; + + // function to print statistics (used only in debug mode) + void printStats( + std::ofstream & fout, + const bool hasCut, + const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double& rhsAggregated, const double* xlp, + const double* xlpExtra, + const int* listRowsAggregated, + const int* listColsSelected, + const int level, + const double* colUpperBound, + const double* colLowerBound ) const; + + +private: + //--------------------------------------------------------------------------- + // Private member data + + // Maximum number of rows to aggregate + int MAXAGGR_; + // Flag that indicates if an aggregated row is also multiplied by -1 + bool MULTIPLY_; + // The criterion to use in the bound substitution + int CRITERION_; + // Tolerance used for numerical purposes + double EPSILON_; + /// There is no variable upper bound or variable lower bound defined + int UNDEFINED_; + // If violation of a cut is greater that this number, the cut is accepted + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // The array of CglMixIntRoundVUB2s. + CglMixIntRoundVUB2* vubs_; + // The array of CglMixIntRoundVLB2s. + CglMixIntRoundVLB2* vlbs_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // The number of rows of type ROW_MIX + int numRowMix_; + // The indices of the rows of type ROW_MIX + int* indRowMix_; + // The number of rows of type ROW_CONT + int numRowCont_; + // The indices of the rows of type ROW_CONT + int* indRowCont_; + // The number of rows of type ROW_INT + int numRowInt_; + // The indices of the rows of type ROW_INT + int* indRowInt_; + // The number of rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int numRowContVB_; + // The indices of the rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int* indRowContVB_; + // If integer - for speed + char * integerType_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + +}; + +//############################################################################# +// A function that tests the methods in the CglMixedIntegerRounding2 class. The +// only reason for it not to be a member method is that this way it doesn't +// have to be compiled into the library. And that's a gain, because the +// library should be compiled with optimization on, but this method should be +// compiled with debugging. +void CglMixedIntegerRounding2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglOddHole.hpp b/thirdparty/linux/include/coin/coin/CglOddHole.hpp new file mode 100644 index 0000000..3b80caa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglOddHole.hpp @@ -0,0 +1,160 @@ +// $Id: CglOddHole.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglOddHole_H +#define CglOddHole_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** Odd Hole Cut Generator Class */ +class CglOddHole : public CglCutGenerator { + friend void CglOddHoleUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate odd hole cuts for the model of the solver interface, si. + This looks at all rows of type sum x(i) <= 1 (or == 1) (x 0-1) + and sees if there is an odd cycle cut. See Grotschel, Lovasz + and Schrijver (1988) for method. + This is then lifted by using the corresponding Chvatal cut i.e. + Take all rows in cycle and add them together. RHS will be odd so + weaken all odd coefficients so 1.0 goes to 0.0 etc - then + constraint is sum even(j)*x(j) <= odd which can be replaced by + sum (even(j)/2)*x(j) <= (odd-1.0)/2. + A similar cut can be generated for sum x(i) >= 1. + + Insert the generated cuts into OsiCut, cs. + + This is only done for rows with unsatisfied 0-1 variables. If there + are many of these it will be slow. Improvements would do a + randomized subset and also speed up shortest path algorithm used. + + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Create Row List */ + //@{ + /// Create a list of rows which might yield cuts + /// this is to speed up process + /// The possible parameter is a list to cut down search + void createRowList( const OsiSolverInterface & si, + const int * possible=NULL); + /// This version passes in a list - 1 marks possible + void createRowList(int numberRows, const int * whichRow); + //@} + + /**@name Create Clique List */ + //@{ + /// Create a list of extra row cliques which may not be in matrix + /// At present these are classical cliques + void createCliqueList(int numberCliques, const int * cliqueStart, + const int * cliqueMember); + //@} + + /**@name Number Possibilities */ + //@{ + /// Returns how many rows might give odd hole cuts + int numberPossible(); + //@} + /**@name Gets and Sets */ + //@{ + /// Minimum violation + double getMinimumViolation() const; + void setMinimumViolation(double value); + /// Minimum violation per entry + double getMinimumViolationPer() const; + void setMinimumViolationPer(double value); + /// Maximum number of entries in a cut + int getMaximumEntries() const; + void setMaximumEntries(int value); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglOddHole (); + + /// Copy constructor + CglOddHole ( + const CglOddHole &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglOddHole & + operator=( + const CglOddHole& rhs); + + /// Destructor + virtual + ~CglOddHole (); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + + /**@name Private methods */ + //@{ + /// Generate cuts from matrix copy and solution + /// If packed true then <=1 rows, otherwise >=1 rows. + void generateCuts(const OsiRowCutDebugger * debugger, + const CoinPackedMatrix & rowCopy, + const double * solution, const double * dj, + OsiCuts & cs, const int * suitableRow, + const int * fixedColumn,const CglTreeInfo info, + bool packed); + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// list of suitableRows + int * suitableRows_; + /// start of each clique + int * startClique_; + /// clique members + int * member_; + /// epsilon + double epsilon_; + /// 1-epsilon + double onetol_; + /// Minimum violation + double minimumViolation_; + /// Minimum violation per entry + double minimumViolationPer_; + /// Maximum number of entries in a cut + int maximumEntries_; + /// number of rows when suitability tested + int numberRows_; + /// number of cliques + int numberCliques_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglOddHole class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglOddHoleUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglParam.hpp b/thirdparty/linux/include/coin/coin/CglParam.hpp new file mode 100644 index 0000000..4463ef5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglParam.hpp @@ -0,0 +1,93 @@ +// Name: CglParam.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 11/24/06 +// +// $Id: CglParam.hpp 1122 2013-04-06 20:39:53Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//----------------------------------------------------------------------------- +// Copyright (C) 2006, Francois Margot and others. All Rights Reserved. + +#ifndef CglParam_H +#define CglParam_H +#include "CglConfig.h" +#include "CoinFinite.hpp" +/** Class collecting parameters for all cut generators. Each generator + may have a derived class to add parameters. Each generator might + also set different default values for the parameters in CglParam. */ + +class CglParam { + +public: + + /**@name Public Set/get methods */ + //@{ + + /** Set INFINIT */ + virtual void setINFINIT(const double inf); + /** Get value of INFINIT */ + inline double getINFINIT() const {return INFINIT;} + + /** Set EPS */ + virtual void setEPS(const double eps); + /** Get value of EPS */ + inline double getEPS() const {return EPS;} + + /** Set EPS_COEFF */ + virtual void setEPS_COEFF(const double eps_c); + /** Get value of EPS_COEFF */ + inline double getEPS_COEFF() const {return EPS_COEFF;} + + /** Set MAX_SUPPORT */ + virtual void setMAX_SUPPORT(const int max_s); + /** Get value of MAX_SUPPORT */ + inline int getMAX_SUPPORT() const {return MAX_SUPPORT;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglParam(const double inf = COIN_DBL_MAX, const double eps = 1e-6, + const double eps_c = 1e-5, const int max_s = COIN_INT_MAX); + + /// Copy constructor + CglParam(const CglParam&); + + /// Clone + virtual CglParam* clone() const; + + /// Assignment operator + CglParam& operator=(const CglParam &rhs); + + /// Destructor + virtual ~CglParam(); + //@} + +protected: + + // Protected member data + + /**@name Protected member data */ + + //@{ + // Value for infinity. Default: COIN_DBL_MAX. + double INFINIT; + + // EPSILON for double comparisons. Default: 1e-6. + double EPS; + + // Returned cuts do not have coefficients with absolute value smaller + // than EPS_COEFF. Default: 1e-5. + double EPS_COEFF; + + /** Maximum number of non zero coefficients in a generated cut; + Default: COIN_INT_MAX */ + int MAX_SUPPORT; + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglPreProcess.hpp b/thirdparty/linux/include/coin/coin/CglPreProcess.hpp new file mode 100644 index 0000000..65c04ca --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglPreProcess.hpp @@ -0,0 +1,492 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglPreProcess_H +#define CglPreProcess_H + +#include <string> +#include <vector> + +#include "CoinMessageHandler.hpp" +#include "OsiSolverInterface.hpp" +#include "CglStored.hpp" +#include "OsiPresolve.hpp" +#include "CglCutGenerator.hpp" + +//############################################################################# + +/** Class for preProcessing and postProcessing. + + While cuts can be added at any time in the tree, some cuts are actually just + stronger versions of existing constraints. In this case they can replace those + constraints rather than being added as new constraints. This is awkward in the + tree but reasonable at the root node. + + This is a general process class which uses other cut generators to strengthen + constraints, establish that constraints are redundant, fix variables and + find relationships such as x + y == 1. + + Presolve will also be done. + + If row names existed they may be replaced by R0000000 etc + +*/ + +class CglPreProcess { + +public: + + ///@name Main methods + //@{ + /** preProcess problem - returning new problem. + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + This version uses default strategy. For more control copy and edit + code from this function i.e. call preProcessNonDefault + */ + OsiSolverInterface * preProcess(OsiSolverInterface & model, + bool makeEquality=false, int numberPasses=5); + /** preProcess problem - returning new problem. + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + This version assumes user has added cut generators to CglPreProcess object + before calling it. As an example use coding in preProcess + If makeEquality is 1 add slacks to get cliques, + if 2 add slacks to get sos (but only if looks plausible) and keep sos info + */ + OsiSolverInterface * preProcessNonDefault(OsiSolverInterface & model, + int makeEquality=0, int numberPasses=5, + int tuning=0); + /// Creates solution in original model + void postProcess(OsiSolverInterface &model + ,bool deleteStuff=true); + /** Tightens primal bounds to make dual and branch and cutfaster. Unless + fixed or integral, bounds are slightly looser than they could be. + Returns non-zero if problem infeasible + Fudge for branch and bound - put bounds on columns of factor * + largest value (at continuous) - should improve stability + in branch and bound on infeasible branches (0.0 is off) + */ + int tightenPrimalBounds(OsiSolverInterface & model,double factor=0.0); + /** Fix some of problem - returning new problem. + Uses reduced costs. + Optional signed character array + 1 always keep, -1 always discard, 0 use djs + + */ + OsiSolverInterface * someFixed(OsiSolverInterface & model, + double fractionToKeep=0.25, + bool fixContinuousAsWell=false, + char * keep=NULL) const; + /** Replace cliques by more maximal cliques + Returns NULL if rows not reduced by greater than cliquesNeeded*rows + + */ + OsiSolverInterface * cliqueIt(OsiSolverInterface & model, + double cliquesNeeded=0.0) const; + /// If we have a cutoff - fix variables + int reducedCostFix(OsiSolverInterface & model); + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + /** Set cutoff bound on the objective function. + + When using strict comparison, the bound is adjusted by a tolerance to + avoid accidentally cutting off the optimal solution. + */ + void setCutoff(double value) ; + + /// Get the cutoff bound on the objective function - always as minimize + double getCutoff() const; + /// The original solver associated with this model. + inline OsiSolverInterface * originalModel() const + { return originalModel_;} + /// Solver after making clique equalities (may == original) + inline OsiSolverInterface * startModel() const + { return startModel_;} + /// Copies of solver at various stages after presolve + inline OsiSolverInterface * modelAtPass(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return model_[iPass]; else return NULL;} + /// Copies of solver at various stages after presolve after modifications + inline OsiSolverInterface * modifiedModel(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return modifiedModel_[iPass]; else return NULL;} + /// Matching presolve information + inline OsiPresolve * presolve(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return presolve_[iPass]; else return NULL;} + /** Return a pointer to the original columns (with possible clique slacks) + MUST be called before postProcess otherwise you just get 0,1,2.. */ + const int * originalColumns(); + /** Return a pointer to the original rows + MUST be called before postProcess otherwise you just get 0,1,2.. */ + const int * originalRows(); + /// Number of SOS if found + inline int numberSOS() const + { return numberSOS_;} + /// Type of each SOS + inline const int * typeSOS() const + { return typeSOS_;} + /// Start of each SOS + inline const int * startSOS() const + { return startSOS_;} + /// Columns in SOS + inline const int * whichSOS() const + { return whichSOS_;} + /// Weights for each SOS column + inline const double * weightSOS() const + { return weightSOS_;} + /// Pass in prohibited columns + void passInProhibited(const char * prohibited,int numberColumns); + /// Updated prohibited columns + inline const char * prohibited() + { return prohibited_;} + /// Number of iterations PreProcessing + inline int numberIterationsPre() const + { return numberIterationsPre_;} + /// Number of iterations PostProcessing + inline int numberIterationsPost() const + { return numberIterationsPost_;} + /** Pass in row types + 0 normal + 1 cut rows - will be dropped if remain in + At end of preprocess cut rows will be dropped + and put into cuts + */ + void passInRowTypes(const char * rowTypes,int numberRows); + /** Updated row types - may be NULL + Carried around and corresponds to existing rows + -1 added by preprocess e.g. x+y=1 + 0 normal + 1 cut rows - can be dropped if wanted + */ + inline const char * rowTypes() + { return rowType_;} + /// Return cuts from dropped rows + inline const CglStored & cuts() const + { return cuts_;} + /// Return pointer to cuts from dropped rows + inline const CglStored * cutsPointer() const + { return &cuts_;} + /// Update prohibited and rowType + void update(const OsiPresolve * pinfo,const OsiSolverInterface * solver); + /// Set options + inline void setOptions(int value) + { options_=value;} + //@} + + ///@name Cut generator methods + //@{ + /// Get the number of cut generators + inline int numberCutGenerators() const + { return numberCutGenerators_;} + /// Get the list of cut generators + inline CglCutGenerator ** cutGenerators() const + { return generator_;} + ///Get the specified cut generator + inline CglCutGenerator * cutGenerator(int i) const + { return generator_[i];} + /** Add one generator - up to user to delete generators. + */ + void addCutGenerator(CglCutGenerator * generator); +//@} + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + + /// Get application data + void * getApplicationData() const; + //@} + + //--------------------------------------------------------------------------- + + /**@name Message handling */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Return handler + inline CoinMessageHandler * messageHandler() const + {return handler_;} + /// Return messages + inline CoinMessages messages() + {return messages_;} + /// Return pointer to messages + inline CoinMessages * messagesPointer() + {return &messages_;} + //@} + //--------------------------------------------------------------------------- + + + ///@name Constructors and destructors etc + //@{ + /// Constructor + CglPreProcess(); + + /// Copy constructor . + CglPreProcess(const CglPreProcess & rhs); + + /// Assignment operator + CglPreProcess & operator=(const CglPreProcess& rhs); + + /// Destructor + ~CglPreProcess (); + + /// Clears out as much as possible + void gutsOfDestructor(); + //@} +private: + + ///@name private methods + //@{ + /** Return model with useful modifications. + If constraints true then adds any x+y=1 or x-y=0 constraints + If NULL infeasible + */ + OsiSolverInterface * modified(OsiSolverInterface * model, + bool constraints, + int & numberChanges, + int iBigPass, + int numberPasses); + /// create original columns and rows + void createOriginalIndices(); + /// Make continuous variables integer + void makeInteger(); + //@} + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + + /// The original solver associated with this model. + OsiSolverInterface * originalModel_; + /// Solver after making clique equalities (may == original) + OsiSolverInterface * startModel_; + /// Number of solvers at various stages + int numberSolvers_; + /// Copies of solver at various stages after presolve + OsiSolverInterface ** model_; + /// Copies of solver at various stages after presolve after modifications + OsiSolverInterface ** modifiedModel_; + /// Matching presolve information + OsiPresolve ** presolve_; + + /// Message handler + CoinMessageHandler * handler_; + + /** Flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + bool defaultHandler_; + + /// Cgl messages + CoinMessages messages_; + + /// Pointer to user-defined data structure + void * appData_; + /// Original column numbers + int * originalColumn_; + /// Original row numbers + int * originalRow_; + /// Number of cut generators + int numberCutGenerators_; + /// Cut generators + CglCutGenerator ** generator_; + /// Number of SOS if found + int numberSOS_; + /// Type of each SOS + int * typeSOS_; + /// Start of each SOS + int * startSOS_; + /// Columns in SOS + int * whichSOS_; + /// Weights for each SOS column + double * weightSOS_; + /// Number of columns in original prohibition set + int numberProhibited_; + /// Number of iterations done in PreProcessing + int numberIterationsPre_; + /// Number of iterations done in PostProcessing + int numberIterationsPost_; + /// Columns which should not be presolved e.g. SOS + char * prohibited_; + /// Number of rows in original row types + int numberRowType_; + /** Options + 1 - original model had integer bounds before tightening + 2 - don't do probing + 4 - don't do duplicate rows + 8 - don't do cliques + 16 - some heavy probing options + 64 - very heavy probing + */ + int options_; + /** Row types (may be NULL) + Carried around and corresponds to existing rows + -1 added by preprocess e.g. x+y=1 + 0 normal + 1 cut rows - can be dropped if wanted + */ + char * rowType_; + /// Cuts from dropped rows + CglStored cuts_; + //@} +}; +/// For Bron-Kerbosch +class CglBK { + +public: + + ///@name Main methods + //@{ + /// For recursive Bron-Kerbosch + void bronKerbosch(); + /// Creates strengthened smaller model + OsiSolverInterface * newSolver(const OsiSolverInterface & model); + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + //@} + + //--------------------------------------------------------------------------- + + + ///@name Constructors and destructors etc + //@{ + /// Default constructor + CglBK(); + + /// Useful constructor + CglBK(const OsiSolverInterface & model, const char * rowType, + int numberElements); + + /// Copy constructor . + CglBK(const CglBK & rhs); + + /// Assignment operator + CglBK & operator=(const CglBK& rhs); + + /// Destructor + ~CglBK (); + + //@} + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + /// Current candidates (created at each level) + int * candidates_; + /// Array to mark stuff + char * mark_; + /// Starts for graph (numberPossible+1) + int * start_; + /// Other column/node + int * otherColumn_; + /// Original row (in parallel with otherColumn_) + int * originalRow_; + /// How many times each original row dominated + int * dominated_; + /// Clique entries + CoinPackedMatrix * cliqueMatrix_; + /// points to row types + const char * rowType_; + /// Number of original columns + int numberColumns_; + /// Number of original rows + int numberRows_; + /// Number possible + int numberPossible_; + /// Current number of candidates + int numberCandidates_; + /// First not (stored backwards from numberPossible_) + int firstNot_; + /// Current number in clique + int numberIn_; + /// For acceleration + int left_; + int lastColumn_; + //@} +}; +/** + Only store unique row cuts +*/ +// for hashing +typedef struct { + int index, next; +} CglHashLink; +class OsiRowCut; +class CglUniqueRowCuts { +public: + + CglUniqueRowCuts(int initialMaxSize=0, int hashMultiplier=4 ); + ~CglUniqueRowCuts(); + CglUniqueRowCuts(const CglUniqueRowCuts& rhs); + CglUniqueRowCuts& operator=(const CglUniqueRowCuts& rhs); + inline OsiRowCut * cut(int sequence) const + { return rowCut_[sequence];} + inline int numberCuts() const + { return numberCuts_;} + inline int sizeRowCuts() const + { return numberCuts_;} + inline OsiRowCut * rowCutPtr(int sequence) + { return rowCut_[sequence];} + void eraseRowCut(int sequence); + // insert cut + inline void insert(const OsiRowCut & cut) + { insertIfNotDuplicate(cut);} + // Return 0 if added, 1 if not + int insertIfNotDuplicate(const OsiRowCut & cut); + // Add in cuts as normal cuts (and delete) + void addCuts(OsiCuts & cs); +private: + OsiRowCut ** rowCut_; + /// Hash table + CglHashLink *hash_; + int size_; + int hashMultiplier_; + int numberCuts_; + int lastHash_; +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglProbing.hpp b/thirdparty/linux/include/coin/coin/CglProbing.hpp new file mode 100644 index 0000000..5ca8996 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglProbing.hpp @@ -0,0 +1,543 @@ +// $Id: CglProbing.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglProbing_H +#define CglProbing_H + +#include <string> + +#include "CglCutGenerator.hpp" + /** Only useful type of disaggregation is most normal + For now just done for 0-1 variables + Can be used for building cliques + */ + typedef struct { + //unsigned int zeroOne:1; // nonzero if affected variable is 0-1 + //unsigned int whenAtUB:1; // nonzero if fixing happens when this variable at 1 + //unsigned int affectedToUB:1; // nonzero if affected variable fixed to UB + //unsigned int affected:29; // If 0-1 then 0-1 sequence, otherwise true + unsigned int affected; + } disaggregationAction; + +/** Probing Cut Generator Class */ +class CglProbing : public CglCutGenerator { + friend void CglProbingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate probing/disaggregation cuts for the model of the + solver interface, si. + + This is a simplification of probing ideas put into OSL about + ten years ago. The only known documentation is a copy of a + talk handout - we think Robin Lougee-Heimer has a copy! + + For selected integer variables (e.g. unsatisfied ones) the effect of + setting them up or down is investigated. Setting a variable up + may in turn set other variables (continuous as well as integer). + There are various possible results: + + 1) It is shown that problem is infeasible (this may also be + because objective function or reduced costs show worse than + best solution). If the other way is feasible we can generate + a column cut (and continue probing), if not feasible we can + say problem infeasible. + + 2) If both ways are feasible, it can happen that x to 0 implies y to 1 + ** and x to 1 implies y to 1 (again a column cut). More common + is that x to 0 implies y to 1 and x to 1 implies y to 0 so we could + substitute for y which might lead later to more powerful cuts. + ** This is not done in this code as there is no mechanism for + returning information. + + 3) When x to 1 a constraint went slack by c. We can tighten the + constraint ax + .... <= b (where a may be zero) to + (a+c)x + .... <= b. If this cut is violated then it is + generated. + + 4) Similarly we can generate implied disaggregation cuts + + Note - differences to cuts in OSL. + + a) OSL had structures intended to make this faster. + b) The "chaining" in 2) was done + c) Row cuts modified original constraint rather than adding cut + b) This code can cope with general integer variables. + + Insert the generated cuts into OsiCut, cs. + + If a "snapshot" of a matrix exists then this will be used. + Presumably this will give global cuts and will be faster. + No check is done to see if cuts will be global. + + Otherwise use current matrix. + + Both row cuts and column cuts may be returned + + The mode options are: + 0) Only unsatisfied integer variables will be looked at. + If no information exists for that variable then + probing will be done so as a by-product you "may" get a fixing + or infeasibility. This will be fast and is only available + if a snapshot exists (otherwise as 1). + The bounds in the snapshot are the ones used. + 1) Look at unsatisfied integer variables, using current bounds. + Probing will be done on all looked at. + 2) Look at all integer variables, using current bounds. + Probing will be done on all + + ** If generateCutsAndModify is used then new relaxed + row bounds and tightened column bounds are generated + Returns number of infeasibilities + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + int generateCutsAndModify( const OsiSolverInterface & si, OsiCuts & cs, + CglTreeInfo * info); + //@} + + /**@name snapshot etc */ + //@{ + /** Create a copy of matrix which is to be used + this is to speed up process and to give global cuts + Can give an array with 1 set to select, 0 to ignore + column bounds are tightened + If array given then values of 1 will be set to 0 if redundant. + Objective may be added as constraint + Returns 1 if infeasible otherwise 0 + */ + int snapshot ( const OsiSolverInterface & si, + char * possible=NULL, + bool withObjective=true); + /// Deletes snapshot + void deleteSnapshot ( ); + /** Creates cliques for use by probing. + Only cliques >= minimumSize and < maximumSize created + Can also try and extend cliques as a result of probing (root node). + Returns number of cliques found. + */ + int createCliques( OsiSolverInterface & si, + int minimumSize=2, int maximumSize=100); + /// Delete all clique information + void deleteCliques(); + /** Create a fake model by adding cliques + if type&4 then delete rest of model first, + if 1 then add proper cliques, 2 add fake cliques */ + OsiSolverInterface * cliqueModel(const OsiSolverInterface * model, + int type); + //@} + + /**@name Get tighter column bounds */ + //@{ + /// Lower + const double * tightLower() const; + /// Upper + const double * tightUpper() const; + /// Array which says tighten continuous + const char * tightenBounds() const + { return tightenBounds_;} + //@} + + /**@name Get possible freed up row bounds - only valid after mode==3 */ + //@{ + /// Lower + const double * relaxedRowLower() const; + /// Upper + const double * relaxedRowUpper() const; + //@} + + /**@name Change mode */ + //@{ + /// Set + void setMode(int mode); + /// Get + int getMode() const; + //@} + + /**@name Change maxima */ + //@{ + /// Set maximum number of passes per node + void setMaxPass(int value); + /// Get maximum number of passes per node + int getMaxPass() const; + /// Set log level - 0 none, 1 - a bit, 2 - more details + void setLogLevel(int value); + /// Get log level + int getLogLevel() const; + /// Set maximum number of unsatisfied variables to look at + void setMaxProbe(int value); + /// Get maximum number of unsatisfied variables to look at + int getMaxProbe() const; + /// Set maximum number of variables to look at in one probe + void setMaxLook(int value); + /// Get maximum number of variables to look at in one probe + int getMaxLook() const; + /// Set maximum number of elements in row for it to be considered + void setMaxElements(int value); + /// Get maximum number of elements in row for it to be considered + int getMaxElements() const; + /// Set maximum number of passes per node (root node) + void setMaxPassRoot(int value); + /// Get maximum number of passes per node (root node) + int getMaxPassRoot() const; + /// Set maximum number of unsatisfied variables to look at (root node) + void setMaxProbeRoot(int value); + /// Get maximum number of unsatisfied variables to look at (root node) + int getMaxProbeRoot() const; + /// Set maximum number of variables to look at in one probe (root node) + void setMaxLookRoot(int value); + /// Get maximum number of variables to look at in one probe (root node) + int getMaxLookRoot() const; + /// Set maximum number of elements in row for it to be considered (root node) + void setMaxElementsRoot(int value); + /// Get maximum number of elements in row for it to be considered (root node) + int getMaxElementsRoot() const; + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const; + //@} + + /**@name Get information back from probing */ + //@{ + /// Number looked at this time + inline int numberThisTime() const + { return numberThisTime_;} + /// Which ones looked at this time + inline const int * lookedAt() const + { return lookedAt_;} + //@} + + /**@name Stop or restart row cuts (otherwise just fixing from probing) */ + //@{ + /// Set + /// 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both) + void setRowCuts(int type); + /// Get + int rowCuts() const; + //@} + /// Clique type + typedef struct { + unsigned int equality:1; // nonzero if clique is == + } CliqueType; + + /**@name Information on cliques */ + //@{ + /// Number of cliques + inline int numberCliques() const + { return numberCliques_;} + /// Clique type + inline CliqueType * cliqueType() const + { return cliqueType_;} + /// Start of each clique + inline int * cliqueStart() const + { return cliqueStart_;} + /// Entries for clique + inline CliqueEntry * cliqueEntry() const + { return cliqueEntry_;} + //@} + + /**@name Whether use objective as constraint */ + //@{ + /** Set + 0 don't + 1 do + -1 don't even think about it + */ + void setUsingObjective(int yesNo); + /// Get + int getUsingObjective() const; + //@} + + /**@name Mark which continuous variables are to be tightened */ + //@{ + /// Mark variables to be tightened + void tightenThese(const OsiSolverInterface & solver, int number, const int * which); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglProbing (); + + /// Copy constructor + CglProbing ( + const CglProbing &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglProbing & + operator=( + const CglProbing& rhs); + + /// Destructor + virtual + ~CglProbing (); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + /**@name probe */ + //@{ + /// Does probing and adding cuts (without cliques and mode_!=0) + int probe( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy,const CoinBigIndex * rowStartPos, + const int * realRow, const double * rowLower, const double * rowUpper, + const char * intVar, double * minR, double * maxR, int * markR, + CglTreeInfo * info); + /// Does probing and adding cuts (with cliques) + int probeCliques( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy, const int * realRow, + double * rowLower, double * rowUpper, + char * intVar, double * minR, double * maxR, int * markR, + CglTreeInfo * info); + /// Does probing and adding cuts for clique slacks + int probeSlacks( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy, + double * rowLower, double * rowUpper, + char * intVar, double * minR, double * maxR,int * markR, + CglTreeInfo * info); + /** Does most of work of generateCuts + Returns number of infeasibilities */ + int gutsOfGenerateCuts( const OsiSolverInterface & si, + OsiCuts & cs, + double * rowLower, double * rowUpper, + double * colLower, double * colUpper, + CglTreeInfo * info); + /// Sets up clique information for each row + void setupRowCliqueInformation(const OsiSolverInterface & si); + /** This tightens column bounds (and can declare infeasibility) + It may also declare rows to be redundant */ + int tighten(double *colLower, double * colUpper, + const int *column, const double *rowElements, + const CoinBigIndex *rowStart,const CoinBigIndex * rowStartPos, + const int * rowLength, + double *rowLower, double *rowUpper, + int nRows,int nCols,char * intVar,int maxpass, + double tolerance); + /// This just sets minima and maxima on rows + void tighten2(double *colLower, double * colUpper, + const int *column, const double *rowElements, + const CoinBigIndex *rowStart, + const int * rowLength, + double *rowLower, double *rowUpper, + double * minR, double * maxR, int * markR, + int nRows); + //@} + + // Private member data + + struct disaggregation_struct_tag ; + friend struct CglProbing::disaggregation_struct_tag ; + + /**@name Private member data */ + //@{ + /// Row copy (only if snapshot) + CoinPackedMatrix * rowCopy_; + /// Column copy (only if snapshot) + CoinPackedMatrix * columnCopy_; + /// Lower bounds on rows + double * rowLower_; + /// Upper bounds on rows + double * rowUpper_; + /// Lower bounds on columns + double * colLower_; + /// Upper bounds on columns + double * colUpper_; + /// Number of rows in snapshot (or when cliqueRow stuff computed) + int numberRows_; + /// Number of columns in problem ( must == current) + int numberColumns_; + /// Tolerance to see if infeasible + double primalTolerance_; + /** Mode - 0 lazy using snapshot, 1 just unsatisfied, 2 all. + 16 bit set if want to extend cliques at root node + */ + int mode_; + /** Row cuts flag + 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both), 4 just column cuts + -n as +n but just fixes variables unless at root + */ + int rowCuts_; + /// Maximum number of passes to do in probing + int maxPass_; + /// Log level - 0 none, 1 - a bit, 2 - more details + int logLevel_; + /// Maximum number of unsatisfied variables to probe + int maxProbe_; + /// Maximum number of variables to look at in one probe + int maxStack_; + /// Maximum number of elements in row for scan + int maxElements_; + /// Maximum number of passes to do in probing at root + int maxPassRoot_; + /// Maximum number of unsatisfied variables to probe at root + int maxProbeRoot_; + /// Maximum number of variables to look at in one probe at root + int maxStackRoot_; + /// Maximum number of elements in row for scan at root + int maxElementsRoot_; + /// Whether to include objective as constraint + int usingObjective_; + /// Number of integer variables + int numberIntegers_; + /// Number of 0-1 integer variables + int number01Integers_; + /// Number looked at this time + int numberThisTime_; + /// Total number of times called + int totalTimesCalled_; + /// Which ones looked at this time + int * lookedAt_; + /// Disaggregation cuts and for building cliques + typedef struct disaggregation_struct_tag { + int sequence; // integer variable + // index will be NULL if no probing done yet + int length; // length of newValue + disaggregationAction * index; // columns whose bounds will be changed + } disaggregation; + disaggregation * cutVector_; + /// Cliques + /// Number of cliques + int numberCliques_; + /// Clique type + CliqueType * cliqueType_; + /// Start of each clique + int * cliqueStart_; + /// Entries for clique + CliqueEntry * cliqueEntry_; + /** Start of oneFixes cliques for a column in matrix or -1 if not + in any clique */ + int * oneFixStart_; + /** Start of zeroFixes cliques for a column in matrix or -1 if not + in any clique */ + int * zeroFixStart_; + /// End of fixes for a column + int * endFixStart_; + /// Clique numbers for one or zero fixes + int * whichClique_; + /** For each column with nonzero in row copy this gives a clique "number". + So first clique mentioned in row is always 0. If no entries for row + then no cliques. If sequence > numberColumns then not in clique. + */ + CliqueEntry * cliqueRow_; + /// cliqueRow_ starts for each row + int * cliqueRowStart_; + /// If not null and [i] !=0 then also tighten even if continuous + char * tightenBounds_; + //@} +}; +inline int affectedInDisaggregation(const disaggregationAction & dis) +{ return dis.affected&0x1fffffff;} +inline void setAffectedInDisaggregation(disaggregationAction & dis, + int affected) +{ dis.affected = affected|(dis.affected&0xe0000000);} +#ifdef NDEBUG +inline bool zeroOneInDisaggregation(const disaggregationAction & ) +{ return true;} +#else +inline bool zeroOneInDisaggregation(const disaggregationAction & dis) +//{ return (dis.affected&0x80000000)!=0;} +{ assert ((dis.affected&0x80000000)!=0); return true;} +#endif +inline void setZeroOneInDisaggregation(disaggregationAction & dis,bool zeroOne) +{ dis.affected = (zeroOne ? 0x80000000 : 0)|(dis.affected&0x7fffffff);} +inline bool whenAtUBInDisaggregation(const disaggregationAction & dis) +{ return (dis.affected&0x40000000)!=0;} +inline void setWhenAtUBInDisaggregation(disaggregationAction & dis,bool whenAtUB) +{ dis.affected = (whenAtUB ? 0x40000000 : 0)|(dis.affected&0xbfffffff);} +inline bool affectedToUBInDisaggregation(const disaggregationAction & dis) +{ return (dis.affected&0x20000000)!=0;} +inline void setAffectedToUBInDisaggregation(disaggregationAction & dis,bool affectedToUB) +{ dis.affected = (affectedToUB ? 0x20000000 : 0)|(dis.affected&0xdfffffff);} + +//############################################################################# +/** A function that tests the methods in the CglProbing class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglProbingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); +/// This just uses implication info +class CglImplication : public CglCutGenerator { + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate cuts from implication table + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglImplication (); + + /// Constructor with info + CglImplication (CglTreeProbingInfo * info); + + /// Copy constructor + CglImplication ( + const CglImplication &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglImplication & + operator=( + const CglImplication& rhs); + + /// Destructor + virtual + ~CglImplication (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + /**@name Set implication */ + //@{ + /// Set implication + inline void setProbingInfo(CglTreeProbingInfo * info) + { probingInfo_=info;} + //@} + +private: + /**@name Private member data */ + //@{ + /// Pointer to tree probing info + CglTreeProbingInfo * probingInfo_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglRedSplit.hpp b/thirdparty/linux/include/coin/coin/CglRedSplit.hpp new file mode 100644 index 0000000..1265b1d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglRedSplit.hpp @@ -0,0 +1,448 @@ +// Last edit: 4/20/07 +// +// Name: CglRedSplit.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 2/6/05 +// +// $Id: CglRedSplit.hpp 1119 2013-04-06 20:24:18Z stefan $ +//----------------------------------------------------------------------------- +// Copyright (C) 2005, Francois Margot and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglRedSplit_H +#define CglRedSplit_H + +#include "CglCutGenerator.hpp" +#include "CglRedSplitParam.hpp" + +/** Gomory Reduce-and-Split Cut Generator Class; See method generateCuts(). + Based on the paper by K. Anderson, G. Cornuejols, Yanjun Li, + "Reduce-and-Split Cuts: Improving the Performance of Mixed Integer + Gomory Cuts", Management Science 51 (2005). */ + +class CglRedSplit : public CglCutGenerator { + + friend void CglRedSplitUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + /**@name generateCuts */ + //@{ + /** Generate Reduce-and-Split Mixed Integer Gomory cuts + for the model of the solver interface si. + + Insert the generated cuts into OsiCuts cs. + + Warning: This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau and + optimal basis inverse and makes assumptions on the way slack variables + are added by the solver. The Osi implementations for Clp and Cplex + verify these assumptions. + + When calling the generator, the solver interface si + must contain an optimized + problem and information related to the optimal basis must be available + through the OsiSolverInterface methods (si->optimalBasisIsAvailable() + must return 'true'). It is also essential that the integrality of + structural variable i can be obtained using si->isInteger(i). + + Reduce-and-Split cuts are variants of Gomory cuts: Starting from + the current optimal tableau, linear combinations of the rows of + the current optimal simplex tableau are used for generating Gomory + cuts. The choice of the linear combinations is driven by the objective + of reducing the coefficients of the non basic continuous variables + in the resulting row. + Note that this generator might not be able to generate cuts for some + solutions violating integrality constraints. + + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglRedSplitParam object. + void setParam(const CglRedSplitParam &source); + // Return the CglRedSplitParam object of the generator. + inline CglRedSplitParam getParam() const {return param;} + + // Compute entries of low_is_lub and up_is_lub. + void compute_is_lub(); + + // Compute entries of is_integer. + void compute_is_integer(); + + /// Set given_optsol to the given optimal solution given_sol. + /// If given_optsol is set using this method, + /// the code will stop as soon as + /// a generated cut is violated by the given solution; exclusively + /// for debugging purposes. + void set_given_optsol(const double *given_sol, const int card_sol); + + /// Print some of the data members + void print() const; + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + //@} + + /**@name Public Methods (soon to be obsolete)*/ + //@{ + //************************************************************ + // TO BE REMOVED + /** Set limit, the maximum number of non zero coefficients in generated cut; + Default: 50 */ + void setLimit(int limit); + /** Get value of limit */ + int getLimit() const; + + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.05 */ + void setAway(double value); + /// Get value of away + double getAway() const; + /** Set the value of LUB, value considered large for the absolute value of + a lower or upper bound on a variable; + Default: 1000 */ + void setLUB(double value); + /** Get the value of LUB */ + double getLUB() const; + + /** Set the value of EPS, epsilon for double computations; + Default: 1e-7 */ + void setEPS(double value); + /** Get the value of EPS */ + double getEPS() const; + + /** Set the value of EPS_COEFF, epsilon for values of coefficients; + Default: 1e-8 */ + void setEPS_COEFF(double value); + /** Get the value of EPS_COEFF */ + double getEPS_COEFF() const; + + /** Set the value of EPS_COEFF_LUB, epsilon for values of coefficients for + variables with absolute value of lower or upper bound larger than LUB; + Default: 1e-13 */ + void setEPS_COEFF_LUB(double value); + /** Get the value of EPS_COEFF_LUB */ + double getEPS_COEFF_LUB() const; + + /** Set the value of EPS_RELAX, value used for relaxing the right hand side + of each generated cut; + Default: 1e-8 */ + void setEPS_RELAX(double value); + /** Get the value of EPS_RELAX */ + double getEPS_RELAX() const; + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + void setNormIsZero(double value); + /** Get the value of normIsZero */ + double getNormIsZero() const; + + /** Set the value of minReduc, threshold for relative norm improvement for + performing a reduction; Default: 0.05 */ + void setMinReduc(double value); + /// Get the value of minReduc + double getMinReduc() const; + + /** Set the maximum allowed value for (mTab * mTab * CoinMax(mTab, nTab)) where + mTab is the number of rows used in the combinations and nTab is the + number of continuous non basic variables. The work of the generator is + proportional to (mTab * mTab * CoinMax(mTab, nTab)). Reducing the value of + maxTab makes the generator faster, but weaker. Default: 1e7. */ + void setMaxTab(double value); + /// Get the value of maxTab + double getMaxTab() const; + // END TO BE REMOVED + //************************************************************ + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplit(); + + /// Constructor with specified parameters + CglRedSplit(const CglRedSplitParam &RS_param); + + /// Copy constructor + CglRedSplit (const CglRedSplit &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglRedSplit & + operator=( + const CglRedSplit& rhs); + + /// Destructor + virtual + ~CglRedSplit (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglRedSplit members are properly set. + void generateCuts(OsiCuts & cs); + + /// Compute the fractional part of value, allowing for small error. + inline double rs_above_integer(double value); + + /// Perform row r1 of pi := row r1 of pi - step * row r2 of pi. + void update_pi_mat(int r1, int r2, int step); + + /// Perform row r1 of tab := row r1 of tab - step * row r2 of tab. + void update_redTab(int r1, int r2, int step); + + /// Find optimal integer step for changing row r1 by adding to it a + /// multiple of another row r2. + void find_step(int r1, int r2, int *step, + double *reduc, double *norm); + + /// Test if an ordered pair of rows yields a reduction. Perform the + /// reduction if it is acceptable. + int test_pair(int r1, int r2, double *norm); + + /// Reduce rows of contNonBasicTab. + void reduce_contNonBasicTab(); + + /// Generate a row of the current LP tableau. + void generate_row(int index_row, double *row); + + /// Generate a mixed integer Chvatal-Gomory cut, when all non basic + /// variables are non negative and at their lower bound. + int generate_cgcut(double *row, double *rhs); + + /// Generate a mixed integer Chvatal-Gomory cut, when all non basic + /// variables are non negative and at their lower bound (different formula) + int generate_cgcut_2(int basic_ind, double *row, double *rhs); + + /// Use multiples of the initial inequalities to cancel out the coefficients + /// of the slack variables. + void eliminate_slacks(double *row, + const double *elements, + const int *start, + const int *indices, + const int *rowLength, + const double *rhs, double *rowrhs); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound. + void flip(double *row); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. + void unflip(double *row, double *rowrhs, double *slack_val); + + /// Return the scale factor for the row. + /// Compute max_coeff: maximum absolute value of the coefficients. + /// Compute min_coeff: minimum absolute value of the coefficients + /// larger than EPS_COEFF. + /// Return -1 if max_coeff < EPS_COEFF or if max_coeff/min_coeff > MAXDYN + /// or MAXDYN_LUB (depending if the row has a non zero coeff. for a variable + /// with large lower/upper bound) */. + double row_scale_factor(double *row); + + /// Generate the packed cut from the row representation. + int generate_packed_row(const double *xlp, double *row, + int *rowind, double *rowelem, + int *card_row, double & rhs); + + /// Check that the generated cuts do not cut a given optimal solution. + void check_optsol(const int calling_place, + const double *xlp, const double *slack_val, + const int do_flip); + + /// Check that the generated cuts do not cut a given optimal solution. + void check_optsol(const int calling_place, + const double *xlp, const double *slack_val, + const double *ck_row, const double ck_rhs, + const int cut_number, const int do_flip); + + // Check that two vectors are different. + bool rs_are_different_vectors(const int *vect1, + const int *vect2, + const int dim); + + // Check that two vectors are different. + bool rs_are_different_vectors(const double *vect1, + const double *vect2, + const int dim); + + // Check that two matrices are different. + bool rs_are_different_matrices(const CoinPackedMatrix *mat1, + const CoinPackedMatrix *mat2, + const int nmaj, + const int nmin); + //@} + + + // Private member data + +/**@name Private member data */ + + //@{ + + /// Object with CglRedSplitParam members. + CglRedSplitParam param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Number of integer basic structural variables that are fractional in the + /// current lp solution (at least param.away_ from being integer). + int card_intBasicVar_frac; + + /// Number of integer non basic structural variables in the + /// current lp solution. + int card_intNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current lp solution. + int card_contNonBasicVar; + + /// Number of non basic variables (structural or slack) at their + /// upper bound in the current lp solution. + int card_nonBasicAtUpper; + + /// Number of non basic variables (structural or slack) at their + /// lower bound in the current lp solution. + int card_nonBasicAtLower; + + /// Characteristic vector for integer basic structural variables + /// with non integer value in the current lp solution. + int *cv_intBasicVar_frac; + + /// List of integer structural basic variables + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar_frac; + + /// List of integer structural non basic variables. + int *intNonBasicVar; + + /// List of continuous non basic variables (structural or slack). + // slacks are considered continuous (no harm if this is not the case). + int *contNonBasicVar; + + /// List of non basic variables (structural or slack) at their + /// upper bound. + int *nonBasicAtUpper; + + /// List of non basic variables (structural or slack) at their lower + /// bound. + int *nonBasicAtLower; + + /// Number of rows in the reduced tableau (= card_intBasicVar_frac). + int mTab; + + /// Number of columns in the reduced tableau (= card_contNonBasicVar) + int nTab; + + /// Tableau of multipliers used to alter the rows used in generation. + /// Dimensions: mTab by mTab. Initially, pi_mat is the identity matrix. + int **pi_mat; + + /// Current tableau for continuous non basic variables (structural or slack). + /// Only rows used for generation. + /// Dimensions: mTab by nTab. + double **contNonBasicTab; + + /// Current tableau for integer non basic structural variables. + /// Only rows used for generation. + // Dimensions: mTab by card_intNonBasicVar. + double **intNonBasicTab; + + /// Right hand side of the tableau. + /// Only rows used for generation. + double *rhsTab ; + + /// Given optimal solution that should not be cut; only for debug. + const double *given_optsol; + + /// Number of entries in given_optsol. + int card_given_optsol; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + int *is_integer; + + /// Characteristic vector of the structural variables whose lower bound + /// in absolute value is larger than LUB. + int *low_is_lub; + + /// Characteristic vector of the structural variables whose upper bound + /// in absolute value is larger than LUB. + int *up_is_lub; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on column type. Reset by each call to generateCuts(). + const char *colType; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglRedSplit class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglRedSplitUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglRedSplit2.hpp b/thirdparty/linux/include/coin/coin/CglRedSplit2.hpp new file mode 100644 index 0000000..c66e1ca --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglRedSplit2.hpp @@ -0,0 +1,494 @@ +// Last edit: 04/03/10 +// +// Name: CglRedSplit2.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// Singapore +// email: nannicini@sutd.edu.sg +// based on CglRedSplit by Francois Margot +// Date: 03/09/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2010, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglRedSplit2_H +#define CglRedSplit2_H + +#include "CglCutGenerator.hpp" +#include "CglRedSplit2Param.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinTime.hpp" + +/** Reduce-and-Split Cut Generator Class; See method generateCuts(). + Based on the papers "Practical strategies for generating rank-1 + split cuts in mixed-integer linear programming" by G. Cornuejols + and G. Nannicini, published on Mathematical Programming + Computation, and "Combining Lift-and-Project and Reduce-and-Split" + by E. Balas, G. Cornuejols, T. Kis and G. Nannicini, published on + INFORMS Journal on Computing. Part of this code is based on + CglRedSplit by F. Margot. */ + +class CglRedSplit2 : public CglCutGenerator { + + friend void CglRedSplit2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + /**@name generateCuts */ + //@{ + /** Generate Reduce-and-Split Mixed Integer Gomory cuts + for the model of the solver interface si. + + Insert the generated cuts into OsiCuts cs. + + This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau + and optimal basis inverse and makes assumptions on the way slack + variables are added by the solver. The Osi implementations for + Clp and Cplex verify these assumptions. + + When calling the generator, the solver interface si must contain + an optimized problem and information related to the optimal + basis must be available through the OsiSolverInterface methods + (si->optimalBasisIsAvailable() must return 'true'). It is also + essential that the integrality of structural variable i can be + obtained using si->isInteger(i). + + Reduce-and-Split cuts are a class of split cuts. We compute + linear combinations of the rows of the simplex tableau, trying + to reduce some of the coefficients on the nonbasic continuous + columns. We have a large number of heuristics to choose which + coefficients should be reduced, and by using which rows. The + paper explains everything in detail. + + Note that this generator can potentially generate a huge number + of cuts, depending on how it is parametered. Default parameters + should be good for most situations; if you want to go heavy on + split cuts, use more row selection strategies or a different + number of rows in the linear combinations. Again, look at the + paper for details. If you want to generate a small number of + cuts, default parameters are not the best choice. + + A combination of Reduce-and-Split with Lift & Project is + described in the paper "Combining Lift-and-Project and + Reduce-and-Split". The Reduce-and-Split code for the + implementation used in that paper is included here. + + This generator does not generate the same cuts as CglRedSplit, + therefore both generators can be used in conjunction. + + */ + + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + + // Generate the row multipliers computed by Reduce-and-Split from the + // given OsiSolverInterface. The multipliers are written in lambda; + // lambda should be of size nrow*maxNumMultipliers. We generate at most + // maxNumMultipliers m-vectors of row multipliers, and return the number + // of m-vectors that were generated. + // If the caller wants to know which variables are basic in each row + // (same order as lambda), basicVariables should be non-NULL (size nrow). + // This method can also generate the cuts corresponding to the multipliers + // returned; it suffices to pass non-NULL OsiCuts. + // This method is not needed by the typical user; however, it is useful + // in the context of generating Lift & Project cuts. + int generateMultipliers(const OsiSolverInterface& si, int* lambda, + int maxNumMultipliers, int* basicVariables = NULL, + OsiCuts* cs = NULL); + + // Try to improve a Lift & Project cut, by employing the + // Reduce-and-Split procedure. We start from a row of a L&P tableau, + // and generate a cut trying to reduce the coefficients on the + // nonbasic variables. Note that this L&P tableau will in general + // have nonbasic variables which are nonzero in the point that we + // want to cut off, so we should be careful. Arguments: + // OsiSolverInterface which contains the simplex tableau, initial + // row from which the cut is derived, row rhs, row number of the + // source row (if it is in the simplex tableau; otherwise, a + // negative number; needed to avoid using duplicate rows), point + // that we want to cut off (note: this is NOT a basic solution for + // the OsiSolverInterace!), list of variables which are basic in + // xbar but are nonbasic in the OsiSolverInterface. The computed cut + // is written in OsiRowCut* cs. Finally, if a starting disjunction + // is provided in the vector lambda (of size ncols, i.e. a + // disjunction on the structural variables), the disjunction is + // modified according to the cut which is produced. + int tiltLandPcut(const OsiSolverInterface* si, double* row, + double rowRhs, int rownumber, const double* xbar, + const int* newnonbasics, OsiRowCut* cs, int* lambda = NULL); + + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglRedSplit2Param object. + void setParam(const CglRedSplit2Param &source); + // Return the CglRedSplit2Param object of the generator. + inline CglRedSplit2Param& getParam() {return param;} + + /// Print some of the data members; used for debugging + void print() const; + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplit2(); + + /// Constructor with specified parameters + CglRedSplit2(const CglRedSplit2Param &RS_param); + + /// Copy constructor + CglRedSplit2(const CglRedSplit2 &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglRedSplit2 & operator=(const CglRedSplit2& rhs); + + /// Destructor + virtual ~CglRedSplit2 (); + + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglRedSplit2 members are + // properly set. This does the actual work. Returns the number of + // generated cuts (or multipliers). + // Will generate cuts if cs != NULL, and will generate multipliers + // if lambda != NULL. + int generateCuts(OsiCuts* cs, int maxNumCuts, int* lambda = NULL); + + /// Compute the fractional part of value, allowing for small error. + inline double rs_above_integer(const double value) const; + + /// Fill workNonBasicTab, depending on the column selection strategy. + /// Accepts a list of variables indices that should be ignored; by + /// default, this list is empty (it is only used by Lift & Project). + /// The list ignore_list contains -1 as the last element. + /// Note that the implementation of the ignore_list is not very efficient + /// if the list is long, so it should be used only if its short. + void fill_workNonBasicTab(CglRedSplit2Param::ColumnSelectionStrategy + strategy, const int* ignore_list = NULL); + + /// Fill workNonBasicTab, alternate version for Lift & Project: also + /// reduces columns which are now nonbasic but are basic in xbar. + /// This function should be called only when CglRedSplit2 is used in + /// conjunction with CglLandP to generate L&P+RS cuts. + void fill_workNonBasicTab(const int* newnonbasics, const double* xbar, + CglRedSplit2Param::ColumnScalingStrategy scaling); + + /// Reduce rows of workNonBasicTab, i.e. compute integral linear + /// combinations of the rows in order to reduce row coefficients on + /// workNonBasicTab + void reduce_workNonBasicTab(int numRows, + CglRedSplit2Param::RowSelectionStrategy + rowSelectionStrategy, + int maxIterations); + + /// Generate a linear combination of the rows of the current LP + /// tableau, using the row multipliers stored in the matrix pi_mat + /// on the row of index index_row + void generate_row(int index_row, double *row); + + /// Generate a mixed integer Gomory cut, when all non basic + /// variables are non negative and at their lower bound. + int generate_cgcut(double *row, double *rhs); + + /// Use multiples of the initial inequalities to cancel out the coefficients + /// of the slack variables. + void eliminate_slacks(double *row, + const double *elements, + const int *start, + const int *indices, + const int *rowLength, + const double *rhs, double *rowrhs); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound. + void flip(double *row); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. + void unflip(double *row, double *rowrhs); + + /// Returns 1 if the row has acceptable max/min coeff ratio. + /// Compute max_coeff: maximum absolute value of the coefficients. + /// Compute min_coeff: minimum absolute value of the coefficients + /// larger than EPS_COEFF. + /// Return 0 if max_coeff/min_coeff > MAXDYN. + int check_dynamism(double *row); + + /// Generate the packed cut from the row representation. + int generate_packed_row(const double *xlp, double *row, + int *rowind, double *rowelem, + int *card_row, double & rhs); + + // Compute entries of is_integer. + void compute_is_integer(); + + // Check that two vectors are different. + bool rs_are_different_vectors(const int *vect1, + const int *vect2, + const int dim); + + // allocate matrix of integers + void rs_allocmatINT(int ***v, int m, int n); + // deallocate matrix of integers + void rs_deallocmatINT(int ***v, int m); + // allocate matrix of doubles + void rs_allocmatDBL(double ***v, int m, int n); + // deallocate matrix of doubles + void rs_deallocmatDBL(double ***v, int m); + // print a vector of integers + void rs_printvecINT(const char *vecstr, const int *x, int n) const; + // print a vector of doubles + void rs_printvecDBL(const char *vecstr, const double *x, int n) const; + // print a matrix of integers + void rs_printmatINT(const char *vecstr, const int * const *x, int m, int n) const; + // print a matrix of doubles + void rs_printmatDBL(const char *vecstr, const double * const *x, int m, int n) const; + // dot product + double rs_dotProd(const double *u, const double *v, int dim) const; + double rs_dotProd(const int *u, const double *v, int dim) const; + // From Numerical Recipes in C: LU decomposition + int ludcmp(double **a, int n, int *indx, double *d, double* vv) const; + // from Numerical Recipes in C: backward substitution + void lubksb(double **a, int n, int *indx, double *b) const; + + // Check if the linear combination given by listOfRows with given multipliers + // improves the norm of row #rowindex; note: multipliers are rounded! + // Returns the difference with respect to the old norm (if negative there is + // an improvement, if positive norm increases) + double compute_norm_change(double oldnorm, const int* listOfRows, + int numElemList, const double* multipliers) const; + + // Compute the list of rows that should be used to reduce row #rowIndex + int get_list_rows_reduction(int rowIndex, int numRowsReduction, + int* list, const double* norm, + CglRedSplit2Param::RowSelectionStrategy + rowSelectionStrategy) const; + + // Sorts the rows by increasing number of nonzeroes with respect to a given + // row (rowIndex), on the nonbasic variables (whichTab == 0 means only + // integer, whichTab == 1 means only workTab, whichTab == 2 means both). + // The array for sorting must be allocated (and deleted) by caller. + // Corresponds to BRS1 in the paper. + int sort_rows_by_nonzeroes(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Greedy variant of the previous function; slower but typically + // more effective. Corresponds to BRS2 in the paper. + int sort_rows_by_nonzeroes_greedy(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Sorts the rows by decreasing absolute value of the cosine of the + // angle with respect to a given row (rowIndex), on the nonbasic + // variables (whichTab == 0 means only integer, whichTab == 1 means + // only workTab, whichTab == 2 means both). The array for sorting + // must be allocated (and deleted) by caller. Very effective + // strategy in practice. Corresponds to BRS3 in the paper. + int sort_rows_by_cosine(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Did we hit the time limit? + inline bool checkTime() const{ + if ((CoinCpuTime() - startTime) < param.getTimeLimit()){ + return true; + } + return false; + } + + //@} + + + // Private member data + + /**@name Private member data */ + + //@{ + + /// Object with CglRedSplit2Param members. + CglRedSplit2Param param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Number of rows which have been reduced + int numRedRows; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Reduced costs for columns + const double *reducedCost; + + /// Row price + const double *rowPrice; + + /// Objective coefficients + const double* objective; + + /// Number of integer basic structural variables + int card_intBasicVar; + + /// Number of integer basic structural variables that are fractional in the + /// current lp solution (at least param.away_ from being integer). + int card_intBasicVar_frac; + + /// Number of integer non basic structural variables in the + /// current lp solution. + int card_intNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current lp solution. + int card_contNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current working set for coefficient reduction + int card_workNonBasicVar; + + /// Number of non basic variables (structural or slack) at their + /// upper bound in the current lp solution. + int card_nonBasicAtUpper; + + /// Number of non basic variables (structural or slack) at their + /// lower bound in the current lp solution. + int card_nonBasicAtLower; + + /// Characteristic vector for integer basic structural variables + int *cv_intBasicVar; + + /// Characteristic vector for integer basic structural variables + /// with non integer value in the current lp solution. + int *cv_intBasicVar_frac; + + /// Characteristic vector for rows of the tableau selected for reduction + /// with non integer value in the current lp solution + int *cv_fracRowsTab; + + /// List of integer structural basic variables + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar; + + /// List of integer structural basic variables with fractional value + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar_frac; + + /// List of integer structural non basic variables. + int *intNonBasicVar; + + /// List of continuous non basic variables (structural or slack). + // slacks are considered continuous (no harm if this is not the case). + int *contNonBasicVar; + + /// List of non basic variables (structural or slack) at their + /// upper bound. + int *nonBasicAtUpper; + + /// List of non basic variables (structural or slack) at their lower + /// bound. + int *nonBasicAtLower; + + /// Number of rows in the reduced tableau (= card_intBasicVar). + int mTab; + + /// Number of columns in the reduced tableau (= card_contNonBasicVar) + int nTab; + + /// Tableau of multipliers used to alter the rows used in generation. + /// Dimensions: mTab by mTab. Initially, pi_mat is the identity matrix. + int **pi_mat; + + /// Simplex tableau for continuous non basic variables (structural or slack). + /// Only rows used for generation. + /// Dimensions: mTab by card_contNonBasicVar. + double **contNonBasicTab; + + /// Current tableau for continuous non basic variables (structural or slack). + /// Only columns used for coefficient reduction. + /// Dimensions: mTab by card_workNonBasicVar. + double **workNonBasicTab; + + /// Simplex tableau for integer non basic structural variables. + /// Only rows used for generation. + // Dimensions: mTab by card_intNonBasicVar. + double **intNonBasicTab; + + /// Right hand side of the tableau. + /// Only rows used for generation. + double *rhsTab; + + /// Norm of rows in workNonBasicTab; needed for faster computations + double *norm; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + int *is_integer; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + /// Time at which cut computations began. + /// Reset by each call to generateCuts(). + double startTime; + + //@} +}; + +//############################################################################# +/** A function that tests some of the methods in the CglRedSplit2 + class. The only reason for it not to be a member method is that + this way it doesn't have to be compiled into the library. And + that's a gain, because the library should be compiled with + optimization on, but this method should be compiled with + debugging. */ +void CglRedSplit2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglRedSplit2Param.hpp b/thirdparty/linux/include/coin/coin/CglRedSplit2Param.hpp new file mode 100644 index 0000000..369c676 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglRedSplit2Param.hpp @@ -0,0 +1,495 @@ +// Name: CglRedSplit2Param.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// Singapore +// email: nannicini@sutd.edu.sg +// Date: 03/09/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2010, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglRedSplit2Param_H +#define CglRedSplit2Param_H + +#include "CglParam.hpp" +#include <vector> + + /**@name CglRedSplit2 Parameters */ + //@{ + + /** Class collecting parameters the Reduced-and-split cut generator. + + An important thing to note is that the cut generator allows for + the selection of a number of strategies that can be combined + together. By default, a selection that typically yields a good + compromise between speed and cut strenght is made. The selection + can be changed by resetting the default choices (see the + functions whose name starts with "reset") or by setting the + parameter use_default_strategies to false in the + constructors. After this, the chosen strategies can be added to + the list by using the functions whose name starts with + "add". All strategies will be combined together: if we choose 3 + row selection strategies, 2 column selection strategies, and 2 + possible numbers of rows, we end up with a total of 3*2*2 + combinations. + + For a detailed explanation of the parameters and their meaning, + see the paper by Cornuejols and Nannicini: "Practical strategies + for generating rank-1 split cuts in mixed-integer linear + programming", on Mathematical Programming Computation. + + Parameters of the generator are listed below. + + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - EPS_RELAX_ABS: Absolute relaxation of cut rhs. + - EPS_RELAX_REL: Relative relaxation of cut rhs. + - MAX_SUPP_ABS: Maximum cut support (absolute). + - MAX_SUPP_REL: Maximum cut support (relative): the formula to + compute maximum cut support is + MAX_SUPP_ABS + ncol*MAX_SUPP_REL. + - USE_INTSLACKS: Use integer slacks to generate cuts. (not implemented). + See method setUSE_INTSLACKS(). + - normIsZero: Norm of a vector is considered zero if smaller than + this value. See method setNormIsZero(). + - minNormReduction: a cut is generated if the new norm of the row on the + continuous nonbasics is reduced by at least + this factor (relative reduction). + - away: Look only at basic integer variables whose current value + is at least this value from being integer. See method setAway(). + - maxSumMultipliers: maximum sum (in absolute value) of row multipliers + - normalization: normalization factor for the norm of lambda in the + coefficient reduction algorithm (convex min problem) + - numRowsReduction: Maximum number of rows in the linear system for + norm reduction. + - columnSelectionStrategy: parameter to select which columns should be + used for coefficient reduction. + - rowSelectionStrategy: parameter to select which rows should be + used for coefficient reduction. + - timeLimit: Time limit (in seconds) for cut generation. + - maxNumCuts: Maximum number of cuts that can be returned at each pass; + we could generate more cuts than this number (see below) + - maxNumComputedCuts: Maximum number of cuts that can be computed + by the generator at each pass + - maxNonzeroesTab : Rows of the simplex tableau with more than + this number of nonzeroes will not be + considered for reduction. Only works if + RS_FAST_* are defined in CglRedSplit2. + - skipGomory: Skip traditional Gomory cuts, i.e. GMI cuts arising from + a single row of the tableau (instead of a combination). + Default is 1 (true), because we assume that they are + generated by a traditional Gomory generator anyway. + */ + //@} + +class CglRedSplit2Param : public CglParam { + +public: + /** Enumerations for parameters */ + + /** Row selection strategies; same names as in the paper */ + enum RowSelectionStrategy{ + /* Pick rows that introduce the fewest nonzeroes on integer nonbasics */ + RS1, + /* Pick rows that introduce the fewest nonzeroes on the set of working + continuous nonbasics */ + RS2, + /* Pick rows that introduce the fewest nonzeroes on both integer and + working continuous nonbasics */ + RS3, + /* Same as RS0 but with greedy algorithm */ + RS4, + /* Same as RS1 but with greedy algorithm */ + RS5, + /* Same as RS2 but with greedy algorithm */ + RS6, + /* Pick rows with smallest angle in the space of integer and working + continuous nonbasics */ + RS7, + /* Pick rows with smallest angle in the space of working + continuous nonbasics */ + RS8, + /* Use all strategies */ + RS_ALL, + /* Use best ones - that is, RS8 and RS7 */ + RS_BEST + }; + + /** Column selection strategies; again, look them up in the paper. */ + enum ColumnSelectionStrategy{ + /* C-3P */ + CS1, CS2, CS3, + /* C-5P */ + CS4, CS5, CS6, CS7, CS8, + /* I-2P-2/3 */ + CS9, CS10, + /* I-2P-4/5 */ + CS11, CS12, + /* I-2P-1/2 */ + CS13, CS14, + /* I-3P */ + CS15, CS16, CS17, + /* I-4P */ + CS18, CS19, CS20, CS21, + /* Use all strategies up to this point */ + CS_ALL, + /* Use best strategies (same effect as CS_ALL, because it turns out that + using all strategies is the best thing to do) */ + CS_BEST, + /* Optimize over all continuous nonbasic columns; this does not give + good results, but we use it for testing Lift & Project + RedSplit */ + CS_ALLCONT, + /* Lift & Project specific strategy: only select variables which + are nonbasic in the tableau but are basic in the point to cut + off. This strategy cannot be used outside L&P. It is not very + effective even with L&P, but is left here for testing.*/ + CS_LAP_NONBASICS + }; + + /** Scaling strategies for new nonbasic columns for Lift & Project; + * "factor" is the value of columnScalingBoundLAP_ */ + enum ColumnScalingStrategy{ + /* No scaling */ + SC_NONE, + /* Multiply by |xbar[i]| where xbar[i] is the value of the + corresponding component of the point that we want to cut off */ + SC_LINEAR, + /* Multiply by min(factor,|xbar[i]|) */ + SC_LINEAR_BOUNDED, + /* Multiply by min(factor,log(|xbar[i]|)) */ + SC_LOG_BOUNDED, + /* Multiply all new nonbasics by factor */ + SC_UNIFORM, + /* Multiply only nonzero coefficients by factor */ + SC_UNIFORM_NZ + }; + + /**@name Set/get methods */ + //@{ + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.005 */ + virtual void setAway(double value); + /// Get value of away + inline double getAway() const {return away_;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 0.0 */ + void setEPS_ELIM(double value); + /** Get the value of EPS_ELIM */ + double getEPS_ELIM() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(double eps_ra); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(double eps_rr); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-3 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + + /** Maximum absolute support of the cutting planes. Default: INT_MAX. + Aliases for consistency with our naming scheme. */ + inline void setMAX_SUPP_ABS(int value) {setMAX_SUPPORT(value);} + inline int getMAX_SUPP_ABS() const {return MAX_SUPPORT;} + + /** Maximum relative support of the cutting planes. Default: 0.0. + The maximum support is MAX_SUPP_ABS + MAX_SUPPREL*ncols. */ + inline void setMAX_SUPP_REL(double value); + inline double getMAX_SUPP_REL() const {return MAX_SUPP_REL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(int value); + /** Get the value of USE_INTSLACKS */ + inline int getUSE_INTSLACKS() const {return USE_INTSLACKS;} + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + virtual void setNormIsZero(double value); + /** Get the value of normIsZero */ + inline double getNormIsZero() const {return normIsZero_;} + + /** Set the value of minNormReduction; Default: 0.1 */ + virtual void setMinNormReduction(double value); + /** Get the value of normIsZero */ + inline double getMinNormReduction() const {return minNormReduction_;} + + /** Set the value of maxSumMultipliers; Default: 10 */ + virtual void setMaxSumMultipliers(int value); + /** Get the value of maxSumMultipliers */ + inline int getMaxSumMultipliers() const {return maxSumMultipliers_;} + + /** Set the value of normalization; Default: 0.0001 */ + virtual void setNormalization(double value); + /** Get the value of normalization */ + inline double getNormalization() const {return normalization_;} + + /** Set the value of numRowsReduction, max number of rows that are used + * for each row reduction step. In particular, the linear system will + * involve a numRowsReduction*numRowsReduction matrix */ + virtual void addNumRowsReduction(int value); + /// get the value + inline std::vector<int> getNumRowsReduction() const {return numRowsReduction_;} + /// reset + inline void resetNumRowsReduction() {numRowsReduction_.clear();} + + /** Add the value of columnSelectionStrategy */ + virtual void addColumnSelectionStrategy(ColumnSelectionStrategy value); + /// get the value + inline std::vector<ColumnSelectionStrategy> getColumnSelectionStrategy() const {return columnSelectionStrategy_;} + /// reset + inline void resetColumnSelectionStrategy(){columnSelectionStrategy_.clear();} + + /** Set the value for rowSelectionStrategy, which changes the way we choose + * the rows for the reduction step */ + virtual void addRowSelectionStrategy(RowSelectionStrategy value); + /// get the value + inline std::vector<RowSelectionStrategy> getRowSelectionStrategy() const {return rowSelectionStrategy_;}; + /// reset + inline void resetRowSelectionStrategy() {rowSelectionStrategy_.clear();} + + /** Set the value of numRowsReductionLAP, max number of rows that are used + * for each row reduction step during Lift & Project. + * In particular, the linear system will involve a + * numRowsReduction*numRowsReduction matrix */ + virtual void addNumRowsReductionLAP(int value); + /// get the value + inline std::vector<int> getNumRowsReductionLAP() const {return numRowsReductionLAP_;} + /// reset + inline void resetNumRowsReductionLAP() {numRowsReductionLAP_.clear();} + + /** Add the value of columnSelectionStrategyLAP */ + virtual void addColumnSelectionStrategyLAP(ColumnSelectionStrategy value); + /// get the value + inline std::vector<ColumnSelectionStrategy> getColumnSelectionStrategyLAP() const {return columnSelectionStrategyLAP_;} + /// reset + inline void resetColumnSelectionStrategyLAP(){columnSelectionStrategyLAP_.clear();} + + /** Set the value for rowSelectionStrategyLAP, which changes the way we + * choose the rows for the reduction step */ + virtual void addRowSelectionStrategyLAP(RowSelectionStrategy value); + /// get the value + inline std::vector<RowSelectionStrategy> getRowSelectionStrategyLAP() const {return rowSelectionStrategyLAP_;}; + /// reset + inline void resetRowSelectionStrategyLAP() {rowSelectionStrategyLAP_.clear();} + + /** Set the value for columnScalingStrategyLAP, which sets the way nonbasic + * columns that are basic in the fractional point to cut off are scaled */ + virtual void setColumnScalingStrategyLAP(ColumnScalingStrategy value); + /// get the value + inline ColumnScalingStrategy getColumnScalingStrategyLAP() const {return columnScalingStrategyLAP_; }; + + /** Set the value for the bound in the column scaling factor */ + virtual void setColumnScalingBoundLAP(double value); + /// get the value + inline double getColumnScalingBoundLAP() const {return columnScalingBoundLAP_;}; + + /** Set the value of the time limit for cut generation (in seconds) */ + virtual void setTimeLimit(double value); + /// get the value + inline double getTimeLimit() const {return timeLimit_;} + + /** Set the value for the maximum number of cuts that can be returned */ + virtual void setMaxNumCuts(int value); + /// get the value + inline int getMaxNumCuts() const {return maxNumCuts_;} + + /** Set the value for the maximum number of cuts that can be computed */ + virtual void setMaxNumComputedCuts(int value); + /// get the value + inline int getMaxNumComputedCuts() const {return maxNumComputedCuts_;} + + /** Set the value for the maximum number of nonzeroes in a row of + * the simplex tableau for the row to be considered */ + virtual void setMaxNonzeroesTab(int value); + /// get the value + inline int getMaxNonzeroesTab() const {return maxNonzeroesTab_;} + + /** Set the value of skipGomory: should we skip simple Gomory cuts, + * i.e. GMI cuts derived from a single row of the simple tableau? + * This is 1 (true) by default: we only generate cuts from linear + * combinations of at least two rows. */ + virtual void setSkipGomory(int value); + /// get the value + inline int getSkipGomory() const {return skipGomory_;} + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor. If use_default_strategies is true, we add + /// to the list of strategies the default ones. If is false, the + /// list of strategies is left empty (must be populated before usage!). + CglRedSplit2Param(bool use_default_strategies = true, + double eps = 1e-12, + double eps_coeff = 1e-11, + double eps_elim = 0.0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-3, + int max_supp_abs = 1000, + double max_supp_rel = 0.1, + int use_int_slacks = 0, + double norm_zero = 1e-5, + double minNormReduction = 0.1, + int maxSumMultipliers = 10, + double normalization = 0.0001, + double away = 0.005, + double timeLimit = 60, + int maxNumCuts = 10000, + int maxNumComputedCuts = 10000, + int maxNonzeroesTab = 1000, + double columnScalingBoundLAP = 5.0, + int skipGomory = 1); + + /// Constructor from CglParam. If use_default_strategies is true, we + /// add to the list of strategies the default ones. If is false, the + /// list of strategies is left empty (must be populated before + /// usage!). + CglRedSplit2Param(const CglParam &source, + bool use_default_strategies = true, + double eps_elim = 0.0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-3, + double max_supp_rel = 0.1, + int use_int_slacks = 0, + double norm_zero = 1e-5, + double minNormReduction = 0.1, + int maxSumMultipliers = 10, + double normalization = 0.0001, + double away = 0.005, + double timeLimit = 60, + int maxNumCuts = 10000, + int maxNumComputedCuts = 10000, + int maxNonzeroesTab = 1000, + double columnScalingBoundLAP = 5.0, + int skipGomory = 1); + + /// Copy constructor + CglRedSplit2Param(const CglRedSplit2Param &source); + + /// Clone + virtual CglRedSplit2Param* clone() const; + + /// Assignment operator + virtual CglRedSplit2Param& operator=(const CglRedSplit2Param &rhs); + + /// Destructor + virtual ~CglRedSplit2Param(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 0.0. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-11 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 1e-13 */ + double EPS_RELAX_REL; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + double MAXDYN; + + /// Minimum violation for the current basic solution in a generated cut. + /// Default: 1e-3. + double MINVIOL; + + /// Maximum support - relative part of the formula + double MAX_SUPP_REL; + + /// Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. + int USE_INTSLACKS; + + /// Norm of a vector is considered zero if smaller than normIsZero; + /// Default: 1e-5. + double normIsZero_; + + /// Minimum reduction to accept a new row. + double minNormReduction_; + + /// Maximum sum of the vector of row multipliers to generate a cut + int maxSumMultipliers_; + + /// Normalization factor for the norm of lambda in the quadratic + /// minimization problem that is solved during the coefficient reduction step + double normalization_; + + /// Use row only if pivot variable should be integer but is more + /// than away_ from being integer. Default: 0.005 + double away_; + + /// Maximum number of rows to use for the reduction of a given row. + std::vector<int> numRowsReduction_; + + /// Column selection method + std::vector<ColumnSelectionStrategy> columnSelectionStrategy_; + + /// Row selection method + std::vector<RowSelectionStrategy> rowSelectionStrategy_; + + /// Maximum number of rows to use for the reduction during Lift & Project + std::vector<int> numRowsReductionLAP_; + + /// Column selection method for Lift & Project + std::vector<ColumnSelectionStrategy> columnSelectionStrategyLAP_; + + /// Row selection method for Lift & Project + std::vector<RowSelectionStrategy> rowSelectionStrategyLAP_; + + /// Column scaling strategy for the nonbasics columns that were basic in + /// the point that we want to cut off (Lift & Project only) + ColumnScalingStrategy columnScalingStrategyLAP_; + + /// Minimum value for column scaling (Lift & Project only) + double columnScalingBoundLAP_; + + /// Time limit + double timeLimit_; + + /// Maximum number of returned cuts + int maxNumCuts_; + + /// Maximum number of computed cuts + int maxNumComputedCuts_; + + /// Maximum number of nonzeroes in tableau row for reduction + int maxNonzeroesTab_; + + /// Skip simple Gomory cuts + int skipGomory_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglRedSplitParam.hpp b/thirdparty/linux/include/coin/coin/CglRedSplitParam.hpp new file mode 100644 index 0000000..2601fb2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglRedSplitParam.hpp @@ -0,0 +1,272 @@ +// Name: CglRedSplitParam.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 11/24/06 +// +// $Id: CglRedSplitParam.hpp 1122 2013-04-06 20:39:53Z stefan $ +//----------------------------------------------------------------------------- +// Copyright (C) 2006, Francois Margot and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglRedSplitParam_H +#define CglRedSplitParam_H + +#include "CglParam.hpp" + + + /**@name CglRedSplit Parameters */ + //@{ + + /** Class collecting parameters the Reduced-and-split cut generator. + + Parameters of the generator are listed below. Modifying the default + values for parameters other than the last four might result in + invalid cuts. + + - LUB: Value considered large for the absolute value of a lower or upper + bound on a variable. See method setLUB(). + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - MAXDYN_LUB: Maximum ratio between largest and smallest non zero + coefficients in a cut involving structural variables with + lower or upper bound in absolute value larger than LUB. + Should logically be larger or equal to MAXDYN. + See method setMAXDYN_LUB(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - EPS_COEFF_LUB: Precision for deciding if a coefficient of a + generated cut is zero when the corresponding + variable has a lower or upper bound larger than + LUB in absolute value. See method setEPS_COEFF_LUB(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - USE_INTSLACKS: Use integer slacks to generate cuts. (not implemented). + See method setUSE_INTSLACKS(). + - USE_CG2: Use alternative formula to generate a mixed integer Gomory + cut (see methods CglRedSPlit::generate_cgcut() + and CglRedSPlit::generate_cgcut_2()). See method setUSE_CG2(). + - normIsZero: Norm of a vector is considered zero if smaller than + this value. See method setNormIsZero(). + - minReduc: Reduction is performed only if the norm of the vector is + reduced by this fraction. See method setMinReduc(). + - away: Look only at basic integer variables whose current value + is at least this value from being integer. See method setAway(). + - maxTab: Controls the number of rows selected for the generation. See + method setMaxTab(). + */ + //@} + +class CglRedSplitParam : public CglParam { + +public: + + /**@name Set/get methods */ + //@{ + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.05 */ + virtual void setAway(const double value); + /// Get value of away + inline double getAway() const {return away_;} + + /** Set the value of LUB, value considered large for the absolute value of + a lower or upper bound on a variable; + Default: 1000 */ + virtual void setLUB(const double value); + /** Get the value of LUB */ + inline double getLUB() const {return LUB;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 1e-12 */ + void setEPS_ELIM(const double value); + /** Get the value of EPS_ELIM */ + double getEPS_ELIM() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(const double eps_ra); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(const double eps_rr); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e8. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN_LUB;} + + // Set the maximum ratio between largest and smallest non zero + // coefficient in a cut involving structural variables with + // lower or upper bound in absolute value larger than LUB. + // Should logically be larger or equal to MAXDYN. Default: 1e13. + virtual void setMAXDYN_LUB(double value); + /** Get the value of MAXDYN_LUB */ + inline double getMAXDYN_LUB() const {return MAXDYN_LUB;} + + /** Set the value of EPS_COEFF_LUB, epsilon for values of coefficients for + variables with absolute value of lower or upper bound larger than LUB; + Default: 1e-13 */ + virtual void setEPS_COEFF_LUB(const double value); + /** Get the value of EPS_COEFF_LUB */ + inline double getEPS_COEFF_LUB() const {return EPS_COEFF_LUB;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-7 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(int value); + /** Get the value of USE_INTSLACKS */ + inline int getUSE_INTSLACKS() const {return USE_INTSLACKS;} + + /** Set the value of USE_CG2. Default: 0 */ + virtual void setUSE_CG2(int value); + /** Get the value of USE_CG2 */ + inline int getUSE_CG2() const {return USE_CG2;} + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + virtual void setNormIsZero(const double value); + /** Get the value of normIsZero */ + inline double getNormIsZero() const {return normIsZero;} + + /** Set the value of minReduc, threshold for relative norm improvement for + performing a reduction; Default: 0.05 */ + virtual void setMinReduc(const double value); + /// Get the value of minReduc + inline double getMinReduc() const {return minReduc;} + + /** Set the maximum allowed value for (mTab * mTab * CoinMax(mTab, nTab)) where + mTab is the number of rows used in the combinations and nTab is the + number of continuous non basic variables. The work of the generator is + proportional to (mTab * mTab * CoinMax(mTab, nTab)). Reducing the value of + maxTab makes the generator faster, but weaker. Default: 1e7. */ + virtual void setMaxTab(const double value); + /// Get the value of maxTab + inline double getMaxTab() const {return maxTab_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplitParam(const double lub = 1000.0, + const double eps_elim = 1e-12, + const double eps_relax_abs = 1e-8, + const double eps_relax_rel = 0.0, + const double max_dyn = 1e8, + const double max_dyn_lub = 1e13, + const double eps_coeff_lub = 1e-13, + const double min_viol = 1e-7, + const int use_int_slacks = 0, + const int use_cg2 = 0, + const double norm_zero = 1e-5, + const double min_reduc = 0.05, + const double away = 0.05, + const double max_tab = 1e7); + + /// Constructor from CglParam + CglRedSplitParam(const CglParam &source, + const double lub = 1000.0, + const double eps_elim = 1e-12, + const double eps_relax_abs = 1e-8, + const double eps_relax_rel = 0.0, + const double max_dyn = 1e8, + const double max_dyn_lub = 1e13, + const double eps_coeff_lub = 1e-13, + const double min_viol = 1e-7, + const int use_int_slacks = 0, + const int use_cg2 = 0, + const double norm_zero = 1e-5, + const double min_reduc = 0.05, + const double away = 0.05, + const double max_tab = 1e7); + + /// Copy constructor + CglRedSplitParam(const CglRedSplitParam &source); + + /// Clone + virtual CglRedSplitParam* clone() const; + + /// Assignment operator + virtual CglRedSplitParam& operator=(const CglRedSplitParam &rhs); + + /// Destructor + virtual ~CglRedSplitParam(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Value considered large for the absolute value of lower or upper + bound on a variable. Default: 1000. */ + double LUB; + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 1e-12. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-8 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 0 */ + double EPS_RELAX_REL; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e8. + double MAXDYN; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut involving structural variables with + // lower or upper bound in absolute value larger than LUB. + // Should logically be larger or equal to MAXDYN. Default: 1e13. + double MAXDYN_LUB; + + /// Epsilon for value of coefficients for variables with absolute value of + /// lower or upper bound larger than LUB. Default: 1e-13. + double EPS_COEFF_LUB; + + /// Minimum violation for the current basic solution in a generated cut. + /// Default: 1e-7. + double MINVIOL; + + /// Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. + int USE_INTSLACKS; + + /// Use second way to generate a mixed integer Gomory cut + /// (see methods generate_cgcut()) and generate_cgcut_2()). Default: 0. + int USE_CG2; + + /// Norm of a vector is considered zero if smaller than normIsZero; + /// Default: 1e-5. + double normIsZero; + + /// Minimum reduction in percent that must be achieved by a potential + /// reduction step in order to be performed; Between 0 and 1, default: 0.05. + double minReduc; + + /// Use row only if pivot variable should be integer but is more + /// than away_ from being integer. + double away_; + + /// Maximum value for (mTab * mTab * CoinMax(mTab, nTab)). See method + /// setMaxTab(). + double maxTab_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglResidualCapacity.hpp b/thirdparty/linux/include/coin/coin/CglResidualCapacity.hpp new file mode 100644 index 0000000..1e26e46 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglResidualCapacity.hpp @@ -0,0 +1,240 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// Implementation of Residual Capacity Inequalities +// Francisco Barahona (barahon@us.ibm.com) +// +// date: May 18, 2006 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglResidualCapacity_H +#define CglResidualCapacity_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + + + + +//============================================================================= + +/** Residual Capacity Inequalities Cut Generator Class + + References: + T Magnanti, P Mirchandani, R Vachani, + "The convex hull of two core capacitated network design problems," + Math Programming 60 (1993), 233-250. + + A Atamturk, D Rajan, + "On splittable and unsplittable flow capacitated network design + arc-set polyhedra," Math Programming 92 (2002), 315-333. **/ + +class CglResidualCapacity : public CglCutGenerator { + + friend void CglResidualCapacityUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + /** row of the type a_1 c_1 + + a_k c_k - d z_1 - - d z_p <= b, + where c_i are continuous variables and z_j are integer variables + */ + ROW_L, + /** row of the type -a_1 c_1 - - a_k c_k + d z_1 + + d z_p >= b, + where c_i are continuous variables and z_j are integer variables + */ + ROW_G, + /** equation that can be treated as ROW_L and ROW_G + */ + ROW_BOTH, + /** Other types of rows + */ + ROW_OTHER + }; + + +public: + /**@name Get and Set Parameters */ + //@{ + /// Set Epsilon + void setEpsilon(double value); + /// Get Epsilon + double getEpsilon() const; + /// Set Tolerance + void setTolerance(double value); + /// Get Tolerance + double getTolerance() const; + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + //@} + + /**@name Generate Cuts */ + //@{ + /** Generate Residual Capacity cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglResidualCapacity (); + + /// Alternate Constructor + CglResidualCapacity ( const double tolerance ); + + /// Copy constructor + CglResidualCapacity ( + const CglResidualCapacity &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglResidualCapacity & + operator=( + const CglResidualCapacity& rhs); + + /// Destructor + virtual + ~CglResidualCapacity (); + /// This is to refresh preprocessing + virtual void refreshPrep(); + //@} + + + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct ( const double tolerance); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglResidualCapacity& rhs); + + // Do preprocessing. + // It determines the type of each row. + // It may change sense and RHS for ranged rows + void resCapPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs, + const double* colLowerBound, + const double* colUpperBound) const; + // helps the function above + bool treatAsLessThan(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, + const double rhs, + const double* colLowerBound, + const double* colUpperBound) const; + + // Generate Residual Capacity cuts + void generateResCapCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + const double* coefByRow, + const int* colInds, + const int* rowStarts, + const int* rowLengths, + OsiCuts& cs ) const; + + + // Residual Capacity separation + bool resCapSeparation(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, + const double rhs, + const double *xlp, + const double* colUpperBound, + const double* colLowerBound, + OsiRowCut& resCapCut) const; + + + +private: + //--------------------------------------------------------------------------- + // Private member data + /** Tolerance used for numerical purposes, default value: 1.e-6 **/ + double EPSILON_; + /** If violation of a cut is greater that this number, + the cut is accepted, default value: 1.e-4 **/ + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + // The number of rows of type ROW_L + int numRowL_; + // The indices of the rows of type ROW_L + int* indRowL_; + // The number of rows of type ROW_G + int numRowG_; + // The indices of the rows of type ROW_G + int* indRowG_; +}; + +//############################################################################# +/** A function that tests the methods in the CglResidualCapacity class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglResidualCapacityUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglSimpleRounding.hpp b/thirdparty/linux/include/coin/coin/CglSimpleRounding.hpp new file mode 100644 index 0000000..b93c8bf --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglSimpleRounding.hpp @@ -0,0 +1,174 @@ +// $Id: CglSimpleRounding.hpp 1149 2013-10-21 18:23:53Z tkr $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglSimpleRounding_H +#define CglSimpleRounding_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinPackedMatrix.hpp" + +/** Simple Rounding Cut Generator Class + + This class generates simple rounding cuts via the following method: + For each contraint, + attempt to derive a <= inequality in all integer variables + by netting out any continuous variables. + Divide the resulting integer inequality through by + the greatest common denomimator (gcd) of the lhs coefficients. + Round down the rhs. + + Warning: Use with careful attention to data precision. + + (Reference: Nemhauser and Wolsey, Integer and Combinatorial Optimization, 1988, pg 211.) +*/ + +class CglSimpleRounding : public CglCutGenerator { + friend void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate simple rounding cuts for the model accessed through the solver interface. + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglSimpleRounding (); + + /// Copy constructor + CglSimpleRounding ( + const CglSimpleRounding &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglSimpleRounding & + operator=( + const CglSimpleRounding& rhs); + + /// Destructor + virtual + ~CglSimpleRounding (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + + /// Derive a <= inequality in integer variables from the rowIndex-th constraint + bool deriveAnIntegerRow( + const OsiSolverInterface & si, + int rowIndex, + const CoinShallowPackedVector & matrixRow, + CoinPackedVector & irow, + double & b, + bool * negative) const; + + + /** Given a vector of doubles, x, with size elements and a positive tolerance, + dataTol, this method returns the smallest power of 10 needed so that + x[i]*10**power "is integer" for all i=0,...,size-1. + + ** change of definition of dataTol so that it refers to original + data, not to scaled data as that seems to lead to problems. + + So if xScaled is x[i]*10**power and xInt is rounded(xScaled) + then fabs(xScaled-xInt) <= dataTol*10**power. This means that + dataTol should be smaller - say 1.0e-12 rather tahn 1.0e-8 + + Returns -number of times overflowed if the power is so big that it will + cause overflow (i.e. integer stored will be bigger than 2**31). + Test in cut generator. + */ + int power10ToMakeDoubleAnInt( + int size, // the length of the vector x + const double * x, + double dataTol ) const; // the precision of the data, i.e. the positive + // epsilon, which is equivalent to zero + + /**@name Greatest common denominators methods */ + //@{ + /// Returns the greatest common denominator of two positive integers, a and b. + inline int gcd(int a, int b) const; + + /** Returns the greatest common denominator of a vector of + positive integers, vi, of length n. + */ + inline int gcdv(int n, const int * const vi) const; + //@} + + //@} + + /**@name Private member data */ + //@{ + /// A value within an epsilon_ neighborhood of 0 is considered to be 0. + double epsilon_; + //@} +}; + + +//------------------------------------------------------------------- +// Returns the greatest common denominator of two +// positive integers, a and b, found using Euclid's algorithm +//------------------------------------------------------------------- +int +CglSimpleRounding::gcd(int a, int b) const +{ + if(a > b) { + // Swap a and b + int temp = a; + a = b; + b = temp; + } + int remainder = b % a; + if (remainder == 0) return a; + else return gcd(remainder,a); +} + +//------------------------------------------------------------------- +// Returns the greatest common denominator of a vector of +// positive integers, vi, of length n. +//------------------------------------------------------------------- +int +CglSimpleRounding::gcdv(int n, const int* const vi) const +{ + if (n==0) + abort(); + + if (n==1) + return vi[0]; + + int retval=gcd(vi[0], vi[1]); + for (int i=2; i<n; i++){ + retval=gcd(retval,vi[i]); + } + return retval; +} + +//############################################################################# +/** A function that tests the methods in the CglSimpleRounding class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglStored.hpp b/thirdparty/linux/include/coin/coin/CglStored.hpp new file mode 100644 index 0000000..07039d9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglStored.hpp @@ -0,0 +1,125 @@ +// $Id: CglStored.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglStored_H +#define CglStored_H + +#include <string> + +#include "CglCutGenerator.hpp" + +class CoinWarmStartBasis; +class CglTreeProbingInfo; +/** Stored Cut Generator Class */ +class CglStored : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Stored cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + This generator just looks at previously stored cuts + and inserts any that are violated by enough + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Change criterion on whether to include cut. + Violations of more than this will be added to current cut list + (default 1.0e-5) */ + //@{ + /// Set + inline void setRequiredViolation(double value) + { requiredViolation_=value;} + /// Get + inline double getRequiredViolation() const + { return requiredViolation_;} + /// Takes over ownership of probing info + inline void setProbingInfo(CglTreeProbingInfo * info) + { probingInfo_ = info;} + //@} + + /**@name Cut stuff */ + //@{ + /// Add cuts + void addCut(const OsiCuts & cs); + /// Add a row cut + void addCut(const OsiRowCut & cut); + /// Add a row cut from a packed vector + void addCut(double lb, double ub, const CoinPackedVector & vector); + /// Add a row cut from elements + void addCut(double lb, double ub, int size, const int * colIndices, const double * elements); + inline int sizeRowCuts() const + { return cuts_.sizeRowCuts();} + const OsiRowCut * rowCutPointer(int index) const + { return cuts_.rowCutPtr(index);} + /// Save stuff + void saveStuff(double bestObjective, const double * bestSolution, + const double * lower, const double * upper); + /// Best solution (or NULL) + inline const double * bestSolution() const + { return bestSolution_;} + /// Best objective + double bestObjective() const; + /// Tight lower bounds + const double * tightLower() const + { return bounds_;} + /// Tight upper bounds + const double * tightUpper() const + { return bounds_+numberColumns_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglStored (int numberColumns=0); + + /// Copy constructor + CglStored (const CglStored & rhs); + + /// Constructor from file + CglStored (const char * fileName); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglStored & + operator=(const CglStored& rhs); + + /// Destructor + virtual + ~CglStored (); + //@} + +protected: + + // Protected member methods + + // Protected member data + + /**@name Protected member data */ + //@{ + /// Only add if more than this requiredViolation + double requiredViolation_; + /// Pointer to probing information + CglTreeProbingInfo * probingInfo_; + /// Cuts + OsiCuts cuts_; + /// Number of columns in model + int numberColumns_; + /// Best solution (objective at end) + double * bestSolution_; + /// Tight bounds + double * bounds_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CglTreeInfo.hpp b/thirdparty/linux/include/coin/coin/CglTreeInfo.hpp new file mode 100644 index 0000000..4f85aca --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglTreeInfo.hpp @@ -0,0 +1,180 @@ +// $Id: CglTreeInfo.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglTreeInfo_H +#define CglTreeInfo_H + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" +#include "CoinHelperFunctions.hpp" +class CglStored; +/** Information about where the cut generator is invoked from. */ + +class CglTreeInfo { +public: + /// The level of the search tree node + int level; + /** How many times the cut generator was already invoked in this search tree + node */ + int pass; + /** The number of rows in the original formulation. Some generators may not + want to consider already generated rows when generating new ones. */ + int formulation_rows; + /** Options + 1 - treat costed integers as important + 2 - switch off some stuff as variables semi-integer + 4 - set global cut flag if at root node + 8 - set global cut flag if at root node and first pass + 16 - set global cut flag and make cuts globally valid + 32 - last round of cuts did nothing - maybe be more aggressive + 64 - in preprocessing stage + 128 - looks like solution + 256 - want alternate cuts + 512 - in sub tree (i.e. parent model) + 1024 - in must call again mode or after everything mode + */ + int options; + /// Set true if in tree (to avoid ambiguity at first branch) + bool inTree; + /** Replacement array. Before Branch and Cut it may be beneficial to strengthen rows + rather than adding cuts. If this array is not NULL then the cut generator can + place a pointer to the stronger cut in this array which is number of rows in size. + + A null (i.e. zero elements and free rhs) cut indicates that the row is useless + and can be removed. + + The calling function can then replace those rows. + */ + OsiRowCut ** strengthenRow; + /// Optional pointer to thread specific random number generator + CoinThreadRandom * randomNumberGenerator; + /// Default constructor + CglTreeInfo (); + + /// Copy constructor + CglTreeInfo ( + const CglTreeInfo &); + /// Clone + virtual CglTreeInfo * clone() const; + + /// Assignment operator + CglTreeInfo & + operator=( + const CglTreeInfo& rhs); + + /// Destructor + virtual + ~CglTreeInfo (); + /// Take action if cut generator can fix a variable (toValue -1 for down, +1 for up) + virtual bool fixes(int , int , int ,bool) {return false;} + /** Initalizes fixing arrays etc - returns >0 if we want to save info + 0 if we don't and -1 if is to be used */ + virtual int initializeFixing(const OsiSolverInterface * ) {return 0;} + +}; + +/** Derived class to pick up probing info. */ +typedef struct { + //unsigned int oneFixed:1; // nonzero if variable to 1 fixes all + //unsigned int sequence:31; // variable (in matrix) (but also see cliqueRow_) + unsigned int fixes; +} CliqueEntry; + +class CglTreeProbingInfo : public CglTreeInfo { +public: + /// Default constructor + CglTreeProbingInfo (); + /// Constructor from model + CglTreeProbingInfo (const OsiSolverInterface * model); + + /// Copy constructor + CglTreeProbingInfo ( + const CglTreeProbingInfo &); + /// Clone + virtual CglTreeInfo * clone() const; + + /// Assignment operator + CglTreeProbingInfo & + operator=( + const CglTreeProbingInfo& rhs); + + /// Destructor + virtual + ~CglTreeProbingInfo (); + OsiSolverInterface * analyze(const OsiSolverInterface & si, int createSolver=0, + int numberExtraCliques=0,const int * starts=NULL, + const CliqueEntry * entries=NULL,const char * type=NULL); + /** Take action if cut generator can fix a variable + (toValue -1 for down, +1 for up) + Returns true if still room, false if not */ + virtual bool fixes(int variable, int toValue, int fixedVariable,bool fixedToLower); + /** Initalizes fixing arrays etc - returns >0 if we want to save info + 0 if we don't and -1 if is to be used */ + virtual int initializeFixing(const OsiSolverInterface * model) ; + /// Fix entries in a solver using implications + int fixColumns(OsiSolverInterface & si) const; + /// Fix entries in a solver using implications for one variable + int fixColumns(int iColumn, int value, OsiSolverInterface & si) const; + /// Packs down entries + int packDown(); + /// Generate cuts from implications + void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info) const; + /// Entries for fixing variables + inline CliqueEntry * fixEntries() + { convert(); return fixEntry_;} + /// Starts of integer variable going to zero + inline int * toZero() + { convert(); return toZero_;} + /// Starts of integer variable going to one + inline int * toOne() + { convert(); return toOne_;} + /// List of 0-1 integer variables + inline int * integerVariable() const + { return integerVariable_;} + /// Backward look up + inline int * backward() const + { return backward_;} + /// Number of variables + inline int numberVariables() const + { return numberVariables_;} + /// Number of 0-1 variables + inline int numberIntegers() const + { return numberIntegers_;} +private: + /// Converts to ordered + void convert(); +protected: + /// Entries for fixing variables + CliqueEntry * fixEntry_; + /// Starts of integer variable going to zero + int * toZero_; + /// Starts of integer variable going to one + int * toOne_; + /// List of 0-1 integer variables + int * integerVariable_; + /// Backward look up + int * backward_; + /// Entries for fixing variable when collecting + int * fixingEntry_; + /// Number of variables + int numberVariables_; + /// Number of 0-1 variables + int numberIntegers_; + /// Maximum number in fixEntry_ + int maximumEntries_; + /// Number entries in fixingEntry_ (and fixEntry_) or -2 if correct style + int numberEntries_; +}; +inline int sequenceInCliqueEntry(const CliqueEntry & cEntry) +{ return cEntry.fixes&0x7fffffff;} +inline void setSequenceInCliqueEntry(CliqueEntry & cEntry,int sequence) +{ cEntry.fixes = sequence|(cEntry.fixes&0x80000000);} +inline bool oneFixesInCliqueEntry(const CliqueEntry & cEntry) +{ return (cEntry.fixes&0x80000000)!=0;} +inline void setOneFixesInCliqueEntry(CliqueEntry & cEntry,bool oneFixes) +{ cEntry.fixes = (oneFixes ? 0x80000000 : 0)|(cEntry.fixes&0x7fffffff);} + +#endif diff --git a/thirdparty/linux/include/coin/coin/CglTwomir.hpp b/thirdparty/linux/include/coin/coin/CglTwomir.hpp new file mode 100644 index 0000000..ba00380 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglTwomir.hpp @@ -0,0 +1,565 @@ +// $Id: CglTwomir.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglTwomir_H +#define CglTwomir_H +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinFactorization.hpp" + +typedef struct +{ + + int nz; /* current length of arrays index[] and coeff[] */ + int max_nz; /* max length of arrays index[] and coeff[] */ + double *coeff; /* coefficient of each variable in the constraint */ + int *index; /* index of the variable (value in 0 ... nrow+ncol) */ + double rhs; /* rhs of the constraint */ + char sense; /* ?? is it necessary */ + +} DGG_constraint_t; + +typedef struct{ + int n; + DGG_constraint_t **c; + int *ctype; + double *alpha; +} DGG_list_t; + +/******************** BASIS INFORMATION ADTs **********************************/ +typedef struct{ + int q_min; + int q_max; + int t_min; + int t_max; + int a_max; + int max_elements; +} cutParams; + +typedef struct +{ + double gomory_threshold; /* factional variable must be this away from int */ + int ncol, /* number of columns in LP */ + nrow, /* number of constaints in LP */ + ninteger; /* number of integer variables in LP */ + + int nbasic_col, /* number of basic columns in the LP */ + nbasic_row; /* number of basic rows in the LP */ + + /* the following arrays are all of size (ncol+nrow) */ + int *info; /* description of each variable (see below) */ + double *lb; /* specifies the lower bound (if any) of each variable */ + double *ub; /* specifies the upper bound (if any) of each variable */ + double *x; /* current solution */ + double *rc; /* current reduced cost */ + double *opt_x; + + cutParams cparams; +} DGG_data_t; + +/* the following macros allow us to decode the info of the DGG_data + type. The encoding is as follows, + bit 1 : if the variable is basic or not (non-basic). + bit 2 : if the variable is integer or or not (rational). + bit 3 : if the variable is structural or not (artifical). + bit 4 : if the variable is non-basic and at its upper bound + (else if non-basic at lower bound). */ + +#define DGG_isBasic(data,idx) ((data->info[idx])&1) +#define DGG_isInteger(data,idx) ((data->info[idx] >> 1)&1) +#define DGG_isStructural(data,idx) ((data->info[idx] >> 2)&1) +#define DGG_isEqualityConstraint(data,idx) ((data->info[idx] >> 3)&1) +#define DGG_isNonBasicAtUB(data,idx) ((data->info[idx] >> 4)&1) +#define DGG_isNonBasicAtLB(data,idx) ((data->info[idx] >> 5)&1) +#define DGG_isConstraintBoundedAbove(data,idx) ((data->info[idx] >> 6)&1) +#define DGG_isConstraintBoundedBelow(data,idx) ((data->info[idx] >> 7)&1) + +#define DGG_setIsBasic(data,idx) ((data->info[idx]) |= 1) +#define DGG_setIsInteger(data,idx) ((data->info[idx]) |= (1<<1)) +#define DGG_setIsStructural(data,idx) ((data->info[idx]) |= (1<<2)) +#define DGG_setEqualityConstraint(data,idx) ((data->info[idx]) |= (1<<3)) +#define DGG_setIsNonBasicAtUB(data,idx) ((data->info[idx]) |= (1<<4)) +#define DGG_setIsNonBasicAtLB(data,idx) ((data->info[idx]) |= (1<<5)) +#define DGG_setIsConstraintBoundedAbove(data,idx) ((data->info[idx]) |= (1<<6)) +#define DGG_setIsConstraintBoundedBelow(data,idx) ((data->info[idx]) |= (1<<7)) + +class CoinWarmStartBasis; +/** Twostep MIR Cut Generator Class */ +class CglTwomir : public CglCutGenerator { + + friend void CglTwomirUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +public: + + /// Problem name + std::string probname_; + + /**@name Generate Cuts */ + //@{ + /** Generate Two step MIR cuts either from the tableau rows or from the + formulation rows + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + + /**@name Change criterion on which scalings to use (default = 1,1,1,1) */ + //@{ + /// Set + void setMirScale (int tmin, int tmax) {t_min_ = tmin; t_max_ = tmax;} + void setTwomirScale (int qmin, int qmax) {q_min_ = qmin; q_max_ = qmax;} + void setAMax (int a) {a_max_ = a;} + void setMaxElements (int n) {max_elements_ = n;} + void setMaxElementsRoot (int n) {max_elements_root_ = n;} + void setCutTypes (bool mir, bool twomir, bool tab, bool form) + { do_mir_ = mir; do_2mir_ = twomir; do_tab_ = tab; do_form_ = form;} + void setFormulationRows (int n) {form_nrows_ = n;} + + /// Get + int getTmin() const {return t_min_;} + int getTmax() const {return t_max_;} + int getQmin() const {return q_min_;} + int getQmax() const {return q_max_;} + int getAmax() const {return a_max_;} + int getMaxElements() const {return max_elements_;} + int getMaxElementsRoot() const {return max_elements_root_;} + int getIfMir() const { return do_mir_;} + int getIfTwomir() const { return do_2mir_;} + int getIfTableau() const { return do_tab_;} + int getIfFormulation() const { return do_form_;} + //@} + + /**@name Change criterion on which variables to look at. All ones + more than "away" away from integrality will be investigated + (default 0.05) */ + //@{ + /// Set away + void setAway(double value); + /// Get away + double getAway() const; + /// Set away at root + void setAwayAtRoot(double value); + /// Get away at root + double getAwayAtRoot() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const + { return max_elements_;} + //@} + + /**@name Change way TwoMir works */ + //@{ + /// Pass in a copy of original solver (clone it) + void passInOriginalSolver(OsiSolverInterface * solver); + /// Returns original solver + inline OsiSolverInterface * originalSolver() const + { return originalSolver_;} + /// Set type - 0 normal, 1 add original matrix one, 2 replace + inline void setTwomirType(int type) + { twomirType_=type;} + /// Return type + inline int twomirType() const + { return twomirType_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglTwomir (); + + /// Copy constructor + CglTwomir (const CglTwomir &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglTwomir & operator=(const CglTwomir& rhs); + + /// Destructor + virtual ~CglTwomir (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + // Private member data + /**@name Private member data */ + //@{ + /// Threadsafe random number generator + CoinThreadRandom randomNumberGenerator_; + /// Original solver + OsiSolverInterface * originalSolver_; + /// Only investigate if more than this away from integrality + double away_; + /// Only investigate if more than this away from integrality (at root) + double awayAtRoot_; + /// Type - 0 normal, 1 add original matrix one, 2 replace + int twomirType_; + bool do_mir_; + bool do_2mir_; + bool do_tab_; + bool do_form_; + + int t_min_; /// t_min - first value of t to use for tMIR inequalities + int t_max_; /// t_max - last value of t to use for tMIR inequalities + int q_min_; /// q_min - first value of t to use for 2-Step tMIR inequalities + int q_max_; /// q_max - last value of t to use for 2-Step tMIR inequalities + int a_max_; /// a_max - maximum value of bhat/alpha + int max_elements_; /// Maximum number of elements in cut + int max_elements_root_; /// Maximum number of elements in cut at root + int form_nrows_; //number of rows on which formulation cuts will be generated + //@} +}; + +//############################################################################# + +/* +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <math.h> +#include <float.h> +#include <cassert> +#include <iostream.h> +*/ + +/******************** DEBUG DEFINITIONS ***************************************/ + +#define DGG_DEBUG_DGG 1 +#define DGG_TRACE_ERRORS 0 +#define DGG_DISPLAY 0 +#define DGG_AUTO_CHECK_CUT_OFF_OPTIMAL 1 + +/******************** CONFIGURATION DEFAULTS **********************************/ + +#define DGG_DEFAULT_METHOD 2 +#define DGG_DEFAULT_TMIN 1 +#define DGG_DEFAULT_TMAX 1 +#define DGG_DEFAULT_TAUMIN 2 +#define DGG_DEFAULT_TAUMAX 6 +#define DGG_DEFAULT_MAX_CUTS 500 +#define DGG_DEFAULT_IMPROVEMENT_THRESH 0.001 +#define DGG_DEFAULT_NBELOW_THRESH INT_MAX +#define DGG_DEFAULT_NROOT_ROUNDS 2 +#define DGG_DEFAULT_NEGATIVE_SCALED_TWOSTEPS 0 +#define DGG_DEFAULT_ALPHA_RULE 0 +#define DGG_DEFAULT_CUT_INC 250 +#define DGG_DEFAULT_CUT_FORM 0 +#define DGG_DEFAULT_NICEFY 0 +#define DGG_DEFAULT_ONLY_DELAYED 0 +#define DGG_DEFAULT_DELAYED_FREQ 9999999 +#define DGG_DEFAULT_LPROWS_FREQ 9999999 +#define DGG_DEFAULT_WHICH_FORMULATION_CUTS 2 + +/******************** SOLVER CONFIGURATION DEFINITIONS ************************/ + +#define DGG_OSI 0 +#define DGG_CPX 1 +#define DGG_QSO 2 + +/* determines the solver to be used */ +#define DGG_SOLVER DGG_OSI + +/* adds checking routines to make sure solver works as expected */ +#define DGG_DEBUG_SOLVER 0 + +/* turn off screen output from solver */ +#define DGG_SOLVER_SCREEN_FLAG 0 + +/******************** CUT DEFINITIONS *****************************************/ + +/* internal names for cut types */ +#define DGG_TMIR_CUT 1 +#define DGG_2STEP_CUT 2 + +/* internal names for alpha-selection rules */ +#define DGG_ALPHA_MIN_SUM 0 +#define DGG_ALPHA_RANDOM_01 1 +#define DGG_ALPHA_RANDOM_COEFF 2 +#define DGG_ALPHA_ALL 3 +#define DGG_ALPHA_MAX_STEEP 5 + +/******************** PRECISION & NUMERICAL ISSUES DEFINITIONS ****************/ + +/* how steep a cut must be before adding it to the lp */ +#define DGG_MIN_STEEPNESS 1.0e-4 +#define DGG_MAX_L2NORM 1.0e7 + +/* 0 = min steepness, 1 = max norm */ +#define DGG_NORM_CRITERIA 1 + +/* internal representation of +infinity */ +#define UB_MAX DBL_MAX + +/* used to define how fractional a basic-integer variable must be + before choosing to use it to generate a TMIR cut on. + OSI's default is 1.0e-7 */ +#define DGG_GOMORY_THRESH 0.005 + +#define DGG_RHS_THRESH 0.005 + +/* used for comparing variables to their upper bounds. + OSI's default is 1.0e-7. + We set it to 1.0e6 because e-7 seems too sensitive. + In fact, with e-7 the problem dsbmip.mps complains. */ +#define DGG_BOUND_THRESH 1.0e-6 + +/* used for comparing the lhs (activity) value of a tableau row + with the rhs. This is only used for debugging purposes. */ +#define DGG_EQUALITY_THRESH 1.0e-5 + +/* used for comparing a variable's lower bound to 0.0 + and determining if we need to shift the variable */ +#define DGG_SHIFT_THRESH 1.0e-6 + +/* used for determing how far from an integer is still an integer. + This value is used for comparing coefficients to integers. + OSI's default is 1.0e-10. */ +#define DGG_INTEGRALITY_THRESH 1.0e-10 + +/* the min value that a coeff can have in the tableau row + before being set to zero. */ +#define CBC_CHECK_CUT +#ifndef CBC_CHECK_CUT +#define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-8 +#else +#define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-12 +#endif + +/* smallest value rho is allowed to have for a simple 2-step MIR + (ie: not an extended two-step MIR) */ +#define DGG_MIN_RHO 1.0e-7 +#define DGG_MIN_ALPHA 1.0e-7 + +/* when a slack is null: used to check if a cut is satisfied or not. */ +#define DGG_NULL_SLACK 1.0e-5 + +/* nicefy constants */ +#define DGG_NICEFY_MIN_ABSVALUE 1.0e-13 +#define DGG_NICEFY_MIN_FIX 1.0e-7 +#define DGG_NICEFY_MAX_PADDING 1.0e-6 +#define DGG_NICEFY_MAX_RATIO 1.0e9 + + +/******************** ERROR-CATCHING MACROS ***********************************/ +#if DGG_TRACE_ERRORS > 0 + +#define __DGG_PRINT_LOC__(F) fprintf(((F==0)?stdout:F), " in %s (%s:%d)\n", __func__, __FILE__, __LINE__) + +#define DGG_THROW(A,REST...) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + return (A);} + +#define DGG_IF_EXIT(A,B,REST...) {\ + if(A) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + exit(B);}} + +#define DGG_CHECKRVAL(A,B) {\ + if(A) {\ + __DGG_PRINT_LOC__(stdout); \ + return B; } } + +#define DGG_CHECKRVAL1(A,B) {\ + if(A) {\ + __DGG_PRINT_LOC__(stdout); \ + rval = B; goto CLEANUP; } } + +#define DGG_WARNING(A, REST...) {\ + if(A) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + }} + +#define DGG_TEST(A,B,REST...) {\ + if(A) DGG_THROW(B,##REST) } + +#define DGG_TEST2(A,B,C,REST) {DGG_TEST(A,B,C,REST) } +#define DGG_TEST3(A,B,C,D,REST) {DGG_TEST(A,B,C,D,REST) } + +#else + +#define DGG_IF_EXIT(A,B,REST) {if(A) {fprintf(stdout, REST);exit(B);}} + +#define DGG_THROW(A,B) return(A) + +#define DGG_CHECKRVAL(A,B) { if(A) return(B); } +#define DGG_CHECKRVAL1(A,B){ if(A) { rval = B; goto CLEANUP; } } + +#define DGG_TEST(A,B,REST) { if(A) return(B);} +#define DGG_TEST2(A,B,REST,C) { DGG_TEST(A,B,REST) } +#define DGG_TEST3(A,B,REST,C,D) { DGG_TEST(A,B,REST) } + +#endif + +/******************** SIMPLE MACROS AND FUNCTIONS *****************************/ + +#define DGG_MIN(a,b) ( (a<b)?a:b ) +#define DGG_MAX(a,b) ( (a>b)?a:b ) +#define KREM(vht,alpha,tau) (DGG_MIN( ceil(vht / alpha), tau ) - 1) +#define LMIN(vht, d, bht) (DGG_MIN( floor(d*bht/bht), d)) +#define ABOV(v) (v - floor(v)) +#define QINT(vht,bht,tau) ( (int)floor( (vht*(tau-1))/bht ) ) +#define V2I(bht,tau,i) ( ((i+1)*bht / tau) ) + +int DGG_is_even(double vht, double bht, int tau, int q); +double frac_part(double value); +int DGG_is_a_multiple_of_b(double a, double b); + + +/* free function for DGG_data_t. Frees internal arrays and data structure */ +int DGG_freeData( DGG_data_t *data ); + +/******************** CONSTRAINT ADTs *****************************************/ +DGG_constraint_t* DGG_newConstraint(int max_arrays); +void DGG_freeConstraint(DGG_constraint_t *c); +DGG_constraint_t *DGG_copyConstraint(DGG_constraint_t *c); +void DGG_scaleConstraint(DGG_constraint_t *c, int t); + +/******************** CONFIGURATION *******************************************/ +void DGG_list_init (DGG_list_t *l); +int DGG_list_addcut (DGG_list_t *l, DGG_constraint_t *cut, int ctype, double alpha); +void DGG_list_delcut (DGG_list_t *l, int i); +void DGG_list_free(DGG_list_t *l); + +/******************* SOLVER SPECIFIC METHODS **********************************/ +DGG_data_t *DGG_getData(const void *solver_ptr); + +/******************* CONSTRAINT MANIPULATION **********************************/ + +/* DGG_transformConstraint: manipulates a constraint in the following way: + +packs everything in output + +1 - variables at their upper bounds are substituted for their +complements. This is done by adjusting the coefficients and +the right hand side (simple substitution). + +2 - variables with non-zero lower bounds are shifted. */ + +int DGG_transformConstraint( DGG_data_t *data, + double **x_out, + double **rc_out, + char **isint_out, + DGG_constraint_t *constraint ); + +/* DGG_unTransformConstraint : + +1 - Undoes step (1) of DGG_transformConstraint +2 - Undoes step (2) of DGG_transformConstraint */ + +int DGG_unTransformConstraint( DGG_data_t *data, + DGG_constraint_t *constraint ); + +/* substitutes each slack variable by the structural variables which + define it. This function, hence, changes the constraint 'cut'. */ + +int DGG_substituteSlacks( const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t *cut ); + +int DGG_nicefyConstraint( const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t *cut); + +/******************* CUT GENERATION *******************************************/ +int DGG_getFormulaConstraint( int row_idx, + const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t* row ); + +int DGG_getTableauConstraint( int index, + const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t* tabrow, + const int * colIsBasic, + const int * rowIsBasic, + CoinFactorization & factorization, + int mode ); + +DGG_constraint_t* DGG_getSlackExpression(const void *solver_ptr, DGG_data_t* data, int row_index); + + int DGG_generateTabRowCuts( DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr ); + + int DGG_generateFormulationCuts( DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr, + int nrows, + CoinThreadRandom & generator); + + + int DGG_generateFormulationCutsFromBase( DGG_constraint_t *base, + double slack, + DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr, + CoinThreadRandom & generator); + + int DGG_generateCutsFromBase( DGG_constraint_t *base, + DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr ); + +int DGG_buildMir( char *isint, + DGG_constraint_t *base, + DGG_constraint_t **cut_out ); + +int DGG_build2step( double alpha, + char *isint, + DGG_constraint_t *base, + DGG_constraint_t **cut_out ); + + int DGG_addMirToList ( DGG_constraint_t *base, + char *isint, + double *x, + DGG_list_t *list, + DGG_data_t *data, + DGG_constraint_t *orig_base ); + + int DGG_add2stepToList ( DGG_constraint_t *base, + char *isint, + double *x, + double *rc, + DGG_list_t *list, + DGG_data_t *data, + DGG_constraint_t *orig_base ); + +/******************* CUT INFORMATION ******************************************/ + +double DGG_cutLHS(DGG_constraint_t *c, double *x); +int DGG_isCutDesirable(DGG_constraint_t *c, DGG_data_t *d); + +/******************* TEST / DEBUGGING ROUTINES ********************************/ + +int DGG_isConstraintViolated(DGG_data_t *d, DGG_constraint_t *c); + +int DGG_isBaseTrivial(DGG_data_t *d, DGG_constraint_t* c); +int DGG_is2stepValid(double alpha, double bht); + +int DGG_cutsOffPoint(double *x, DGG_constraint_t *cut); + +//############################################################################# +/** A function that tests the methods in the CglTwomir class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglTwomirUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +#endif + + diff --git a/thirdparty/linux/include/coin/coin/CglZeroHalf.hpp b/thirdparty/linux/include/coin/coin/CglZeroHalf.hpp new file mode 100644 index 0000000..929269a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CglZeroHalf.hpp @@ -0,0 +1,133 @@ +// $Id: CglZeroHalf.hpp 1122 2013-04-06 20:39:53Z stefan $ +// Copyright (C) 2010, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +#ifndef CglZeroHalf_H +#define CglZeroHalf_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinPackedMatrix.hpp" +#include "Cgl012cut.hpp" + +/** Zero Half Cut Generator Class + + This class generates zero half cuts via the following method: + + See - + +G. Andreello, A. Caprara, M. Fischetti, + “Embedding Cuts in a Branch and Cut Framework: a Computational Study + with {0,1/2}-Cuts”, INFORMS Journal on Computing 19(2), 229-238, 2007. + +*/ + +class CglZeroHalf : public CglCutGenerator { + friend void CglZeroHalfUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate zero half cuts for the model accessed through the solver interface. + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Sets and Gets */ + //@{ + /// Get flags + inline int getFlags() const + { return flags_;} + /// Set flags + inline void setFlags(int value) + { flags_ = value;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglZeroHalf (); + + /// Copy constructor + CglZeroHalf ( + const CglZeroHalf &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglZeroHalf & + operator=( + const CglZeroHalf& rhs); + + /// Destructor + virtual + ~CglZeroHalf (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + //@} + + + /**@name Private member data */ + //@{ + /// number of rows in the ILP matrix + int mr_; + /// number of columns in the ILP matrix + int mc_; + /// number of nonzero's in the ILP matrix + int mnz_; + /// starting position of each row in arrays mtind and mtval + int *mtbeg_; + /// number of entries of each row in arrays mtind and mtval + int *mtcnt_; + /// column indices of the nonzero entries of the ILP matrix + int *mtind_; + /// values of the nonzero entries of the ILP matrix + int *mtval_; + /// lower bounds on the variables + int *vlb_; + /// upper bounds on the variables + int *vub_; + /// right hand sides of the constraints + int *mrhs_; + /// senses of the constraints: 'L', 'G' or 'E' + char *msense_; + /// Cgl012Cut object to make thread safe + Cgl012Cut cutInfo_; + /** Flags + 1 bit - global cuts + */ + int flags_; + //@} +}; +/// A simple Dijkstra shortest path - make better later +#ifndef CGL_NEW_SHORT +void cglShortestPath(cgl_graph * graph, int source, int maximumLength); +#else +void cglShortestPath(auxiliary_graph * graph, int source, int maximumLength); +#endif +//############################################################################# +/** A function that tests the methods in the CglZeroHalf class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglZeroHalfUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpAmplObjective.hpp b/thirdparty/linux/include/coin/coin/ClpAmplObjective.hpp new file mode 100644 index 0000000..32b04e4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpAmplObjective.hpp @@ -0,0 +1,113 @@ +/* $Id: ClpAmplObjective.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpAmplObjective_H +#define ClpAmplObjective_H + +#include "ClpObjective.hpp" +#include "CoinPackedMatrix.hpp" + +//############################################################################# + +/** Ampl Objective Class + +*/ + +class ClpAmplObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Ampl then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /// Resize objective + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() ; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpAmplObjective(); + + /// Constructor from ampl info + ClpAmplObjective(void * amplInfo); + + /** Copy constructor . + */ + ClpAmplObjective(const ClpAmplObjective & rhs); + + /// Assignment operator + ClpAmplObjective & operator=(const ClpAmplObjective& rhs); + + /// Destructor + virtual ~ClpAmplObjective (); + + /// Clone + virtual ClpObjective * clone() const; + + //@} + ///@name Gets and sets + //@{ + /// Linear objective + double * linearObjective() const; + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Saved offset + double offset_; + /// Ampl info + void * amplObjective_; + /// Objective + double * objective_; + /// Gradient + double * gradient_; + //@} +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/ClpCholeskyBase.hpp b/thirdparty/linux/include/coin/coin/ClpCholeskyBase.hpp new file mode 100644 index 0000000..815af01 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpCholeskyBase.hpp @@ -0,0 +1,294 @@ +/* $Id: ClpCholeskyBase.hpp 1722 2011-04-17 09:58:37Z stefan $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpCholeskyBase_H +#define ClpCholeskyBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +//#define CLP_LONG_CHOLESKY 0 +#ifndef CLP_LONG_CHOLESKY +#define CLP_LONG_CHOLESKY 0 +#endif +/* valid combinations are + CLP_LONG_CHOLESKY 0 and COIN_LONG_WORK 0 + CLP_LONG_CHOLESKY 1 and COIN_LONG_WORK 1 + CLP_LONG_CHOLESKY 2 and COIN_LONG_WORK 1 +*/ +#if COIN_LONG_WORK==0 +#if CLP_LONG_CHOLESKY>0 +#define CHOLESKY_BAD_COMBINATION +#endif +#else +#if CLP_LONG_CHOLESKY==0 +#define CHOLESKY_BAD_COMBINATION +#endif +#endif +#ifdef CHOLESKY_BAD_COMBINATION +# warning("Bad combination of CLP_LONG_CHOLESKY and COIN_BIG_DOUBLE/COIN_LONG_WORK"); +"Bad combination of CLP_LONG_CHOLESKY and COIN_LONG_WORK" +#endif +#if CLP_LONG_CHOLESKY>1 +typedef long double longDouble; +#define CHOL_SMALL_VALUE 1.0e-15 +#elif CLP_LONG_CHOLESKY==1 +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#else +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#endif +class ClpInterior; +class ClpCholeskyDense; +class ClpMatrixBase; + +/** Base class for Clp Cholesky factorization + Will do better factorization. very crude ordering + + Derived classes may be using more sophisticated methods +*/ + +class ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Orders rows and saves pointer to matrix.and model. + returns non-zero if not enough memory. + You can use preOrder to set up ADAT + If using default symbolic etc then must set sizeFactor_ to + size of input matrix to order (and to symbolic). + Also just permute_ and permuteInverse_ should be created */ + virtual int order(ClpInterior * model); + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /** Uses factorization to solve. - given as if KKT. + region1 is rows+columns, region2 is rows */ + virtual void solveKKT (CoinWorkDouble * region1, CoinWorkDouble * region2, const CoinWorkDouble * diagonal, + CoinWorkDouble diagonalScaleFactor); +private: + /// AMD ordering + int orderAMD(); +public: + //@} + + /**@name Gets */ + //@{ + /// status. Returns status + inline int status() const { + return status_; + } + /// numberRowsDropped. Number of rows gone + inline int numberRowsDropped() const { + return numberRowsDropped_; + } + /// reset numberRowsDropped and rowsDropped. + void resetRowsDropped(); + /// rowsDropped - which rows are gone + inline char * rowsDropped() const { + return rowsDropped_; + } + /// choleskyCondition. + inline double choleskyCondition() const { + return choleskyCondition_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline double goDense() const { + return goDense_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline void setGoDense(double value) { + goDense_ = value; + } + /// rank. Returns rank + inline int rank() const { + return numberRows_ - numberRowsDropped_; + } + /// Return number of rows + inline int numberRows() const { + return numberRows_; + } + /// Return size + inline CoinBigIndex size() const { + return sizeFactor_; + } + /// Return sparseFactor + inline longDouble * sparseFactor() const { + return sparseFactor_; + } + /// Return diagonal + inline longDouble * diagonal() const { + return diagonal_; + } + /// Return workDouble + inline longDouble * workDouble() const { + return workDouble_; + } + /// If KKT on + inline bool kkt() const { + return doKKT_; + } + /// Set KKT + inline void setKKT(bool yesNo) { + doKKT_ = yesNo; + } + /// Set integer parameter + inline void setIntegerParameter(int i, int value) { + integerParameters_[i] = value; + } + /// get integer parameter + inline int getIntegerParameter(int i) { + return integerParameters_[i]; + } + /// Set double parameter + inline void setDoubleParameter(int i, double value) { + doubleParameters_[i] = value; + } + /// get double parameter + inline double getDoubleParameter(int i) { + return doubleParameters_[i]; + } + //@} + + +public: + + /**@name Constructors, destructor + */ + //@{ + /** Constructor which has dense columns activated. + Default is off. */ + ClpCholeskyBase(int denseThreshold = -1); + /** Destructor (has to be public) */ + virtual ~ClpCholeskyBase(); + /// Copy + ClpCholeskyBase(const ClpCholeskyBase&); + /// Assignment + ClpCholeskyBase& operator=(const ClpCholeskyBase&); + //@} + //@{ + ///@name Other + /// Clone + virtual ClpCholeskyBase * clone() const; + + /// Returns type + inline int type() const { + if (doKKT_) return 100; + else return type_; + } +protected: + /// Sets type + inline void setType(int type) { + type_ = type; + } + /// model. + inline void setModel(ClpInterior * model) { + model_ = model; + } + //@} + + /**@name Symbolic, factor and solve */ + //@{ + /** Symbolic1 - works out size without clever stuff. + Uses upper triangular as much easier. + Returns size + */ + int symbolic1(const CoinBigIndex * Astart, const int * Arow); + /** Symbolic2 - Fills in indices + Uses lower triangular so can do cliques etc + */ + void symbolic2(const CoinBigIndex * Astart, const int * Arow); + /** Factorize - filling in rowsDropped and returning number dropped + in integerParam. + */ + void factorizePart2(int * rowsDropped) ; + /** solve - 1 just first half, 2 just second half - 3 both. + If 1 and 2 then diagonal has sqrt of inverse otherwise inverse + */ + void solve(CoinWorkDouble * region, int type); + /// Forms ADAT - returns nonzero if not enough memory + int preOrder(bool lowerTriangular, bool includeDiagonal, bool doKKT); + /// Updates dense part (broken out for profiling) + void updateDense(longDouble * d, /*longDouble * work,*/ int * first); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// type (may be useful) if > 20 do KKT + int type_; + /// Doing full KKT (only used if default symbolic and factorization) + bool doKKT_; + /// Go dense at this fraction + double goDense_; + /// choleskyCondition. + double choleskyCondition_; + /// model. + ClpInterior * model_; + /// numberTrials. Number of trials before rejection + int numberTrials_; + /// numberRows. Number of Rows in factorization + int numberRows_; + /// status. Status of factorization + int status_; + /// rowsDropped + char * rowsDropped_; + /// permute inverse. + int * permuteInverse_; + /// main permute. + int * permute_; + /// numberRowsDropped. Number of rows gone + int numberRowsDropped_; + /// sparseFactor. + longDouble * sparseFactor_; + /// choleskyStart - element starts + CoinBigIndex * choleskyStart_; + /// choleskyRow (can be shorter than sparsefactor) + int * choleskyRow_; + /// Index starts + CoinBigIndex * indexStart_; + /// Diagonal + longDouble * diagonal_; + /// double work array + longDouble * workDouble_; + /// link array + int * link_; + // Integer work array + CoinBigIndex * workInteger_; + // Clique information + int * clique_; + /// sizeFactor. + CoinBigIndex sizeFactor_; + /// Size of index array + CoinBigIndex sizeIndex_; + /// First dense row + int firstDense_; + /// integerParameters + int integerParameters_[64]; + /// doubleParameters; + double doubleParameters_[64]; + /// Row copy of matrix + ClpMatrixBase * rowCopy_; + /// Dense indicators + char * whichDense_; + /// Dense columns (updated) + longDouble * denseColumn_; + /// Dense cholesky + ClpCholeskyDense * dense_; + /// Dense threshold (for taking out of Cholesky) + int denseThreshold_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpCholeskyDense.hpp b/thirdparty/linux/include/coin/coin/ClpCholeskyDense.hpp new file mode 100644 index 0000000..d8428b6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpCholeskyDense.hpp @@ -0,0 +1,162 @@ +/* $Id: ClpCholeskyDense.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +/* + Copyright (C) 2003, International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpCholeskyDense_H +#define ClpCholeskyDense_H + +#include "ClpCholeskyBase.hpp" +class ClpMatrixBase; + +class ClpCholeskyDense : public ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes provides */ + /**@{*/ + /** Orders rows and saves pointer to matrix.and model. + Returns non-zero if not enough memory */ + virtual int order(ClpInterior * model) ; + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /**@}*/ + + /**@name Non virtual methods for ClpCholeskyDense */ + /**@{*/ + /** Reserves space. + If factor not NULL then just uses passed space + Returns non-zero if not enough memory */ + int reserveSpace(const ClpCholeskyBase * factor, int numberRows) ; + /** Returns space needed */ + CoinBigIndex space( int numberRows) const; + /** part 2 of Factorize - filling in rowsDropped */ + void factorizePart2(int * rowsDropped) ; + /** part 2 of Factorize - filling in rowsDropped - blocked */ + void factorizePart3(int * rowsDropped) ; + /** Forward part of solve */ + void solveF1(longDouble * a, int n, CoinWorkDouble * region); + void solveF2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + /** Backward part of solve */ + void solveB1(longDouble * a, int n, CoinWorkDouble * region); + void solveB2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + int bNumber(const longDouble * array, int &, int&); + /** A */ + inline longDouble * aMatrix() const { + return sparseFactor_; + } + /** Diagonal */ + inline longDouble * diagonal() const { + return diagonal_; + } + /**@}*/ + + + /**@name Constructors, destructor */ + /**@{*/ + /** Default constructor. */ + ClpCholeskyDense(); + /** Destructor */ + virtual ~ClpCholeskyDense(); + /** Copy */ + ClpCholeskyDense(const ClpCholeskyDense&); + /** Assignment */ + ClpCholeskyDense& operator=(const ClpCholeskyDense&); + /** Clone */ + virtual ClpCholeskyBase * clone() const ; + /**@}*/ + + +private: + /**@name Data members */ + /**@{*/ + /** Just borrowing space */ + bool borrowSpace_; + /**@}*/ +}; + +/* structure for C */ +typedef struct { + longDouble * diagonal_; + longDouble * a; + longDouble * work; + int * rowsDropped; + double doubleParameters_[1]; /* corresponds to 10 */ + int integerParameters_[2]; /* corresponds to 34, nThreads */ + int n; + int numberBlocks; +} ClpCholeskyDenseC; + +extern "C" { + void ClpCholeskySpawn(void *); +} +/**Non leaf recursive factor */ +void +ClpCholeskyCfactor(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, int numberBlocks, + longDouble * diagonal, longDouble * work, int * rowsDropped); + +/**Non leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRec(ClpCholeskyDenseC * thisStruct, + longDouble * aTri, int nThis, + longDouble * aUnder, longDouble * diagonal, + longDouble * work, + int nLeft, int iBlock, int jBlock, + int numberBlocks); +/**Non leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTri(ClpCholeskyDenseC * thisStruct, + longDouble * aUnder, int nTri, int nDo, + int iBlock, int jBlock, longDouble * aTri, + longDouble * diagonal, longDouble * work, + int numberBlocks); +/** Non leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRec(ClpCholeskyDenseC * thisStruct, + longDouble * above, int nUnder, int nUnderK, + int nDo, longDouble * aUnder, longDouble *aOther, + longDouble * work, + int iBlock, int jBlock, + int numberBlocks); +/**Leaf recursive factor */ +void +ClpCholeskyCfactorLeaf(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, + longDouble * diagonal, longDouble * work, + int * rowsDropped); +/**Leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRecLeaf(/*ClpCholeskyDenseC * thisStruct,*/ + longDouble * aTri, longDouble * aUnder, + longDouble * diagonal, longDouble * work, + int nUnder); +/**Leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTriLeaf(/*ClpCholeskyDenseC * thisStruct, */ + longDouble * aUnder, longDouble * aTri, + /*longDouble * diagonal,*/ longDouble * work, int nUnder); +/** Leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRecLeaf(/*ClpCholeskyDenseC * thisStruct, */ + const longDouble * COIN_RESTRICT above, + const longDouble * COIN_RESTRICT aUnder, + longDouble * COIN_RESTRICT aOther, + const longDouble * COIN_RESTRICT work, + int nUnder); +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpCholeskyMumps.hpp b/thirdparty/linux/include/coin/coin/ClpCholeskyMumps.hpp new file mode 100644 index 0000000..48261d7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpCholeskyMumps.hpp @@ -0,0 +1,63 @@ +/* $Id: ClpCholeskyMumps.hpp 1692 2011-03-05 18:05:01Z stefan $ */ +// Copyright (C) 2009, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpCholeskyMumps_H +#define ClpCholeskyMumps_H +#include "ClpCholeskyBase.hpp" +class ClpMatrixBase; +class ClpCholeskyDense; + +// unfortunately, DMUMPS_STRUC_C is an anonymous struct in MUMPS, so we define it to void for everyone outside ClpCholeskyMumps +// if this file is included by ClpCholeskyMumps.cpp, then after dmumps_c.h has been included, which defines MUMPS_VERSION +#ifndef MUMPS_VERSION +typedef void DMUMPS_STRUC_C; +#endif + +/** Mumps class for Clp Cholesky factorization + +*/ +class ClpCholeskyMumps : public ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes provides */ + //@{ + /** Orders rows and saves pointer to matrix.and model. + Returns non-zero if not enough memory */ + virtual int order(ClpInterior * model) ; + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const double * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (double * region) ; + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Constructor which has dense columns activated. + Default is off. */ + ClpCholeskyMumps(int denseThreshold = -1); + /** Destructor */ + virtual ~ClpCholeskyMumps(); + /// Clone + virtual ClpCholeskyBase * clone() const ; + //@} + +private: + // Mumps structure + DMUMPS_STRUC_C* mumps_; + + // Copy + ClpCholeskyMumps(const ClpCholeskyMumps&); + // Assignment + ClpCholeskyMumps& operator=(const ClpCholeskyMumps&); +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpConfig.h b/thirdparty/linux/include/coin/coin/ClpConfig.h new file mode 100644 index 0000000..2e3620f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpConfig.h @@ -0,0 +1,17 @@ +/* src/config_clp.h. Generated by configure. */ +/* src/config_clp.h.in. */ + +/* Define to 1, 2, 3, or 4 if Aboca should be build. */ +/* #undef CLP_HAS_ABC */ + +/* Version number of project */ +#define CLP_VERSION "1.16.10" + +/* Major Version number of project */ +#define CLP_VERSION_MAJOR 1 + +/* Minor Version number of project */ +#define CLP_VERSION_MINOR 16 + +/* Release Version number of project */ +#define CLP_VERSION_RELEASE 10 diff --git a/thirdparty/linux/include/coin/coin/ClpConstraint.hpp b/thirdparty/linux/include/coin/coin/ClpConstraint.hpp new file mode 100644 index 0000000..be43bb8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpConstraint.hpp @@ -0,0 +1,125 @@ +/* $Id: ClpConstraint.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraint_H +#define ClpConstraint_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Constraint Abstract Base Class + +Abstract Base Class for describing a constraint or objective function + +*/ +class ClpConstraint { + +public: + + ///@name Stuff + //@{ + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient undefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const = 0; + /// Constraint function value + virtual double functionValue (const ClpSimplex * model, + const double * solution, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale constraint + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const = 0; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const = 0; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraint(); + + /// Copy constructor + ClpConstraint(const ClpConstraint &); + + /// Assignment operator + ClpConstraint & operator=(const ClpConstraint& rhs); + + /// Destructor + virtual ~ClpConstraint (); + + /// Clone + virtual ClpConstraint * clone() const = 0; + + //@} + + ///@name Other + //@{ + /// Returns type, 0 linear, 1 nonlinear + inline int type() { + return type_; + } + /// Row number (-1 is objective) + inline int rowNumber() const { + return rowNumber_; + } + + /// Number of possible coefficients in gradient + virtual int numberCoefficients() const = 0; + + /// Stored constraint function value + inline double functionValue () const { + return functionValue_; + } + + /// Constraint offset + inline double offset () const { + return offset_; + } + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Gradient at last evaluation + mutable double * lastGradient_; + /// Value of non-linear part of constraint + mutable double functionValue_; + /// Value of offset for constraint + mutable double offset_; + /// Type of constraint - linear is 1 + int type_; + /// Row number (-1 is objective) + int rowNumber_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpConstraintAmpl.hpp b/thirdparty/linux/include/coin/coin/ClpConstraintAmpl.hpp new file mode 100644 index 0000000..1ca0ab4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpConstraintAmpl.hpp @@ -0,0 +1,108 @@ +/* $Id: ClpConstraintAmpl.hpp 1899 2013-04-09 18:12:08Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintAmpl_H +#define ClpConstraintAmpl_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Ampl Constraint Class + +*/ + +class ClpConstraintAmpl : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Ampl then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonampl columns to 1. + Returns number of nonampl columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() ; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintAmpl(); + + /// Constructor from ampl + ClpConstraintAmpl(int row, void * amplInfo); + + /** Copy constructor . + */ + ClpConstraintAmpl(const ClpConstraintAmpl & rhs); + + /// Assignment operator + ClpConstraintAmpl & operator=(const ClpConstraintAmpl& rhs); + + /// Destructor + virtual ~ClpConstraintAmpl (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Ampl info + void * amplInfo_; + /// Column + int * column_; + /// Coefficients + double * coefficient_; + /// Number of coefficients in gradient + int numberCoefficients_; + //@} +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/ClpConstraintLinear.hpp b/thirdparty/linux/include/coin/coin/ClpConstraintLinear.hpp new file mode 100644 index 0000000..fd0a4da --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpConstraintLinear.hpp @@ -0,0 +1,110 @@ +/* $Id: ClpConstraintLinear.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintLinear_H +#define ClpConstraintLinear_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Linear Constraint Class + +*/ + +class ClpConstraintLinear : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintLinear(); + + /// Constructor from constraint + ClpConstraintLinear(int row, int numberCoefficients, int numberColumns, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintLinear(const ClpConstraintLinear & rhs); + + /// Assignment operator + ClpConstraintLinear & operator=(const ClpConstraintLinear& rhs); + + /// Destructor + virtual ~ClpConstraintLinear (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in linear constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients + int numberCoefficients_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpConstraintQuadratic.hpp b/thirdparty/linux/include/coin/coin/ClpConstraintQuadratic.hpp new file mode 100644 index 0000000..2eff6cc --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpConstraintQuadratic.hpp @@ -0,0 +1,119 @@ +/* $Id: ClpConstraintQuadratic.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintQuadratic_H +#define ClpConstraintQuadratic_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Quadratic Constraint Class + +*/ + +class ClpConstraintQuadratic : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Quadratic then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonquadratic columns to 1. + Returns number of nonquadratic columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintQuadratic(); + + /// Constructor from quadratic + ClpConstraintQuadratic(int row, int numberQuadraticColumns, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintQuadratic(const ClpConstraintQuadratic & rhs); + + /// Assignment operator + ClpConstraintQuadratic & operator=(const ClpConstraintQuadratic& rhs); + + /// Destructor + virtual ~ClpConstraintQuadratic (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Column starts + inline CoinBigIndex * start() const { + return start_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column starts + CoinBigIndex * start_; + /// Column (if -1 then linear coefficient) + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients in gradient + int numberCoefficients_; + /// Number of quadratic columns + int numberQuadraticColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDualRowDantzig.hpp b/thirdparty/linux/include/coin/coin/ClpDualRowDantzig.hpp new file mode 100644 index 0000000..73b42b3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDualRowDantzig.hpp @@ -0,0 +1,71 @@ +/* $Id: ClpDualRowDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowDantzig_H +#define ClpDualRowDantzig_H + +#include "ClpDualRowPivot.hpp" + +//############################################################################# + +/** Dual Row Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpDualRowDantzig : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowDantzig(); + + /// Copy constructor + ClpDualRowDantzig(const ClpDualRowDantzig &); + + /// Assignment operator + ClpDualRowDantzig & operator=(const ClpDualRowDantzig& rhs); + + /// Destructor + virtual ~ClpDualRowDantzig (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDualRowPivot.hpp b/thirdparty/linux/include/coin/coin/ClpDualRowPivot.hpp new file mode 100644 index 0000000..f1f57a6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDualRowPivot.hpp @@ -0,0 +1,129 @@ +/* $Id: ClpDualRowPivot.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowPivot_H +#define ClpDualRowPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Dual Row Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose row pivot in dual simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. + +*/ + +class ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow() = 0; + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn) = 0; + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + Would be faster if we kept basic regions, but on other hand it + means everything is always in sync + */ + /* FIXME: this was pure virtul (=0). Why? */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective) = 0; + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize to 1 , infeasibilities + 6) scale back + 7) for strong branching - initialize full weights , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// checks accuracy and may re-initialize (may be empty) + virtual void checkAccuracy(); + /// Gets rid of last update (may be empty) + virtual void unrollWeights(); + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const { + return false; + } + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowPivot(); + + /// Copy constructor + ClpDualRowPivot(const ClpDualRowPivot &); + + /// Assignment operator + ClpDualRowPivot & operator=(const ClpDualRowPivot& rhs); + + /// Destructor + virtual ~ClpDualRowPivot (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + + /// Sets model (normally to NULL) + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of row pivot algorithm + int type_; + //@} +}; +#ifndef CLP_DUAL_COLUMN_MULTIPLIER +//#define CLP_DUAL_COLUMN_MULTIPLIER 0.99999 +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDualRowSteepest.hpp b/thirdparty/linux/include/coin/coin/ClpDualRowSteepest.hpp new file mode 100644 index 0000000..7e2cc62 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDualRowSteepest.hpp @@ -0,0 +1,153 @@ +/* $Id: ClpDualRowSteepest.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowSteepest_H +#define ClpDualRowSteepest_H + +#include "ClpDualRowPivot.hpp" +class CoinIndexedVector; + + +//############################################################################# + +/** Dual Row Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + +class ClpDualRowSteepest : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + + /** Saves any weights round factorization as pivot rows may change + Save model + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize (uninitialized) , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Pass in saved weights + void passInSavedWeights(const CoinIndexedVector * saved); + /// Get saved weights + inline CoinIndexedVector * savedWeights() + { return savedWeights_;} + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is uninitialized, 1 full, 2 is partial uninitialized, + 3 starts as 2 but may switch to 1. + By partial is meant that the weights are updated as normal + but only part of the infeasible basic variables are scanned. + This can be faster on very easy problems. + */ + ClpDualRowSteepest(int mode = 3); + + /// Copy constructor + ClpDualRowSteepest(const ClpDualRowSteepest &); + + /// Assignment operator + ClpDualRowSteepest & operator=(const ClpDualRowSteepest& rhs); + + /// Fill most values + void fill(const ClpDualRowSteepest& rhs); + + /// Destructor + virtual ~ClpDualRowSteepest (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /// Set mode + inline void setMode(int mode) { + mode_ = mode; + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } +//@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** If 0 then we are using uninitialized weights, 1 then full, + if 2 then uninitialized partial, 3 switchable */ + int mode_; + /// Life of weights + Persistence persistence_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible rows) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + CoinIndexedVector * savedWeights_; + /// Dubious weights + int * dubiousWeights_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDummyMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpDummyMatrix.hpp new file mode 100644 index 0000000..1b4a2d4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDummyMatrix.hpp @@ -0,0 +1,183 @@ +/* $Id: ClpDummyMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDummyMatrix_H +#define ClpDummyMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a dummy matrix as derived from ClpMatrixBase. + This is so you can do ClpPdco but may come in useful elsewhere. + It just has dimensions but no data +*/ + + +class ClpDummyMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return numberElements_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const; + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const {} + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + + using ClpMatrixBase::transposeTimes ; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDummyMatrix(); + /// Constructor with data + ClpDummyMatrix(int numberColumns, int numberRows, + int numberElements); + /** Destructor */ + virtual ~ClpDummyMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDummyMatrix(const ClpDummyMatrix&); + /** The copy constructor from an CoinDummyMatrix. */ + ClpDummyMatrix(const CoinPackedMatrix&); + + ClpDummyMatrix& operator=(const ClpDummyMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Number of elements + int numberElements_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDynamicExampleMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpDynamicExampleMatrix.hpp new file mode 100644 index 0000000..81fe5ba --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDynamicExampleMatrix.hpp @@ -0,0 +1,186 @@ +/* $Id: ClpDynamicExampleMatrix.hpp 1936 2013-04-09 10:29:27Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicExampleMatrix_H +#define ClpDynamicExampleMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpDynamicMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpDynamicMatrix and knows that + the real matrix is gub. This acts just like ClpDynamicMatrix but generates columns. + This "generates" columns by choosing from stored set. It is maent as a starting point + as to how you could use shortest path to generate columns. + + So it has its own copy of all data needed. It populates ClpDynamicWatrix with enough + to allow for gub keys and active variables. In turn ClpDynamicMatrix populates + a CoinPackedMatrix with active columns and rows. + + As there is one copy here and one in ClpDynamicmatrix these names end in Gen_ + + It is obviously more efficient to just use ClpDynamicMatrix but the ideas is to + show how much code a user would have to write. + + This does not work very well with bounds + +*/ + +class ClpDynamicExampleMatrix : public ClpDynamicMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** If addColumn forces compression then this allows descendant to know what to do. + If >= then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * in, int numberToPack); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicExampleMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#if 0 + /// This constructor just takes over ownership (except for lower, upper) + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, int * starts, + const double * lower, const double * upper, + int * startColumn, int * row, + double * element, double * cost, + double * columnLower = NULL, double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#endif + /** Destructor */ + virtual ~ClpDynamicExampleMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicExampleMatrix(const ClpDynamicExampleMatrix&); + ClpDynamicExampleMatrix& operator=(const ClpDynamicExampleMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Starts of each column + inline CoinBigIndex * startColumnGen() const { + return startColumnGen_; + } + /// rows + inline int * rowGen() const { + return rowGen_; + } + /// elements + inline double * elementGen() const { + return elementGen_; + } + /// costs + inline double * costGen() const { + return costGen_; + } + /// full starts + inline int * fullStartGen() const { + return fullStartGen_; + } + /// ids in next level matrix + inline int * idGen() const { + return idGen_; + } + /// Optional lower bounds on columns + inline double * columnLowerGen() const { + return columnLowerGen_; + } + /// Optional upper bounds on columns + inline double * columnUpperGen() const { + return columnUpperGen_; + } + /// size + inline int numberColumns() const { + return numberColumns_; + } + inline void setDynamicStatusGen(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatusGen_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatusGen(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatusGen_[sequence] & 7); + } + /// Whether flagged + inline bool flaggedGen(int i) const { + return (dynamicStatusGen_[i] & 8) != 0; + } + inline void setFlaggedGen(int i) { + dynamicStatusGen_[i] = static_cast<unsigned char>(dynamicStatusGen_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatusGen_[i] = static_cast<unsigned char>(dynamicStatusGen_[i] & ~8); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// size + int numberColumns_; + /// Starts of each column + CoinBigIndex * startColumnGen_; + /// rows + int * rowGen_; + /// elements + double * elementGen_; + /// costs + double * costGen_; + /// start of each set + int * fullStartGen_; + /// for status and which bound + unsigned char * dynamicStatusGen_; + /** identifier for each variable up one level (startColumn_, etc). This is + of length maximumGubColumns_. For this version it is just sequence number + at this level */ + int * idGen_; + /// Optional lower bounds on columns + double * columnLowerGen_; + /// Optional upper bounds on columns + double * columnUpperGen_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpDynamicMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpDynamicMatrix.hpp new file mode 100644 index 0000000..da4e144 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpDynamicMatrix.hpp @@ -0,0 +1,381 @@ +/* $Id: ClpDynamicMatrix.hpp 1755 2011-06-28 18:24:31Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicMatrix_H +#define ClpDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpPackedMatrix and knows that + the real matrix is gub. A later version could use shortest path to generate columns. + +*/ + +class ClpDynamicMatrix : public ClpPackedMatrix { + +public: + /// enums for status of various sorts + enum DynamicStatus { + soloKey = 0x00, + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big dynamic or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// Modifies rhs offset + void modifyOffset(int sequence, double amount); + /// Gets key value when none in small + double keyValue(int iSet) const; + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * model); + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /// Returns reduced cost of a variable + virtual double reducedCost( ClpSimplex * model, int sequence) const; + /// Does gub crash + void gubCrash(); + /// Writes out model (without names) + void writeMps(const char * name); + /// Populates initial matrix from dynamic status + void initialProblem(); + /** Adds in a column to gub structure (called from descendant) and returns sequence */ + int addColumn(int numberEntries, const int * row, const double * element, + double cost, double lower, double upper, int iSet, + DynamicStatus status); + /** If addColumn forces compression then this allows descendant to know what to do. + If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * , int ) {} + /// Gets lower bound (to simplify coding) + inline double columnLower(int sequence) const { + if (columnLower_) return columnLower_[sequence]; + else return 0.0; + } + /// Gets upper bound (to simplify coding) + inline double columnUpper(int sequence) const { + if (columnUpper_) return columnUpper_[sequence]; + else return COIN_DBL_MAX; + } + + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const CoinBigIndex * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL); + + /** Destructor */ + virtual ~ClpDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicMatrix(const ClpDynamicMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpDynamicMatrix(const CoinPackedMatrix&); + + ClpDynamicMatrix& operator=(const ClpDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Status of row slacks + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast<ClpSimplex::Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + /// Whether flagged slack + inline bool flaggedSlack(int i) const { + return (status_[i] & 8) != 0; + } + inline void setFlaggedSlack(int i) { + status_[i] = static_cast<unsigned char>(status_[i] | 8); + } + inline void unsetFlaggedSlack(int i) { + status_[i] = static_cast<unsigned char>(status_[i] & ~8); + } + /// Number of sets (dynamic rows) + inline int numberSets() const { + return numberSets_; + } + /// Number of possible gub variables + inline int numberGubEntries() const + { return startSet_[numberSets_];} + /// Sets + inline int * startSets() const + { return startSet_;} + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * columnLower() const { + return columnLower_; + } + /// Optional upper bounds on columns + inline double * columnUpper() const { + return columnUpper_; + } + /// Lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// number of rows in original model + inline int numberStaticRows() const { + return numberStaticRows_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + inline int * keyVariable() const { + return keyVariable_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Saved best dual on gub row in pricing + double savedBestGubDual_; + /// Saved best set in pricing + int savedBestSet_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Key variable of set (only accurate if none in small problem) + mutable int * keyVariable_; + /// Backward pointer to extra row + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Number of sets (dynamic rows) + int numberSets_; + /// Number of active sets + int numberActiveSets_; + /// Saved value of objective offset + double objectiveOffset_; + /// Lower bounds on sets + double * lowerSet_; + /// Upper bounds on sets + double * upperSet_; + /// Status of slack on set + unsigned char * status_; + /// Pointer back to model + ClpSimplex * model_; + /// first free + int firstAvailable_; + /// first free when iteration started + int firstAvailableBefore_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// number of rows in original model + int numberStaticRows_; + /// size of working matrix (max) + int numberElements_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// size + int numberGubColumns_; + /// current maximum number of columns (then compress) + int maximumGubColumns_; + /// current maximum number of elemnts (then compress) + int maximumElements_; + /// Start of each set + int * startSet_; + /// next in chain + int * next_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * columnLower_; + /// Optional upper bounds on columns + double * columnUpper_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpEventHandler.hpp b/thirdparty/linux/include/coin/coin/ClpEventHandler.hpp new file mode 100644 index 0000000..aeed324 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpEventHandler.hpp @@ -0,0 +1,187 @@ +/* $Id: ClpEventHandler.hpp 2156 2015-08-07 14:51:42Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpEventHandler_H +#define ClpEventHandler_H + +#include "ClpSimplex.hpp" +/** Base class for Clp event handling + +This is just here to allow for event handling. By event I mean a Clp event +e.g. end of values pass. + +One use would be to let a user handle a system event e.g. Control-C. This could be done +by deriving a class MyEventHandler which knows about such events. If one occurs +MyEventHandler::event() could clear event status and return 3 (stopped). + +Clp would then return to user code. + +As it is called every iteration this should be fine grained enough. + +User can derive and construct from CbcModel - not pretty + +*/ + +class ClpEventHandler { + +public: + /** enums for what sort of event. + + These will also be returned in ClpModel::secondaryStatus() as int + */ + enum Event { + endOfIteration = 100, // used to set secondary status + endOfFactorization, // after gutsOfSolution etc + endOfValuesPass, + node, // for Cbc + treeStatus, // for Cbc + solution, // for Cbc + theta, // hit in parametrics + pivotRow, // used to choose pivot row + presolveStart, // ClpSolve presolve start + presolveSize, // sees if ClpSolve presolve too big or too small + presolveInfeasible, // ClpSolve presolve infeasible + presolveBeforeSolve, // ClpSolve presolve before solve + presolveAfterFirstSolve, // ClpSolve presolve after solve + presolveAfterSolve, // ClpSolve presolve after solve + presolveEnd, // ClpSolve presolve end + goodFactorization, // before gutsOfSolution + complicatedPivotIn, // in modifyCoefficients + noCandidateInPrimal, // tentative end + looksEndInPrimal, // About to declare victory (or defeat) + endInPrimal, // Victory (or defeat) + beforeStatusOfProblemInPrimal, + startOfStatusOfProblemInPrimal, + complicatedPivotOut, // in modifyCoefficients + noCandidateInDual, // tentative end + looksEndInDual, // About to declare victory (or defeat) + endInDual, // Victory (or defeat) + beforeStatusOfProblemInDual, + startOfStatusOfProblemInDual, + startOfIterationInDual, + updateDualsInDual, + endOfCreateRim, + slightlyInfeasible, + modifyMatrixInMiniPresolve, + moreMiniPresolve, + modifyMatrixInMiniPostsolve, + startOfCrossover, // in Idiot + noTheta // At end (because no pivot) + }; + /**@name Virtual method that the derived classes should provide. + The base class instance does nothing and as event() is only useful method + it would not be very useful NOT providing one! + */ + //@{ + /** This can do whatever it likes. If return code -1 then carries on + if 0 sets ClpModel::status() to 5 (stopped by event) and will return to user. + At present if <-1 carries on and if >0 acts as if 0 - this may change. + For ClpSolve 2 -> too big return status of -2 and -> too small 3 + */ + virtual int event(Event whichEvent); + /** This can do whatever it likes. Return code -1 means no action. + This passes in something + */ + virtual int eventWithInfo(Event whichEvent, void * info) ; + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpEventHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpEventHandler(); + // Copy + ClpEventHandler(const ClpEventHandler&); + // Assignment + ClpEventHandler& operator=(const ClpEventHandler&); + /// Clone + virtual ClpEventHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +/** Base class for Clp disaster handling + +This is here to allow for disaster handling. By disaster I mean that Clp +would otherwise give up + +*/ + +class ClpDisasterHandler { + +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex() = 0; + /// Checks if disaster + virtual bool check() const = 0; + /// saves information for next attempt + virtual void saveInfo() = 0; + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpDisasterHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpDisasterHandler(); + // Copy + ClpDisasterHandler(const ClpDisasterHandler&); + // Assignment + ClpDisasterHandler& operator=(const ClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const = 0; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpFactorization.hpp b/thirdparty/linux/include/coin/coin/ClpFactorization.hpp new file mode 100644 index 0000000..dda8ff7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpFactorization.hpp @@ -0,0 +1,432 @@ +/* $Id: ClpFactorization.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpFactorization_H +#define ClpFactorization_H + + +#include "CoinPragma.hpp" + +#include "CoinFactorization.hpp" +class ClpMatrixBase; +class ClpSimplex; +class ClpNetworkBasis; +class CoinOtherFactorization; +#ifndef CLP_MULTIPLE_FACTORIZATIONS +#define CLP_MULTIPLE_FACTORIZATIONS 4 +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS +#include "CoinDenseFactorization.hpp" +#include "ClpSimplex.hpp" +#endif +#ifndef COIN_FAST_CODE +#define COIN_FAST_CODE +#endif +#ifndef CLP_FACTORIZATION_NEW_TIMING +#define CLP_FACTORIZATION_NEW_TIMING 1 +#endif + +/** This just implements CoinFactorization when an ClpMatrixBase object + is passed. If a network then has a dummy CoinFactorization and + a genuine ClpNetworkBasis object +*/ +class ClpFactorization +#ifndef CLP_MULTIPLE_FACTORIZATIONS + : public CoinFactorization +#endif +{ + + //friend class CoinFactorization; + +public: + /**@name factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + if increasingRows_ >1. + Allows scaling + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize (ClpSimplex * model, int solveType, bool valuesPass); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpFactorization(); + /** Destructor */ + ~ClpFactorization(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor from an CoinFactorization. */ + ClpFactorization(const CoinFactorization&); + /** The copy constructor. */ + ClpFactorization(const ClpFactorization&, int denseIfSmaller = 0); +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /** The copy constructor from an CoinOtherFactorization. */ + ClpFactorization(const CoinOtherFactorization&); +#endif + ClpFactorization& operator=(const ClpFactorization&); + //@} + + /* **** below here is so can use networkish basis */ + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( const ClpSimplex * model, + CoinIndexedVector * regionSparse, + CoinIndexedVector * tableauColumn, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying = false, + double acceptablePivot = 1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room + region1 starts as zero and is zero at end */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** Updates one column (FTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3 = false) ; + /// For debug (no statistics update) + int updateColumnForDebug ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (BTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /**@name Lifted from CoinFactorization */ + //@{ + /// Total number of elements in factorization + inline int numberElements ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElements(); + else return coinFactorizationB_->numberElements() ; + } + /// Returns address of permute region + inline int *permute ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->permute(); + else return coinFactorizationB_->permute() ; + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotColumn(); + else return coinFactorizationB_->permute() ; + } + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->maximumPivots(); + else return coinFactorizationB_->maximumPivots() ; + } + /// Set maximum number of pivots between factorizations + inline void maximumPivots ( int value) { + if (coinFactorizationA_) coinFactorizationA_->maximumPivots(value); + else coinFactorizationB_->maximumPivots(value); + } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivots(); + else return coinFactorizationB_->pivots() ; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->areaFactor(); + else return 0.0 ; + } + /// Set whether larger areas needed + inline void areaFactor ( double value) { + if (coinFactorizationA_) coinFactorizationA_->areaFactor(value); + } + /// Zero tolerance + inline double zeroTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->zeroTolerance(); + else return coinFactorizationB_->zeroTolerance() ; + } + /// Set zero tolerance + inline void zeroTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->zeroTolerance(value); + else coinFactorizationB_->zeroTolerance(value); + } + /// Set tolerances to safer of existing and given + void saferTolerances ( double zeroTolerance, double pivotTolerance); + /** get sparse threshold */ + inline int sparseThreshold ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold(); + else return 0 ; + } + /** Set sparse threshold */ + inline void sparseThreshold ( int value) { + if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value); + } + /// Returns status + inline int status ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->status(); + else return coinFactorizationB_->status() ; + } + /// Sets status + inline void setStatus ( int value) { + if (coinFactorizationA_) coinFactorizationA_->setStatus(value); + else coinFactorizationB_->setStatus(value) ; + } + /// Returns number of dense rows + inline int numberDense() const { + if (coinFactorizationA_) return coinFactorizationA_->numberDense(); + else return 0 ; + } +#if 1 + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsU(); + else return -1 ; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsL(); + else return -1 ; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsR(); + else return 0 ; + } +#endif + bool timeToRefactorize() const; +#if CLP_FACTORIZATION_NEW_TIMING>1 + void statsRefactor(char when) const; +#endif + /// Level of detail of messages + inline int messageLevel ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->messageLevel(); + else return 1 ; + } + /// Set level of detail of messages + inline void messageLevel ( int value) { + if (coinFactorizationA_) coinFactorizationA_->messageLevel(value); + } + /// Get rid of all memory + inline void clearArrays() { + if (coinFactorizationA_) + coinFactorizationA_->clearArrays(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Number of Rows after factorization + inline int numberRows ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberRows(); + else return coinFactorizationB_->numberRows() ; + } + /// Gets dense threshold + inline int denseThreshold() const { + if (coinFactorizationA_) return coinFactorizationA_->denseThreshold(); + else return 0 ; + } + /// Sets dense threshold + inline void setDenseThreshold(int value) { + if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value); + } + /// Pivot tolerance + inline double pivotTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance(); + else if (coinFactorizationB_) return coinFactorizationB_->pivotTolerance(); + return 1.0e-8 ; + } + /// Set pivot tolerance + inline void pivotTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value); + else if (coinFactorizationB_) coinFactorizationB_->pivotTolerance(value); + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) { + if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value); + } + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const { + if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag(); + else return 0 ; + } + inline void setPersistenceFlag(int value) { + if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value); + } + /// Delete all stuff (leaves as after CoinFactorization()) + inline void almostDestructor() { + if (coinFactorizationA_) + coinFactorizationA_->almostDestructor(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Returns areaFactor but adjusted for dense + inline double adjustedAreaFactor() const { + if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor(); + else return 0.0 ; + } + inline void setBiasLU(int value) { + if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value); + } + /// true if Forrest Tomlin update, false if PFI + inline void setForrestTomlin(bool value) { + if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value); + } + /// Sets default values + inline void setDefaultValues() { + if (coinFactorizationA_) { + // row activities have negative sign +#ifndef COIN_FAST_CODE + coinFactorizationA_->slackValue(-1.0); +#endif + coinFactorizationA_->zeroTolerance(1.0e-13); + } + } + /// If nonzero force use of 1,dense 2,small 3,osl + void forceOtherFactorization(int which); + /// Get switch to osl if number rows <= this + inline int goOslThreshold() const { + return goOslThreshold_; + } + /// Set switch to osl if number rows <= this + inline void setGoOslThreshold(int value) { + goOslThreshold_ = value; + } + /// Get switch to dense if number rows <= this + inline int goDenseThreshold() const { + return goDenseThreshold_; + } + /// Set switch to dense if number rows <= this + inline void setGoDenseThreshold(int value) { + goDenseThreshold_ = value; + } + /// Get switch to small if number rows <= this + inline int goSmallThreshold() const { + return goSmallThreshold_; + } + /// Set switch to small if number rows <= this + inline void setGoSmallThreshold(int value) { + goSmallThreshold_ = value; + } + /// Go over to dense or small code if small enough + void goDenseOrSmall(int numberRows) ; + /// Sets factorization + void setFactorization(ClpFactorization & factorization); + /// Return 1 if dense code + inline int isDenseOrSmall() const { + return coinFactorizationB_ ? 1 : 0; + } +#else + inline bool timeToRefactorize() const { + return (pivots() * 3 > maximumPivots() * 2 && + numberElementsR() * 3 > (numberElementsL() + numberElementsU()) * 2 + 1000 && + !numberDense()); + } + /// Sets default values + inline void setDefaultValues() { + // row activities have negative sign +#ifndef COIN_FAST_CODE + slackValue(-1.0); +#endif + zeroTolerance(1.0e-13); + } + /// Go over to dense code + inline void goDense() {} +#endif + //@} + + /**@name other stuff */ + //@{ + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /// Cleans up i.e. gets rid of network basis + void cleanUp(); + /// Says whether to redo pivot order + bool needToReorder() const; +#ifndef SLIM_CLP + /// Says if a network basis + inline bool networkBasis() const { + return (networkBasis_ != NULL); + } +#else + /// Says if a network basis + inline bool networkBasis() const { + return false; + } +#endif + /// Fills weighted row list + void getWeights(int * weights) const; + //@} + +////////////////// data ////////////////// +private: + + /**@name data */ + //@{ + /// Pointer to network basis +#ifndef SLIM_CLP + ClpNetworkBasis * networkBasis_; +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /// Pointer to CoinFactorization + CoinFactorization * coinFactorizationA_; + /// Pointer to CoinOtherFactorization + CoinOtherFactorization * coinFactorizationB_; +#ifdef CLP_REUSE_ETAS + /// Pointer to model + ClpSimplex * model_; +#endif + /// If nonzero force use of 1,dense 2,small 3,osl + int forceB_; + /// Switch to osl if number rows <= this + int goOslThreshold_; + /// Switch to small if number rows <= this + int goSmallThreshold_; + /// Switch to dense if number rows <= this + int goDenseThreshold_; +#endif +#ifdef CLP_FACTORIZATION_NEW_TIMING + /// For guessing when to re-factorize + mutable double shortestAverage_; + mutable double totalInR_; + mutable double totalInIncreasingU_; + mutable int endLengthU_; + mutable int lastNumberPivots_; + mutable int effectiveStartNumberU_; +#endif + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpGubDynamicMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpGubDynamicMatrix.hpp new file mode 100644 index 0000000..2d13e6d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpGubDynamicMatrix.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpGubDynamicMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubDynamicMatrix_H +#define ClpGubDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpGubMatrix.hpp" +/** This implements Gub rows plus a ClpPackedMatrix. + This a dynamic version which stores the gub part and dynamically creates matrix. + All bounds are assumed to be zero and infinity + + This is just a simple example for real column generation +*/ + +class ClpGubDynamicMatrix : public ClpGubMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Add a new variable to a set + void insertNonBasic(int sequence, int iSet); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /** Just for debug + Returns sum and number of primal infeasibilities. Recomputes keys + */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const; + /// Cleans data after setWarmStart + void cleanData(ClpSimplex * model); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubDynamicMatrix(); + /** Destructor */ + virtual ~ClpGubDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubDynamicMatrix(const ClpGubDynamicMatrix&); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + */ + ClpGubDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * lowerColumn = NULL, const double * upperColumn = NULL, + const unsigned char * status = NULL); + + ClpGubDynamicMatrix& operator=(const ClpGubDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// enums for status of various sorts + enum DynamicStatus { + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// full starts + inline int * fullStart() const { + return fullStart_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * lowerColumn() const { + return lowerColumn_; + } + /// Optional upper bounds on columns + inline double * upperColumn() const { + return upperColumn_; + } + /// Optional true lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Optional true upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// set first free + inline void setFirstAvailable(int value) { + firstAvailable_ = value; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Saved value of objective offset + double objectiveOffset_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// full starts + int * fullStart_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * lowerColumn_; + /// Optional upper bounds on columns + double * upperColumn_; + /// Optional true lower bounds on sets + double * lowerSet_; + /// Optional true upper bounds on sets + double * upperSet_; + /// size + int numberGubColumns_; + /// first free + int firstAvailable_; + /// saved first free + int savedFirstAvailable_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// size of working matrix (max) + int numberElements_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpGubMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpGubMatrix.hpp new file mode 100644 index 0000000..26c3f62 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpGubMatrix.hpp @@ -0,0 +1,358 @@ +/* $Id: ClpGubMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubMatrix_H +#define ClpGubMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements Gub rows plus a ClpPackedMatrix. + + There will be a version using ClpPlusMinusOne matrix but + there is no point doing one with ClpNetworkMatrix (although + an embedded network is attractive). + +*/ + +class ClpGubMatrix : public ClpPackedMatrix { + +public: + /**@name Main functions provided */ + //@{ + /** Returns a new matrix in reverse order without gaps (GUB wants NULL) */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + //@} + + /**@name Matrix times vector methods */ + //@{ + + using ClpPackedMatrix::transposeTimes ; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added if mode 0. + If mode 1 deletes extra entries + + This active in Gub + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=6 - return 1 if there may be changing bounds on variable (column generation) + mode=7 - do extra restores for column generation + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubMatrix(); + /** Destructor */ + virtual ~ClpGubMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubMatrix(const ClpGubMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpGubMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpGubMatrix (const ClpGubMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpGubMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpGubMatrix(CoinPackedMatrix * matrix); + + /** This takes over ownership (for space reasons) and is the + real constructor*/ + ClpGubMatrix(ClpPackedMatrix * matrix, int numberSets, + const int * start, const int * end, + const double * lower, const double * upper, + const unsigned char * status = NULL); + + ClpGubMatrix& operator=(const ClpGubMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /** redoes next_ for a set. */ + void redoSet(ClpSimplex * model, int newKey, int oldKey, int iSet); + //@} + /**@name gets and sets */ + //@{ + /// Status + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast<ClpSimplex::Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64); + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say key is above ub + inline void setAbove( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = static_cast<unsigned char>(iStat | 16); + } + /// To say key is feasible + inline void setFeasible( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = static_cast<unsigned char>(iStat | 8); + } + /// To say key is below lb + inline void setBelow( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = iStat; + } + inline double weight( int sequence) const { + int iStat = status_[sequence] & 31; + iStat = iStat >> 3; + return static_cast<double> (iStat - 1); + } + /// Starts + inline int * start() const { + return start_; + } + /// End + inline int * end() const { + return end_; + } + /// Lower bounds on sets + inline double * lower() const { + return lower_; + } + /// Upper bounds on sets + inline double * upper() const { + return upper_; + } + /// Key variable of set + inline int * keyVariable() const { + return keyVariable_; + } + /// Backward pointer to set number + inline int * backward() const { + return backward_; + } + /// Number of sets (gub rows) + inline int numberSets() const { + return numberSets_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// Starts + int * start_; + /// End + int * end_; + /// Lower bounds on sets + double * lower_; + /// Upper bounds on sets + double * upper_; + /// Status of slacks + mutable unsigned char * status_; + /// Saved status of slacks + unsigned char * saveStatus_; + /// Saved key variables + int * savedKeyVariable_; + /// Backward pointer to set number + int * backward_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Change in costs for keys + double * changeCost_; + /// Key variable of set + mutable int * keyVariable_; + /** Next basic variable in set - starts at key and end with -(set+1). + Now changes to -(nonbasic+1). + next_ has extra space for 2* longest set */ + mutable int * next_; + /// Backward pointer to index in CoinIndexedVector + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Pointer back to model + ClpSimplex * model_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Number of sets (gub rows) + int numberSets_; + /// Number in vector without gub extension + int saveNumber_; + /// Pivot row of possible next key + int possiblePivotKey_; + /// Gub slack in (set number or -1) + int gubSlackIn_; + /// First gub variables (same as start_[0] at present) + int firstGub_; + /// last gub variable (same as end_[numberSets_-1] at present) + int lastGub_; + /** type of gub - 0 not contiguous, 1 contiguous + add 8 bit to say no ubs on individual variables */ + int gubType_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpInterior.hpp b/thirdparty/linux/include/coin/coin/ClpInterior.hpp new file mode 100644 index 0000000..7f87e1e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpInterior.hpp @@ -0,0 +1,570 @@ +/* $Id: ClpInterior.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Tomlin (pdco) + John Forrest (standard predictor-corrector) + + Note JJF has added arrays - this takes more memory but makes + flow easier to understand and hopefully easier to extend + + */ +#ifndef ClpInterior_H +#define ClpInterior_H + +#include <iostream> +#include <cfloat> +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "CoinDenseVector.hpp" +class ClpLsqr; +class ClpPdcoBase; +/// ******** DATA to be moved into protected section of ClpInterior +typedef struct { + double atolmin; + double r3norm; + double LSdamp; + double* deltay; +} Info; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double atolold; + double atolnew; + double r3ratio; + int istop; + int itncg; +} Outfo; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double gamma; + double delta; + int MaxIter; + double FeaTol; + double OptTol; + double StepTol; + double x0min; + double z0min; + double mu0; + int LSmethod; // 1=Cholesky 2=QR 3=LSQR + int LSproblem; // See below + int LSQRMaxIter; + double LSQRatol1; // Initial atol + double LSQRatol2; // Smallest atol (unless atol1 is smaller) + double LSQRconlim; + int wait; +} Options; +class Lsqr; +class ClpCholeskyBase; +// ***** END +/** This solves LPs using interior point methods + + It inherits from ClpModel and all its arrays are created at + algorithm time. + +*/ + +class ClpInterior : public ClpModel { + friend void ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpInterior ( ); + + /// Copy constructor. + ClpInterior(const ClpInterior &); + /// Copy constructor from model. + ClpInterior(const ClpModel &); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpInterior (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Assignment operator. This copies the data + ClpInterior & operator=(const ClpInterior & rhs); + /// Destructor + ~ClpInterior ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one. */ + void borrowModel(ClpModel & otherModel); + /** Return model - updates any scalars */ + void returnModel(ClpModel & otherModel); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Pdco algorithm - see ClpPdco.hpp for method */ + int pdco(); + // ** Temporary version + int pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo); + /// Primal-Dual Predictor-Corrector barrier + int primalDual(); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (sumPrimalInfeasibilities_ <= 1.0e-5); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (sumDualInfeasibilities_ <= 1.0e-5); + } + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Sum of dual infeasibilities + inline CoinWorkDouble sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + /// Sum of primal infeasibilities + inline CoinWorkDouble sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + /// dualObjective. + inline CoinWorkDouble dualObjective() const { + return dualObjective_; + } + /// primalObjective. + inline CoinWorkDouble primalObjective() const { + return primalObjective_; + } + /// diagonalNorm + inline CoinWorkDouble diagonalNorm() const { + return diagonalNorm_; + } + /// linearPerturbation + inline CoinWorkDouble linearPerturbation() const { + return linearPerturbation_; + } + inline void setLinearPerturbation(CoinWorkDouble value) { + linearPerturbation_ = value; + } + /// projectionTolerance + inline CoinWorkDouble projectionTolerance() const { + return projectionTolerance_; + } + inline void setProjectionTolerance(CoinWorkDouble value) { + projectionTolerance_ = value; + } + /// diagonalPerturbation + inline CoinWorkDouble diagonalPerturbation() const { + return diagonalPerturbation_; + } + inline void setDiagonalPerturbation(CoinWorkDouble value) { + diagonalPerturbation_ = value; + } + /// gamma + inline CoinWorkDouble gamma() const { + return gamma_; + } + inline void setGamma(CoinWorkDouble value) { + gamma_ = value; + } + /// delta + inline CoinWorkDouble delta() const { + return delta_; + } + inline void setDelta(CoinWorkDouble value) { + delta_ = value; + } + /// ComplementarityGap + inline CoinWorkDouble complementarityGap() const { + return complementarityGap_; + } + //@} + + /**@name most useful gets and sets */ + //@{ + /// Largest error on Ax-b + inline CoinWorkDouble largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline CoinWorkDouble largestDualError() const { + return largestDualError_; + } + /// Maximum iterations + inline int maximumBarrierIterations() const { + return maximumBarrierIterations_; + } + inline void setMaximumBarrierIterations(int value) { + maximumBarrierIterations_ = value; + } + /// Set cholesky (and delete present one) + void setCholesky(ClpCholeskyBase * cholesky); + /// Return number fixed to see if worth presolving + int numberFixed() const; + /** fix variables interior says should be. If reallyFix false then just + set values to exact bounds */ + void fixFixed(bool reallyFix = true); + /// Primal erturbation vector + inline CoinWorkDouble * primalR() const { + return primalR_; + } + /// Dual erturbation vector + inline CoinWorkDouble * dualR() const { + return dualR_; + } + //@} + +protected: + /**@name protected methods */ + //@{ + /// Does most of deletion + void gutsOfDelete(); + /// Does most of copying + void gutsOfCopy(const ClpInterior & rhs); + /// Returns true if data looks okay, false if not + bool createWorkingData(); + void deleteWorkingData(); + /// Sanity check on input rim data + bool sanityCheck(); + /// This does housekeeping + int housekeeping(); + //@} +public: + /**@name public methods */ + //@{ + /// Raw objective value (so always minimize) + inline CoinWorkDouble rawObjectiveValue() const { + return objectiveValue_; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Checks solution + void checkSolution(); + /** Modifies djs to allow for quadratic. + returns quadratic offset */ + CoinWorkDouble quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution, + CoinWorkDouble scaleFactor); + + /// To say a variable is fixed + inline void setFixed( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 1) ; + } + inline void clearFixed( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~1) ; + } + inline bool fixed(int sequence) const { + return ((status_[sequence] & 1) != 0); + } + + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 2) ; + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~2) ; + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 2) != 0); + } + + /// To say a variable is fixed OR free + inline void setFixedOrFree( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 4) ; + } + inline void clearFixedOrFree( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~4) ; + } + inline bool fixedOrFree(int sequence) const { + return ((status_[sequence] & 4) != 0); + } + + /// To say a variable has lower bound + inline void setLowerBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 8) ; + } + inline void clearLowerBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~8) ; + } + inline bool lowerBound(int sequence) const { + return ((status_[sequence] & 8) != 0); + } + + /// To say a variable has upper bound + inline void setUpperBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 16) ; + } + inline void clearUpperBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~16) ; + } + inline bool upperBound(int sequence) const { + return ((status_[sequence] & 16) != 0); + } + + /// To say a variable has fake lower bound + inline void setFakeLower( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 32) ; + } + inline void clearFakeLower( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~32) ; + } + inline bool fakeLower(int sequence) const { + return ((status_[sequence] & 32) != 0); + } + + /// To say a variable has fake upper bound + inline void setFakeUpper( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64) ; + } + inline void clearFakeUpper( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64) ; + } + inline bool fakeUpper(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /// Largest error on Ax-b + CoinWorkDouble largestPrimalError_; + /// Largest error on basic duals + CoinWorkDouble largestDualError_; + /// Sum of dual infeasibilities + CoinWorkDouble sumDualInfeasibilities_; + /// Sum of primal infeasibilities + CoinWorkDouble sumPrimalInfeasibilities_; + /// Worst complementarity + CoinWorkDouble worstComplementarity_; + /// +public: + CoinWorkDouble xsize_; + CoinWorkDouble zsize_; +protected: + /// Working copy of lower bounds (Owner of arrays below) + CoinWorkDouble * lower_; + /// Row lower bounds - working copy + CoinWorkDouble * rowLowerWork_; + /// Column lower bounds - working copy + CoinWorkDouble * columnLowerWork_; + /// Working copy of upper bounds (Owner of arrays below) + CoinWorkDouble * upper_; + /// Row upper bounds - working copy + CoinWorkDouble * rowUpperWork_; + /// Column upper bounds - working copy + CoinWorkDouble * columnUpperWork_; + /// Working copy of objective + CoinWorkDouble * cost_; +public: + /// Rhs + CoinWorkDouble * rhs_; + CoinWorkDouble * x_; + CoinWorkDouble * y_; + CoinWorkDouble * dj_; +protected: + /// Pointer to Lsqr object + ClpLsqr * lsqrObject_; + /// Pointer to stuff + ClpPdcoBase * pdcoStuff_; + /// Below here is standard barrier stuff + /// mu. + CoinWorkDouble mu_; + /// objectiveNorm. + CoinWorkDouble objectiveNorm_; + /// rhsNorm. + CoinWorkDouble rhsNorm_; + /// solutionNorm. + CoinWorkDouble solutionNorm_; + /// dualObjective. + CoinWorkDouble dualObjective_; + /// primalObjective. + CoinWorkDouble primalObjective_; + /// diagonalNorm. + CoinWorkDouble diagonalNorm_; + /// stepLength + CoinWorkDouble stepLength_; + /// linearPerturbation + CoinWorkDouble linearPerturbation_; + /// diagonalPerturbation + CoinWorkDouble diagonalPerturbation_; + // gamma from Saunders and Tomlin regularized + CoinWorkDouble gamma_; + // delta from Saunders and Tomlin regularized + CoinWorkDouble delta_; + /// targetGap + CoinWorkDouble targetGap_; + /// projectionTolerance + CoinWorkDouble projectionTolerance_; + /// maximumRHSError. maximum Ax + CoinWorkDouble maximumRHSError_; + /// maximumBoundInfeasibility. + CoinWorkDouble maximumBoundInfeasibility_; + /// maximumDualError. + CoinWorkDouble maximumDualError_; + /// diagonalScaleFactor. + CoinWorkDouble diagonalScaleFactor_; + /// scaleFactor. For scaling objective + CoinWorkDouble scaleFactor_; + /// actualPrimalStep + CoinWorkDouble actualPrimalStep_; + /// actualDualStep + CoinWorkDouble actualDualStep_; + /// smallestInfeasibility + CoinWorkDouble smallestInfeasibility_; + /// historyInfeasibility. +#define LENGTH_HISTORY 5 + CoinWorkDouble historyInfeasibility_[LENGTH_HISTORY]; + /// complementarityGap. + CoinWorkDouble complementarityGap_; + /// baseObjectiveNorm + CoinWorkDouble baseObjectiveNorm_; + /// worstDirectionAccuracy + CoinWorkDouble worstDirectionAccuracy_; + /// maximumRHSChange + CoinWorkDouble maximumRHSChange_; + /// errorRegion. i.e. Ax + CoinWorkDouble * errorRegion_; + /// rhsFixRegion. + CoinWorkDouble * rhsFixRegion_; + /// upperSlack + CoinWorkDouble * upperSlack_; + /// lowerSlack + CoinWorkDouble * lowerSlack_; + /// diagonal + CoinWorkDouble * diagonal_; + /// solution + CoinWorkDouble * solution_; + /// work array + CoinWorkDouble * workArray_; + /// delta X + CoinWorkDouble * deltaX_; + /// delta Y + CoinWorkDouble * deltaY_; + /// deltaZ. + CoinWorkDouble * deltaZ_; + /// deltaW. + CoinWorkDouble * deltaW_; + /// deltaS. + CoinWorkDouble * deltaSU_; + CoinWorkDouble * deltaSL_; + /// Primal regularization array + CoinWorkDouble * primalR_; + /// Dual regularization array + CoinWorkDouble * dualR_; + /// rhs B + CoinWorkDouble * rhsB_; + /// rhsU. + CoinWorkDouble * rhsU_; + /// rhsL. + CoinWorkDouble * rhsL_; + /// rhsZ. + CoinWorkDouble * rhsZ_; + /// rhsW. + CoinWorkDouble * rhsW_; + /// rhs C + CoinWorkDouble * rhsC_; + /// zVec + CoinWorkDouble * zVec_; + /// wVec + CoinWorkDouble * wVec_; + /// cholesky. + ClpCholeskyBase * cholesky_; + /// numberComplementarityPairs i.e. ones with lower and/or upper bounds (not fixed) + int numberComplementarityPairs_; + /// numberComplementarityItems_ i.e. number of active bounds + int numberComplementarityItems_; + /// Maximum iterations + int maximumBarrierIterations_; + /// gonePrimalFeasible. + bool gonePrimalFeasible_; + /// goneDualFeasible. + bool goneDualFeasible_; + /// Which algorithm being used + int algorithm_; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpInterior class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpLinearObjective.hpp b/thirdparty/linux/include/coin/coin/ClpLinearObjective.hpp new file mode 100644 index 0000000..ff035d4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpLinearObjective.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpLinearObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpLinearObjective_H +#define ClpLinearObjective_H + +#include "ClpObjective.hpp" + +//############################################################################# + +/** Linear Objective Class + +*/ + +class ClpLinearObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns objective coefficients. + + Offset is always set to 0.0. All other parameters unused. + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + /// Resize objective + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpLinearObjective(); + + /// Constructor from objective + ClpLinearObjective(const double * objective, int numberColumns); + + /// Copy constructor + ClpLinearObjective(const ClpLinearObjective &); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpLinearObjective (const ClpLinearObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpLinearObjective & operator=(const ClpLinearObjective& rhs); + + /// Destructor + virtual ~ClpLinearObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Objective + double * objective_; + /// number of columns + int numberColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpMatrixBase.hpp b/thirdparty/linux/include/coin/coin/ClpMatrixBase.hpp new file mode 100644 index 0000000..06dc523 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpMatrixBase.hpp @@ -0,0 +1,524 @@ +/* $Id: ClpMatrixBase.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMatrixBase_H +#define ClpMatrixBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" + +#include "CoinPackedMatrix.hpp" +class CoinIndexedVector; +class ClpSimplex; +class ClpModel; +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +/** Abstract base class for Clp Matrices + +Since this class is abstract, no object of this type can be created. + +If a derived class provides all methods then all Clp algorithms +should work. Some can be very inefficient e.g. getElements etc is +only used for tightening bounds for dual and the copies are +deleted. Many methods can just be dummy i.e. abort(); if not +all features are being used. So if column generation was being done +then it makes no sense to do steepest edge so there would be +no point providing subsetTransposeTimes. +*/ + +class ClpMatrixBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const = 0; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const = 0; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const = 0; + /** Number of columns. */ + virtual int getNumCols() const = 0; + /** Number of rows. */ + virtual int getNumRows() const = 0; + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const = 0; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const = 0; + + virtual const CoinBigIndex * getVectorStarts() const = 0; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const = 0 ; + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const ; + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel) = 0; + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel) = 0; +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false); + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + + /** Returns a new matrix in reverse order without gaps + Is allowed to return NULL if doesn't want to have row copy */ + virtual ClpMatrixBase * reverseOrderedCopy() const { + return NULL; + } + + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic) = 0; + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element) = 0; + /** Creates scales for column copy (rowCopy in model may be modified) + default does not allow scaling + returns non-zero if no scaling done */ + virtual int scale(ClpModel * , const ClpSimplex * = NULL) const { + return 1; + } + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * ) const { } + /// Returns true if can create row copy + virtual bool canGetRowCopy() const { + return true; + } + /** Realy really scales column copy + Only called if scales already exist. + Up to user to delete */ + inline virtual ClpMatrixBase * scaledColumnCopy(ClpModel * ) const { + return this->clone(); + } + + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * , + double , double , + int = 15) { + return true; + } + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + If returns zeros then can't tell anything */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const = 0; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const = 0; + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * ) { + return 0; + } + + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + Default returns vector of ones + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const = 0; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const = 0; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const = 0; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added. + + This will normally be a no-op - it is in for GUB but may get extended to + general non-overlapping and embedded networks. + + mode 0 - extend + mode 1 - delete etc + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + utility primal function for dealing with dynamic constraints + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + utility dual function for dealing with dynamic constraints + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + general utility function for dealing with dynamic constraints + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs and bounds + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Creates a variable. This is called after partial pricing and may modify matrix. + May update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** Just for debug if odd type matrix. + Returns number of primal infeasibilities. */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const ; + /// Returns reduced cost of a variable + double reducedCost(ClpSimplex * model, int sequence) const; + /// Correct sequence in and out to give true value (if both -1 maybe do whole matrix) + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return <code>y + A * x * scalar</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale, + double * COIN_RESTRICT spare = NULL) const; +#if COIN_LONG_WORK + // For long double versions (aborts if not supported) + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; +#endif + /** Return <code>x * scalar *A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + This is only needed for primal steepest edge. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * , + const CoinIndexedVector * ) const { + return false; + } + /// Updates two arrays for steepest and does devex weights (need not be coded) + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights (need not be coded) + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /** Return <code>x *A</code> in <code>z</code> but + just for number indices in y. + Default cheats with fake CoinIndexedVector and + then calls subsetTransposeTimes */ + virtual void listTransposeTimes(const ClpSimplex * model, + double * x, + int * y, + int number, + double * z) const; + //@} + //@{ + ///@name Other + /// Clone + virtual ClpMatrixBase * clone() const = 0; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const; + /// Gets rid of any mutable by products + virtual void backToBasics() {} + /** Returns type. + The types which code may need to know about are: + 1 - ClpPackedMatrix + 11 - ClpNetworkMatrix + 12 - ClpPlusMinusOneMatrix + */ + inline int type() const { + return type_; + } + /// Sets type + void setType(int newtype) { + type_ = newtype; + } + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /// If rhsOffset used this is iteration last refreshed + inline int lastRefresh() const { + return lastRefresh_; + } + /// If rhsOffset used this is refresh frequency (0==off) + inline int refreshFrequency() const { + return refreshFrequency_; + } + inline void setRefreshFrequency(int value) { + refreshFrequency_ = value; + } + /// whether to skip dual checks most of time + inline bool skipDualCheck() const { + return skipDualCheck_; + } + inline void setSkipDualCheck(bool yes) { + skipDualCheck_ = yes; + } + /** Partial pricing tuning parameter - minimum number of "objects" to scan. + e.g. number of Gub sets but could be number of variables */ + inline int minimumObjectsScan() const { + return minimumObjectsScan_; + } + inline void setMinimumObjectsScan(int value) { + minimumObjectsScan_ = value; + } + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + inline int minimumGoodReducedCosts() const { + return minimumGoodReducedCosts_; + } + inline void setMinimumGoodReducedCosts(int value) { + minimumGoodReducedCosts_ = value; + } + /// Current start of search space in matrix (as fraction) + inline double startFraction() const { + return startFraction_; + } + inline void setStartFraction(double value) { + startFraction_ = value; + } + /// Current end of search space in matrix (as fraction) + inline double endFraction() const { + return endFraction_; + } + inline void setEndFraction(double value) { + endFraction_ = value; + } + /// Current best reduced cost + inline double savedBestDj() const { + return savedBestDj_; + } + inline void setSavedBestDj(double value) { + savedBestDj_ = value; + } + /// Initial number of negative reduced costs wanted + inline int originalWanted() const { + return originalWanted_; + } + inline void setOriginalWanted(int value) { + originalWanted_ = value; + } + /// Current number of negative reduced costs which we still need + inline int currentWanted() const { + return currentWanted_; + } + inline void setCurrentWanted(int value) { + currentWanted_ = value; + } + /// Current best sequence + inline int savedBestSequence() const { + return savedBestSequence_; + } + inline void setSavedBestSequence(int value) { + savedBestSequence_ = value; + } + //@} + + +protected: + + /**@name Constructors, destructor<br> + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpMatrixBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpMatrixBase(); +protected: + // Copy + ClpMatrixBase(const ClpMatrixBase&); + // Assignment + ClpMatrixBase& operator=(const ClpMatrixBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** Effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive */ + double * rhsOffset_; + /// Current start of search space in matrix (as fraction) + double startFraction_; + /// Current end of search space in matrix (as fraction) + double endFraction_; + /// Best reduced cost so far + double savedBestDj_; + /// Initial number of negative reduced costs wanted + int originalWanted_; + /// Current number of negative reduced costs which we still need + int currentWanted_; + /// Saved best sequence in pricing + int savedBestSequence_; + /// type (may be useful) + int type_; + /// If rhsOffset used this is iteration last refreshed + int lastRefresh_; + /// If rhsOffset used this is refresh frequency (0==off) + int refreshFrequency_; + /// Partial pricing tuning parameter - minimum number of "objects" to scan + int minimumObjectsScan_; + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + int minimumGoodReducedCosts_; + /// True sequence in (i.e. from larger problem) + int trueSequenceIn_; + /// True sequence out (i.e. from larger problem) + int trueSequenceOut_; + /// whether to skip dual checks most of time + bool skipDualCheck_; + //@} +}; +// bias for free variables +#define FREE_BIAS 1.0e1 +// Acceptance criteria for free variables +#define FREE_ACCEPT 1.0e2 + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpMessage.hpp b/thirdparty/linux/include/coin/coin/ClpMessage.hpp new file mode 100644 index 0000000..5eb3653 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpMessage.hpp @@ -0,0 +1,131 @@ +/* $Id: ClpMessage.hpp 1926 2013-03-26 15:23:38Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMessage_H +#define ClpMessage_H + + +#include "CoinPragma.hpp" +#include <cstring> + +// This deals with Clp messages (as against Osi messages etc) + +#include "CoinMessageHandler.hpp" +enum CLP_Message { + CLP_SIMPLEX_FINISHED, + CLP_SIMPLEX_INFEASIBLE, + CLP_SIMPLEX_UNBOUNDED, + CLP_SIMPLEX_STOPPED, + CLP_SIMPLEX_ERROR, + CLP_SIMPLEX_INTERRUPT, + CLP_SIMPLEX_STATUS, + CLP_DUAL_BOUNDS, + CLP_SIMPLEX_ACCURACY, + CLP_SIMPLEX_BADFACTOR, + CLP_SIMPLEX_BOUNDTIGHTEN, + CLP_SIMPLEX_INFEASIBILITIES, + CLP_SIMPLEX_FLAG, + CLP_SIMPLEX_GIVINGUP, + CLP_DUAL_CHECKB, + CLP_DUAL_ORIGINAL, + CLP_SIMPLEX_PERTURB, + CLP_PRIMAL_ORIGINAL, + CLP_PRIMAL_WEIGHT, + CLP_PRIMAL_OPTIMAL, + CLP_SINGULARITIES, + CLP_MODIFIEDBOUNDS, + CLP_RIMSTATISTICS1, + CLP_RIMSTATISTICS2, + CLP_RIMSTATISTICS3, + CLP_POSSIBLELOOP, + CLP_SMALLELEMENTS, + CLP_DUPLICATEELEMENTS, + CLP_SIMPLEX_HOUSE1, + CLP_SIMPLEX_HOUSE2, + CLP_SIMPLEX_NONLINEAR, + CLP_SIMPLEX_FREEIN, + CLP_SIMPLEX_PIVOTROW, + CLP_DUAL_CHECK, + CLP_PRIMAL_DJ, + CLP_PACKEDSCALE_INITIAL, + CLP_PACKEDSCALE_WHILE, + CLP_PACKEDSCALE_FINAL, + CLP_PACKEDSCALE_FORGET, + CLP_INITIALIZE_STEEP, + CLP_UNABLE_OPEN, + CLP_BAD_BOUNDS, + CLP_BAD_MATRIX, + CLP_LOOP, + CLP_IMPORT_RESULT, + CLP_IMPORT_ERRORS, + CLP_EMPTY_PROBLEM, + CLP_CRASH, + CLP_END_VALUES_PASS, + CLP_QUADRATIC_BOTH, + CLP_QUADRATIC_PRIMAL_DETAILS, + CLP_IDIOT_ITERATION, + CLP_INFEASIBLE, + CLP_MATRIX_CHANGE, + CLP_TIMING, + CLP_INTERVAL_TIMING, + CLP_SPRINT, + CLP_BARRIER_ITERATION, + CLP_BARRIER_OBJECTIVE_GAP, + CLP_BARRIER_GONE_INFEASIBLE, + CLP_BARRIER_CLOSE_TO_OPTIMAL, + CLP_BARRIER_COMPLEMENTARITY, + CLP_BARRIER_EXIT2, + CLP_BARRIER_STOPPING, + CLP_BARRIER_EXIT, + CLP_BARRIER_SCALING, + CLP_BARRIER_MU, + CLP_BARRIER_INFO, + CLP_BARRIER_END, + CLP_BARRIER_ACCURACY, + CLP_BARRIER_SAFE, + CLP_BARRIER_NEGATIVE_GAPS, + CLP_BARRIER_REDUCING, + CLP_BARRIER_DIAGONAL, + CLP_BARRIER_SLACKS, + CLP_BARRIER_DUALINF, + CLP_BARRIER_KILLED, + CLP_BARRIER_ABS_DROPPED, + CLP_BARRIER_ABS_ERROR, + CLP_BARRIER_FEASIBLE, + CLP_BARRIER_STEP, + CLP_BARRIER_KKT, + CLP_RIM_SCALE, + CLP_SLP_ITER, + CLP_COMPLICATED_MODEL, + CLP_BAD_STRING_VALUES, + CLP_CRUNCH_STATS, + CLP_PARAMETRICS_STATS, + CLP_PARAMETRICS_STATS2, +#ifndef NO_FATHOM_PRINT + CLP_FATHOM_STATUS, + CLP_FATHOM_SOLUTION, + CLP_FATHOM_FINISH, +#endif + CLP_GENERAL, + CLP_GENERAL2, + CLP_GENERAL_WARNING, + CLP_DUMMY_END +}; + +/** This deals with Clp messages (as against Osi messages etc) + */ +class ClpMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + ClpMessage(Language language = us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpModel.hpp b/thirdparty/linux/include/coin/coin/ClpModel.hpp new file mode 100644 index 0000000..4a22539 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpModel.hpp @@ -0,0 +1,1307 @@ +/* $Id: ClpModel.hpp 2074 2014-12-10 09:43:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpModel_H +#define ClpModel_H + +#include "ClpConfig.h" + +#include <iostream> +#include <cassert> +#include <cmath> +#include <vector> +#include <string> +//#ifndef COIN_USE_CLP +//#define COIN_USE_CLP +//#endif +#include "ClpPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" +#include "ClpParameters.hpp" +#include "ClpObjective.hpp" +class ClpEventHandler; +/** This is the base class for Linear and quadratic Models + This knows nothing about the algorithm, but it seems to + have a reasonable amount of information + + I would welcome suggestions for what should be in this and + how it relates to OsiSolverInterface. Some methods look + very similar. + +*/ +class CoinBuild; +class CoinModel; +class ClpModel { + +public: + + /**@name Constructors and destructor + Note - copy methods copy ALL data so can chew up memory + until other copy is freed + */ + //@{ + /// Default constructor + ClpModel (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 auto-but-as-initialSolve-in-bab + */ + ClpModel(const ClpModel & rhs, int scalingMode = -1); + /// Assignment operator. This copies the data + ClpModel & operator=(const ClpModel & rhs); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpModel (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Destructor + ~ClpModel ( ); + //@} + + /**@name Load model - loads some stuff and initializes others */ + //@{ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + + modelObject not const as may be changed as part of process + If tryPlusMinusOne then will try adding as +-1 matrix + */ + int loadProblem ( CoinModel & modelObject, bool tryPlusMinusOne = false); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + /// This just loads up a row objective + void setRowObjective(const double * rowObjective); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Copy in integer informations + void copyInIntegerInformation(const char * information); + /// Drop integer informations + void deleteIntegerInformation(); + /** Set the index-th variable to be a continuous variable */ + void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + void setInteger(int index); + /** Return true if the index-th variable is an integer variable */ + bool isInteger(int index) const; + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + /// Deletes rows + void deleteRows(int number, const int * which); + /// Add one row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower = -COIN_DBL_MAX, + double rowUpper = COIN_DBL_MAX); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * columns, + const double * elements); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * rowLengths, + const int * columns, + const double * elements); +#ifndef CLP_NO_VECTOR + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinPackedVectorBase * const * rows); +#endif + /** Add rows from a build object. + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addRows(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add rows from a model object. returns + -1 if object in bad state (i.e. has column information) + otherwise number of errors. + + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addRows(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + + /// Deletes columns + void deleteColumns(int number, const int * which); + /// Deletes rows AND columns (keeps old sizes) + void deleteRowsAndColumns(int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /// Add one column + void addColumn(int numberInColumn, + const int * rows, + const double * elements, + double columnLower = 0.0, + double columnUpper = COIN_DBL_MAX, + double objective = 0.0); + /// Add columns + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * rows, + const double * elements); + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * columnLengths, + const int * rows, + const double * elements); +#ifndef CLP_NO_VECTOR + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinPackedVectorBase * const * columns); +#endif + /** Add columns from a build object + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addColumns(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addColumns(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /// Modify one element of a matrix + inline void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Change row lower bounds */ + void chgRowLower(const double * rowLower); + /** Change row upper bounds */ + void chgRowUpper(const double * rowUpper); + /** Change column lower bounds */ + void chgColumnLower(const double * columnLower); + /** Change column upper bounds */ + void chgColumnUpper(const double * columnUpper); + /** Change objective coefficients */ + void chgObjCoefficients(const double * objIn); + /** Borrow model. This is so we don't have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm */ + void borrowModel(ClpModel & otherModel); + /** Return model - nulls all arrays so can be deleted safely + also updates any scalars */ + void returnModel(ClpModel & otherModel); + + /// Create empty ClpPackedMatrix + void createEmptyMatrix(); + /** Really clean up matrix (if ClpPackedMatrix). + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated or -1 if not ClpPackedMatrix + */ + int cleanMatrix(double threshold = 1.0e-20); + /// Copy contents - resizing if necessary - otherwise re-use memory + void copy(const ClpMatrixBase * from, ClpMatrixBase * & to); +#ifndef CLP_NO_STD + /// Drops names - makes lengthnames 0 and names empty + void dropNames(); + /// Copies in names + void copyNames(const std::vector<std::string> & rowNames, + const std::vector<std::string> & columnNames); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const std::vector<std::string> & rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const char * const * rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const char * const * columnNames, int first, int last); + /// Set name of row + void setRowName(int rowIndex, std::string & name) ; + /// Set name of col + void setColumnName(int colIndex, std::string & name) ; +#endif + /** Find a network subset. + rotate array should be numberRows. On output + -1 not in network + 0 in network as is + 1 in network with signs swapped + Returns number of network rows + */ + int findNetwork(char * rotate, double fractionNeeded = 0.75); + /** This creates a coinModel object + */ + CoinModel * createCoinModel() const; + + /** Write the problem in MPS format to the specified file. + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex + </ul> + + Returns non-zero on I/O error + */ + int writeMps(const char *filename, + int formatType = 0, int numberAcross = 2, + double objSense = 0.0) const ; + //@} + /**@name gets and sets */ + //@{ + /// Number of rows + inline int numberRows() const { + return numberRows_; + } + inline int getNumRows() const { + return numberRows_; + } + /// Number of columns + inline int getNumCols() const { + return numberColumns_; + } + inline int numberColumns() const { + return numberColumns_; + } + /// Primal tolerance to use + inline double primalTolerance() const { + return dblParam_[ClpPrimalTolerance]; + } + void setPrimalTolerance( double value) ; + /// Dual tolerance to use + inline double dualTolerance() const { + return dblParam_[ClpDualTolerance]; + } + void setDualTolerance( double value) ; + /// Primal objective limit + inline double primalObjectiveLimit() const { + return dblParam_[ClpPrimalObjectiveLimit]; + } + void setPrimalObjectiveLimit(double value); + /// Dual objective limit + inline double dualObjectiveLimit() const { + return dblParam_[ClpDualObjectiveLimit]; + } + void setDualObjectiveLimit(double value); + /// Objective offset + inline double objectiveOffset() const { + return dblParam_[ClpObjOffset]; + } + void setObjectiveOffset(double value); + /// Presolve tolerance to use + inline double presolveTolerance() const { + return dblParam_[ClpPresolveTolerance]; + } +#ifndef CLP_NO_STD + inline const std::string & problemName() const { + return strParam_[ClpProbName]; + } +#endif + /// Number of iterations + inline int numberIterations() const { + return numberIterations_; + } + inline int getIterationCount() const { + return numberIterations_; + } + inline void setNumberIterations(int numberIterationsNew) { + numberIterations_ = numberIterationsNew; + } + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + inline int solveType() const { + return solveType_; + } + inline void setSolveType(int type) { + solveType_ = type; + } + /// Maximum number of iterations + inline int maximumIterations() const { + return intParam_[ClpMaxNumIteration]; + } + void setMaximumIterations(int value); + /// Maximum time in seconds (from when set called) + inline double maximumSeconds() const { + return dblParam_[ClpMaxSeconds]; + } + void setMaximumSeconds(double value); + void setMaximumWallSeconds(double value); + /// Returns true if hit maximum iterations (or time) + bool hitMaximumIterations() const; + /** Status of problem: + -1 - unknown e.g. before solve or if postSolve says not optimal + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations or time + 4 - stopped due to errors + 5 - stopped by event handler (virtual int ClpEventHandler::event()) + */ + inline int status() const { + return problemStatus_; + } + inline int problemStatus() const { + return problemStatus_; + } + /// Set problem status + inline void setProblemStatus(int problemStatusNew) { + problemStatus_ = problemStatusNew; + } + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached OR (probably primal + infeasible but can't prove it - main status was 4) + 2 - scaled problem optimal - unscaled problem has primal infeasibilities + 3 - scaled problem optimal - unscaled problem has dual infeasibilities + 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities + 5 - giving up in primal with flagged variables + 6 - failed due to empty problem check + 7 - postSolve says not optimal + 8 - failed due to bad element check + 9 - status was 3 and stopped on time + 10 - status was 3 but stopped as primal feasible + 100 up - translation of enum from ClpEventHandler + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int newstatus) { + secondaryStatus_ = newstatus; + } + /// Are there a numerical difficulties? + inline bool isAbandoned() const { + return problemStatus_ == 4; + } + /// Is optimality proven? + inline bool isProvenOptimal() const { + return problemStatus_ == 0; + } + /// Is primal infeasiblity proven? + inline bool isProvenPrimalInfeasible() const { + return problemStatus_ == 1; + } + /// Is dual infeasiblity proven? + inline bool isProvenDualInfeasible() const { + return problemStatus_ == 2; + } + /// Is the given primal objective limit reached? + bool isPrimalObjectiveLimitReached() const ; + /// Is the given dual objective limit reached? + bool isDualObjectiveLimitReached() const ; + /// Iteration limit reached? + inline bool isIterationLimitReached() const { + return problemStatus_ == 3; + } + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + inline double getObjSense() const { + return optimizationDirection_; + } + void setOptimizationDirection(double value); + /// Primal row solution + inline double * primalRowSolution() const { + return rowActivity_; + } + inline const double * getRowActivity() const { + return rowActivity_; + } + /// Primal column solution + inline double * primalColumnSolution() const { + return columnActivity_; + } + inline const double * getColSolution() const { + return columnActivity_; + } + inline void setColSolution(const double * input) { + memcpy(columnActivity_, input, numberColumns_ * sizeof(double)); + } + /// Dual row solution + inline double * dualRowSolution() const { + return dual_; + } + inline const double * getRowPrice() const { + return dual_; + } + /// Reduced costs + inline double * dualColumnSolution() const { + return reducedCost_; + } + inline const double * getReducedCost() const { + return reducedCost_; + } + /// Row lower + inline double* rowLower() const { + return rowLower_; + } + inline const double* getRowLower() const { + return rowLower_; + } + /// Row upper + inline double* rowUpper() const { + return rowUpper_; + } + inline const double* getRowUpper() const { + return rowUpper_; + } + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double lower, double upper ) { + setColumnBounds(elementIndex, lower, upper); + } + + /** Set the bounds on a number of columns simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + //@} + /// Scaling + inline const double * rowScale() const { + return rowScale_; + } + inline const double * columnScale() const { + return columnScale_; + } + inline const double * inverseRowScale() const { + return inverseRowScale_; + } + inline const double * inverseColumnScale() const { + return inverseColumnScale_; + } + inline double * mutableRowScale() const { + return rowScale_; + } + inline double * mutableColumnScale() const { + return columnScale_; + } + inline double * mutableInverseRowScale() const { + return inverseRowScale_; + } + inline double * mutableInverseColumnScale() const { + return inverseColumnScale_; + } + inline double * swapRowScale(double * newScale) { + double * oldScale = rowScale_; + rowScale_ = newScale; + return oldScale; + } + void setRowScale(double * scale) ; + void setColumnScale(double * scale); + /// Scaling of objective + inline double objectiveScale() const { + return objectiveScale_; + } + inline void setObjectiveScale(double value) { + objectiveScale_ = value; + } + /// Scaling of rhs and bounds + inline double rhsScale() const { + return rhsScale_; + } + inline void setRhsScale(double value) { + rhsScale_ = value; + } + /// Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 auto-but-as-initialSolve-in-bab + void scaling(int mode = 1); + /** If we constructed a "really" scaled model then this reverses the operation. + Quantities may not be exactly as they were before due to rounding errors */ + void unscale(); + /// Gets scalingFlag + inline int scalingFlag() const { + return scalingFlag_; + } + /// Objective + inline double * objective() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + inline double * objective(const double * solution, double & offset, bool refresh = true) const { + offset = 0.0; + if (objective_) { + return objective_->gradient(NULL, solution, offset, refresh); + } else { + return NULL; + } + } + inline const double * getObjCoefficients() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + /// Row Objective + inline double * rowObjective() const { + return rowObjective_; + } + inline const double * getRowObjCoefficients() const { + return rowObjective_; + } + /// Column Lower + inline double * columnLower() const { + return columnLower_; + } + inline const double * getColLower() const { + return columnLower_; + } + /// Column Upper + inline double * columnUpper() const { + return columnUpper_; + } + inline const double * getColUpper() const { + return columnUpper_; + } + /// Matrix (if not ClpPackedmatrix be careful about memory leak + inline CoinPackedMatrix * matrix() const { + if ( matrix_ == NULL ) return NULL; + else return matrix_->getPackedMatrix(); + } + /// Number of elements in matrix + inline int getNumElements() const { + return matrix_->getNumElements(); + } + /** Small element value - elements less than this set to zero, + default is 1.0e-20 */ + inline double getSmallElementValue() const { + return smallElement_; + } + inline void setSmallElementValue(double value) { + smallElement_ = value; + } + /// Row Matrix + inline ClpMatrixBase * rowCopy() const { + return rowCopy_; + } + /// Set new row matrix + void setNewRowCopy(ClpMatrixBase * newCopy); + /// Clp Matrix + inline ClpMatrixBase * clpMatrix() const { + return matrix_; + } + /// Scaled ClpPackedMatrix + inline ClpPackedMatrix * clpScaledMatrix() const { + return scaledMatrix_; + } + /// Sets pointer to scaled ClpPackedMatrix + inline void setClpScaledMatrix(ClpPackedMatrix * scaledMatrix) { + delete scaledMatrix_; + scaledMatrix_ = scaledMatrix; + } + /// Swaps pointer to scaled ClpPackedMatrix + inline ClpPackedMatrix * swapScaledMatrix(ClpPackedMatrix * scaledMatrix) { + ClpPackedMatrix * oldMatrix = scaledMatrix_; + scaledMatrix_ = scaledMatrix; + return oldMatrix; + } + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) + So up to user to delete current. This was used where + matrices were being rotated. ClpModel takes ownership. + */ + void replaceMatrix(ClpMatrixBase * matrix, bool deleteCurrent = false); + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) So up to user to delete current. This was used where + matrices were being rotated. This version changes CoinPackedMatrix + to ClpPackedMatrix. ClpModel takes ownership. + */ + inline void replaceMatrix(CoinPackedMatrix * newmatrix, + bool deleteCurrent = false) { + replaceMatrix(new ClpPackedMatrix(newmatrix), deleteCurrent); + } + /// Objective value + inline double objectiveValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + inline void setObjectiveValue(double value) { + objectiveValue_ = (value + dblParam_[ClpObjOffset]) / optimizationDirection_; + } + inline double getObjValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + /// Integer information + inline char * integerInformation() const { + return integerType_; + } + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + double * unboundedRay() const; + /// For advanced users - no need to delete - sign not changed + inline double * ray() const + { return ray_;} + /// just test if infeasibility or unbounded Ray exists + inline bool rayExists() const { + return (ray_!=NULL); + } + /// just delete ray if exists + inline void deleteRay() { + delete [] ray_; + ray_=NULL; + } + /// Access internal ray storage. Users should call infeasibilityRay() or unboundedRay() instead. + inline const double * internalRay() const { + return ray_; + } + /// See if status (i.e. basis) array exists (partly for OsiClp) + inline bool statusExists() const { + return (status_ != NULL); + } + /// Return address of status (i.e. basis) array (char[numberRows+numberColumns]) + inline unsigned char * statusArray() const { + return status_; + } + /** Return copy of status (i.e. basis) array (char[numberRows+numberColumns]), + use delete [] */ + unsigned char * statusCopy() const; + /// Copy in status (basis) vector + void copyinStatus(const unsigned char * statusArray); + + /// User pointer for whatever reason + inline void setUserPointer (void * pointer) { + userPointer_ = pointer; + } + inline void * getUserPointer () const { + return userPointer_; + } + /// Trusted user pointer + inline void setTrustedUserPointer (ClpTrustedData * pointer) { + trustedUserPointer_ = pointer; + } + inline ClpTrustedData * getTrustedUserPointer () const { + return trustedUserPointer_; + } + /// What has changed in model (only for masochistic users) + inline int whatsChanged() const { + return whatsChanged_; + } + inline void setWhatsChanged(int value) { + whatsChanged_ = value; + } + /// Number of threads (not really being used) + inline int numberThreads() const { + return numberThreads_; + } + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + //@} + /**@name Message handling */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Pass in Message handler (not deleted at end) and return current + CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler, + bool & oldDefault); + /// back to previous message handler + void popMessageHandler(CoinMessageHandler * oldHandler, bool oldDefault); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Overrides message handler with a default one + void setDefaultMessageHandler(); + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages messages() const { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return & messages_; + } + /// Return Coin messages + inline CoinMessages coinMessages() const { + return coinMessages_; + } + /// Return pointer to Coin messages + inline CoinMessages * coinMessagesPointer() { + return & coinMessages_; + } + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + inline void setLogLevel(int value) { + handler_->setLogLevel(value); + } + inline int logLevel() const { + return handler_->logLevel(); + } + /// Return true if default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Event handler + inline ClpEventHandler * eventHandler() const { + return eventHandler_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Thread specific random number generator + inline CoinThreadRandom & mutableRandomNumberGenerator() { + return randomNumberGenerator_; + } + /// Set seed for thread specific random number generator + inline void setRandomSeed(int value) { + randomNumberGenerator_.setSeed(value); + } + /// length of names (0 means no names0 + inline int lengthNames() const { + return lengthNames_; + } +#ifndef CLP_NO_STD + /// length of names (0 means no names0 + inline void setLengthNames(int value) { + lengthNames_ = value; + } + /// Row names + inline const std::vector<std::string> * rowNames() const { + return &rowNames_; + } + inline const std::string& rowName(int iRow) const { + return rowNames_[iRow]; + } + /// Return name or Rnnnnnnn + std::string getRowName(int iRow) const; + /// Column names + inline const std::vector<std::string> * columnNames() const { + return &columnNames_; + } + inline const std::string& columnName(int iColumn) const { + return columnNames_[iColumn]; + } + /// Return name or Cnnnnnnn + std::string getColumnName(int iColumn) const; +#endif + /// Objective methods + inline ClpObjective * objectiveAsObject() const { + return objective_; + } + void setObjective(ClpObjective * objective); + inline void setObjectivePointer(ClpObjective * newobjective) { + objective_ = newobjective; + } + /** Solve a problem with no elements - return status and + dual and primal infeasibilites */ + int emptyProblem(int * infeasNumber = NULL, double * infeasSum = NULL, bool printMessage = true); + + //@} + + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + These are covers so user need not worry about scaling + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return <code>y + A * x * scalar</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + void times(double scalar, + const double * x, double * y) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + void transposeTimes(double scalar, + const double * x, double * y) const ; + //@} + + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + ** once it has been decided where solver sits this may be redone + */ + //@{ + /// Set an integer parameter + bool setIntParam(ClpIntParam key, int value) ; + /// Set an double parameter + bool setDblParam(ClpDblParam key, double value) ; +#ifndef CLP_NO_STD + /// Set an string parameter + bool setStrParam(ClpStrParam key, const std::string & value); +#endif + // Get an integer parameter + inline bool getIntParam(ClpIntParam key, int& value) const { + if (key < ClpLastIntParam) { + value = intParam_[key]; + return true; + } else { + return false; + } + } + // Get an double parameter + inline bool getDblParam(ClpDblParam key, double& value) const { + if (key < ClpLastDblParam) { + value = dblParam_[key]; + return true; + } else { + return false; + } + } +#ifndef CLP_NO_STD + // Get a string parameter + inline bool getStrParam(ClpStrParam key, std::string& value) const { + if (key < ClpLastStrParam) { + value = strParam_[key]; + return true; + } else { + return false; + } + } +#endif + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + /** For advanced options + 1 - Don't keep changing infeasibility weight + 2 - Keep nonLinearCost round solves + 4 - Force outgoing variables to exact bound (primal) + 8 - Safe to use dense initial factorization + 16 -Just use basic variables for operation if column generation + 32 -Create ray even in BAB + 64 -Treat problem as feasible until last minute (i.e. minimize infeasibilities) + 128 - Switch off all matrix sanity checks + 256 - No row copy + 512 - If not in values pass, solution guaranteed, skip as much as possible + 1024 - In branch and bound + 2048 - Don't bother to re-factorize if < 20 iterations + 4096 - Skip some optimality checks + 8192 - Do Primal when cleaning up primal + 16384 - In fast dual (so we can switch off things) + 32768 - called from Osi + 65536 - keep arrays around as much as possible (also use maximumR/C) + 131072 - transposeTimes is -1.0 and can skip basic and fixed + 262144 - extra copy of scaled matrix + 524288 - Clp fast dual + 1048576 - don't need to finish dual (can return 3) + 2097152 - zero costs! + 4194304 - don't scale integer variables + 8388608 - Idiot when not really sure about it + NOTE - many applications can call Clp but there may be some short cuts + which are taken which are not guaranteed safe from all applications. + Vetted applications will have a bit set and the code may test this + At present I expect a few such applications - if too many I will + have to re-think. It is up to application owner to change the code + if she/he needs these short cuts. I will not debug unless in Coin + repository. See COIN_CLP_VETTED comments. + 0x01000000 is Cbc (and in branch and bound) + 0x02000000 is in a different branch and bound + */ + inline unsigned int specialOptions() const { + return specialOptions_; + } + void setSpecialOptions(unsigned int value); +#define COIN_CBC_USING_CLP 0x01000000 + inline bool inCbcBranchAndBound() const { + return (specialOptions_ & COIN_CBC_USING_CLP) != 0; + } + //@} + + /**@name private or protected methods */ + //@{ +protected: + /// Does most of deletion (0 = all, 1 = most) + void gutsOfDelete(int type); + /** Does most of copying + If trueCopy 0 then just points to arrays + If -1 leaves as much as possible */ + void gutsOfCopy(const ClpModel & rhs, int trueCopy = 1); + /// gets lower and upper bounds on rows + void getRowBound(int iRow, double& lower, double& upper) const; + /// puts in format I like - 4 array matrix - may make row copy + void gutsOfLoadModel ( int numberRows, int numberColumns, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Does much of scaling + void gutsOfScaling(); + /// Objective value - always minimize + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// If we are using maximumRows_ and Columns_ + inline bool permanentArrays() const { + return (specialOptions_ & 65536) != 0; + } + /// Start using maximumRows_ and Columns_ + void startPermanentArrays(); + /// Stop using maximumRows_ and Columns_ + void stopPermanentArrays(); + /// Create row names as char ** + const char * const * rowNamesAsChar() const; + /// Create column names as char ** + const char * const * columnNamesAsChar() const; + /// Delete char * version of names + void deleteNamesAsChar(const char * const * names, int number) const; + /// On stopped - sets secondary status + void onStopped(); + //@} + + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Array of double parameters + double dblParam_[ClpLastDblParam]; + /// Objective value + double objectiveValue_; + /// Small element value + double smallElement_; + /// Scaling of objective + double objectiveScale_; + /// Scaling of rhs and bounds + double rhsScale_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Row activities + double * rowActivity_; + /// Column activities + double * columnActivity_; + /// Duals + double * dual_; + /// Reduced costs + double * reducedCost_; + /// Row lower + double* rowLower_; + /// Row upper + double* rowUpper_; + /// Objective + ClpObjective * objective_; + /// Row Objective (? sign) - may be NULL + double * rowObjective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Packed matrix + ClpMatrixBase * matrix_; + /// Row copy if wanted + ClpMatrixBase * rowCopy_; + /// Scaled packed matrix + ClpPackedMatrix * scaledMatrix_; + /// Infeasible/unbounded ray + double * ray_; + /// Row scale factors for matrix + double * rowScale_; + /// Column scale factors + double * columnScale_; + /// Inverse row scale factors for matrix (end of rowScale_) + double * inverseRowScale_; + /// Inverse column scale factors for matrix (end of columnScale_) + double * inverseColumnScale_; + /** Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic, + 5 geometric on rows */ + int scalingFlag_; + /** Status (i.e. basis) Region. I know that not all algorithms need a status + array, but it made sense for things like crossover and put + all permanent stuff in one place. No assumption is made + about what is in status array (although it might be good to reserve + bottom 3 bits (i.e. 0-7 numeric) for classic status). This + is number of columns + number of rows long (in that order). + */ + unsigned char * status_; + /// Integer information + char * integerType_; + /// User pointer for whatever reason + void * userPointer_; + /// Trusted user pointer e.g. for heuristics + ClpTrustedData * trustedUserPointer_; + /// Array of integer parameters + int intParam_[ClpLastIntParam]; + /// Number of iterations + int numberIterations_; + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + int solveType_; + /** Whats changed since last solve. This is a work in progress + It is designed so careful people can make go faster. + It is only used when startFinishOptions used in dual or primal. + Bit 1 - number of rows/columns has not changed (so work arrays valid) + 2 - matrix has not changed + 4 - if matrix has changed only by adding rows + 8 - if matrix has changed only by adding columns + 16 - row lbs not changed + 32 - row ubs not changed + 64 - column objective not changed + 128 - column lbs not changed + 256 - column ubs not changed + 512 - basis not changed (up to user to set this to 0) + top bits may be used internally + shift by 65336 is 3 all same, 1 all except col bounds + */ +#define ROW_COLUMN_COUNTS_SAME 1 +#define MATRIX_SAME 2 +#define MATRIX_JUST_ROWS_ADDED 4 +#define MATRIX_JUST_COLUMNS_ADDED 8 +#define ROW_LOWER_SAME 16 +#define ROW_UPPER_SAME 32 +#define OBJECTIVE_SAME 64 +#define COLUMN_LOWER_SAME 128 +#define COLUMN_UPPER_SAME 256 +#define BASIS_SAME 512 +#define ALL_SAME 65339 +#define ALL_SAME_EXCEPT_COLUMN_BOUNDS 65337 + unsigned int whatsChanged_; + /// Status of problem + int problemStatus_; + /// Secondary status of problem + int secondaryStatus_; + /// length of names (0 means no names) + int lengthNames_; + /// Number of threads (not very operational) + int numberThreads_; + /** For advanced options + See get and set for meaning + */ + unsigned int specialOptions_; + /// Message handler + CoinMessageHandler * handler_; + /// Flag to say if default handler (so delete) + bool defaultHandler_; + /// Thread specific random number generator + CoinThreadRandom randomNumberGenerator_; + /// Event handler + ClpEventHandler * eventHandler_; +#ifndef CLP_NO_STD + /// Row names + std::vector<std::string> rowNames_; + /// Column names + std::vector<std::string> columnNames_; +#endif + /// Messages + CoinMessages messages_; + /// Coin messages + CoinMessages coinMessages_; + /// Maximum number of columns in model + int maximumColumns_; + /// Maximum number of rows in model + int maximumRows_; + /// Maximum number of columns (internal arrays) in model + int maximumInternalColumns_; + /// Maximum number of rows (internal arrays) in model + int maximumInternalRows_; + /// Base packed matrix + CoinPackedMatrix baseMatrix_; + /// Base row copy + CoinPackedMatrix baseRowCopy_; + /// Saved row scale factors for matrix + double * savedRowScale_; + /// Saved column scale factors + double * savedColumnScale_; +#ifndef CLP_NO_STD + /// Array of string parameters + std::string strParam_[ClpLastStrParam]; +#endif + //@} +}; +/** This is a tiny class where data can be saved round calls. + */ +class ClpDataSave { + +public: + /**@name Constructors and destructor + */ + //@{ + /// Default constructor + ClpDataSave ( ); + + /// Copy constructor. + ClpDataSave(const ClpDataSave &); + /// Assignment operator. This copies the data + ClpDataSave & operator=(const ClpDataSave & rhs); + /// Destructor + ~ClpDataSave ( ); + + //@} + +////////////////// data ////////////////// +public: + + /**@name data - with same names as in other classes*/ + //@{ + double dualBound_; + double infeasibilityCost_; + double pivotTolerance_; + double zeroFactorizationTolerance_; + double zeroSimplexTolerance_; + double acceptablePivot_; + double objectiveScale_; + int sparseThreshold_; + int perturbation_; + int forceFactorization_; + int scalingFlag_; + unsigned int specialOptions_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpNetworkMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpNetworkMatrix.hpp new file mode 100644 index 0000000..ec650a4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpNetworkMatrix.hpp @@ -0,0 +1,229 @@ +/* $Id: ClpNetworkMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNetworkMatrix_H +#define ClpNetworkMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple network matrix as derived from ClpMatrixBase. + +If you want more sophisticated version then you could inherit from this. +Also you might want to allow networks with gain */ + +class ClpNetworkMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return 2 * numberColumns_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const ; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + /// Return true if really network, false if has slacks + inline bool trueNetwork() const { + return trueNetwork_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNetworkMatrix(); + /** Constructor from two arrays */ + ClpNetworkMatrix(int numberColumns, const int * head, + const int * tail); + /** Destructor */ + virtual ~ClpNetworkMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpNetworkMatrix(const ClpNetworkMatrix&); + /** The copy constructor from an CoinNetworkMatrix. */ + ClpNetworkMatrix(const CoinPackedMatrix&); + + ClpNetworkMatrix& operator=(const ClpNetworkMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpNetworkMatrix (const ClpNetworkMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// True if all entries have two elements + bool trueNetwork_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpNode.hpp b/thirdparty/linux/include/coin/coin/ClpNode.hpp new file mode 100644 index 0000000..671d62f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpNode.hpp @@ -0,0 +1,349 @@ +/* $Id: ClpNode.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNode_H +#define ClpNode_H + +#include "CoinPragma.hpp" + +// This implements all stuff for Clp fathom +/** This contains what is in a Clp "node" + + */ + +class ClpFactorization; +class ClpDualRowSteepest; +class ClpNodeStuff; +class ClpNode { + +public: + /**@name Useful methods */ + //@{ + /** Applies node to model + 0 - just tree bounds + 1 - tree bounds and basis etc + 2 - saved bounds and basis etc + */ + void applyNode(ClpSimplex * model, int doBoundsEtc ); + /// Choose a new variable + void chooseVariable(ClpSimplex * model, ClpNodeStuff * info); + /// Fix on reduced costs + int fixOnReducedCosts(ClpSimplex * model); + /// Create odd arrays + void createArrays(ClpSimplex * model); + /// Clean up as crunch is different model + void cleanUpForCrunch(); + //@} + + /**@name Gets and sets */ + //@{ + /// Objective value + inline double objectiveValue() const { + return objectiveValue_; + } + /// Set objective value + inline void setObjectiveValue(double value) { + objectiveValue_ = value; + } + /// Primal solution + inline const double * primalSolution() const { + return primalSolution_; + } + /// Dual solution + inline const double * dualSolution() const { + return dualSolution_; + } + /// Initial value of integer variable + inline double branchingValue() const { + return branchingValue_; + } + /// Sum infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Number infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Relative depth + inline int depth() const { + return depth_; + } + /// Estimated solution value + inline double estimatedSolution() const { + return estimatedSolution_; + } + /** Way for integer variable -1 down , +1 up */ + int way() const; + /// Return true if branch exhausted + bool fathomed() const; + /// Change state of variable i.e. go other way + void changeState(); + /// Sequence number of integer variable (-1 if none) + inline int sequence() const { + return sequence_; + } + /// If odd arrays exist + inline bool oddArraysExist() const { + return lower_ != NULL; + } + /// Status array + inline const unsigned char * statusArray() const { + return status_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNode(); + /// Constructor from model + ClpNode (ClpSimplex * model, const ClpNodeStuff * stuff, int depth); + /// Does work of constructor (partly so gdb will work) + void gutsOfConstructor(ClpSimplex * model, const ClpNodeStuff * stuff, + int arraysExist, int depth); + /** Destructor */ + virtual ~ClpNode(); + //@} + + /**@name Copy methods (at present illegal - will abort) */ + //@{ + /** The copy constructor. */ + ClpNode(const ClpNode&); + /// Operator = + ClpNode& operator=(const ClpNode&); + //@} + +protected: +// For state of branch + typedef struct { + unsigned int firstBranch: 1; // nonzero if first branch on variable is up + unsigned int branch: 2; // 0 means do first branch next, 1 second, 2 finished + unsigned int spare: 29; + } branchState; + /**@name Data */ + //@{ + /// Initial value of integer variable + double branchingValue_; + /// Value of objective + double objectiveValue_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Estimated solution value + double estimatedSolution_; + /// Factorization + ClpFactorization * factorization_; + /// Steepest edge weights + ClpDualRowSteepest * weights_; + /// Status vector + unsigned char * status_; + /// Primal solution + double * primalSolution_; + /// Dual solution + double * dualSolution_; + /// Integer lower bounds (only used in fathomMany) + int * lower_; + /// Integer upper bounds (only used in fathomMany) + int * upper_; + /// Pivot variables for factorization + int * pivotVariables_; + /// Variables fixed by reduced costs (at end of branch) 0x10000000 added if fixed to UB + int * fixed_; + /// State of branch + branchState branchState_; + /// Sequence number of integer variable (-1 if none) + int sequence_; + /// Number of infeasibilities + int numberInfeasibilities_; + /// Relative depth + int depth_; + /// Number fixed by reduced cost + int numberFixed_; + /// Flags - 1 duals scaled + int flags_; + /// Maximum number fixed by reduced cost + int maximumFixed_; + /// Maximum rows so far + int maximumRows_; + /// Maximum columns so far + int maximumColumns_; + /// Maximum Integers so far + int maximumIntegers_; + //@} +}; +class ClpNodeStuff { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNodeStuff(); + /** Destructor */ + virtual ~ClpNodeStuff(); + //@} + + /**@name Copy methods (only copies ints etc, nulls arrays) */ + //@{ + /** The copy constructor. */ + ClpNodeStuff(const ClpNodeStuff&); + /// Operator = + ClpNodeStuff& operator=(const ClpNodeStuff&); + /// Zaps stuff 1 - arrays, 2 ints, 3 both + void zap(int type); + //@} + + + /**@name Fill methods */ + //@{ + /** Fill with pseudocosts */ + void fillPseudoCosts(const double * down, const double * up, + const int * priority, + const int * numberDown, const int * numberUp, + const int * numberDownInfeasible, const int * numberUpInfeasible, + int number); + /// Update pseudo costs + void update(int way, int sequence, double change, bool feasible); + /// Return maximum number of nodes + int maximumNodes() const; + /// Return maximum space for nodes + int maximumSpace() const; + //@} + +public: + /**@name Data */ + //@{ + /// Integer tolerance + double integerTolerance_; + /// Integer increment + double integerIncrement_; + /// Small change in branch + double smallChange_; + /// Down pseudo costs + double * downPseudo_; + /// Up pseudo costs + double * upPseudo_; + /// Priority + int * priority_; + /// Number of times down + int * numberDown_; + /// Number of times up + int * numberUp_; + /// Number of times down infeasible + int * numberDownInfeasible_; + /// Number of times up infeasible + int * numberUpInfeasible_; + /// Copy of costs (local) + double * saveCosts_; + /// Array of ClpNodes + ClpNode ** nodeInfo_; + /// Large model if crunched + ClpSimplex * large_; + /// Which rows in large model + int * whichRow_; + /// Which columns in large model + int * whichColumn_; +#ifndef NO_FATHOM_PRINT + /// Cbc's message handler + CoinMessageHandler * handler_; +#endif + /// Number bounds in large model + int nBound_; + /// Save of specialOptions_ (local) + int saveOptions_; + /** Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + 32 - just create up to nDepth_+1 nodes + 65536 - set if activated + */ + int solverOptions_; + /// Maximum number of nodes to do + int maximumNodes_; + /// Number before trust from CbcModel + int numberBeforeTrust_; + /// State of search from CbcModel + int stateOfSearch_; + /// Number deep + int nDepth_; + /// Number nodes returned (-1 if fathom aborted) + int nNodes_; + /// Number of nodes explored + int numberNodesExplored_; + /// Number of iterations + int numberIterations_; + /// Type of presolve - 0 none, 1 crunch + int presolveType_; +#ifndef NO_FATHOM_PRINT + /// Depth passed in + int startingDepth_; + /// Node at which called + int nodeCalled_; +#endif + //@} +}; +class ClpHashValue { + +public: + /**@name Useful methods */ + //@{ + /// Return index or -1 if not found + int index(double value) const; + /// Add value to list and return index + int addValue(double value) ; + /// Number of different entries + inline int numberEntries() const { + return numberHash_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpHashValue(); + /** Useful constructor. */ + ClpHashValue(ClpSimplex * model); + /** Destructor */ + virtual ~ClpHashValue(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpHashValue(const ClpHashValue&); + /// = + ClpHashValue& operator=(const ClpHashValue&); + //@} +private: + /**@name private stuff */ + //@{ + /** returns hash */ + int hash(double value) const; + /// Resizes + void resize(bool increaseMax); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + // for hashing + typedef struct { + double value; + int index, next; + } CoinHashLink; + /// Hash table + mutable CoinHashLink *hash_; + /// Number of entries in hash table + int numberHash_; + /// Maximum number of entries in hash table i.e. size + int maxHash_; + /// Last used space + int lastUsed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpNonLinearCost.hpp b/thirdparty/linux/include/coin/coin/ClpNonLinearCost.hpp new file mode 100644 index 0000000..1007865 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpNonLinearCost.hpp @@ -0,0 +1,401 @@ +/* $Id: ClpNonLinearCost.hpp 1769 2011-07-26 09:31:51Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNonLinearCost_H +#define ClpNonLinearCost_H + + +#include "CoinPragma.hpp" + +class ClpSimplex; +class CoinIndexedVector; + +/** Trivial class to deal with non linear costs + + I don't make any explicit assumptions about convexity but I am + sure I do make implicit ones. + + One interesting idea for normal LP's will be to allow non-basic + variables to come into basis as infeasible i.e. if variable at + lower bound has very large positive reduced cost (when problem + is infeasible) could it reduce overall problem infeasibility more + by bringing it into basis below its lower bound. + + Another feature would be to automatically discover when problems + are convex piecewise linear and re-formulate to use non-linear. + I did some work on this many years ago on "grade" problems, but + while it improved primal interior point algorithms were much better + for that particular problem. +*/ +/* status has original status and current status + 0 - below lower so stored is upper + 1 - in range + 2 - above upper so stored is lower + 4 - (for current) - same as original +*/ +#define CLP_BELOW_LOWER 0 +#define CLP_FEASIBLE 1 +#define CLP_ABOVE_UPPER 2 +#define CLP_SAME 4 +inline int originalStatus(unsigned char status) +{ + return (status & 15); +} +inline int currentStatus(unsigned char status) +{ + return (status >> 4); +} +inline void setOriginalStatus(unsigned char & status, int value) +{ + status = static_cast<unsigned char>(status & ~15); + status = static_cast<unsigned char>(status | value); +} +inline void setCurrentStatus(unsigned char &status, int value) +{ + status = static_cast<unsigned char>(status & ~(15 << 4)); + status = static_cast<unsigned char>(status | (value << 4)); +} +inline void setInitialStatus(unsigned char &status) +{ + status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4)); +} +inline void setSameStatus(unsigned char &status) +{ + status = static_cast<unsigned char>(status & ~(15 << 4)); + status = static_cast<unsigned char>(status | (CLP_SAME << 4)); +} +// Use second version to get more speed +//#define FAST_CLPNON +#ifndef FAST_CLPNON +#define CLP_METHOD1 ((method_&1)!=0) +#define CLP_METHOD2 ((method_&2)!=0) +#else +#define CLP_METHOD1 (false) +#define CLP_METHOD2 (true) +#endif +class ClpNonLinearCost { + +public: + +public: + + /**@name Constructors, destructor */ + //@{ + /// Default constructor. + ClpNonLinearCost(); + /** Constructor from simplex. + This will just set up wasteful arrays for linear, but + later may do dual analysis and even finding duplicate columns . + */ + ClpNonLinearCost(ClpSimplex * model, int method = 1); + /** Constructor from simplex and list of non-linearities (columns only) + First lower of each column has to match real lower + Last lower has to be <= upper (if == then cost ignored) + This could obviously be changed to make more user friendly + */ + ClpNonLinearCost(ClpSimplex * model, const int * starts, + const double * lower, const double * cost); + /// Destructor + ~ClpNonLinearCost(); + // Copy + ClpNonLinearCost(const ClpNonLinearCost&); + // Assignment + ClpNonLinearCost& operator=(const ClpNonLinearCost&); + //@} + + + /**@name Actual work in primal */ + //@{ + /** Changes infeasible costs and computes number and cost of infeas + Puts all non-basic (non free) variables to bounds + and all free variables to zero if oldTolerance is non-zero + - but does not move those <= oldTolerance away*/ + void checkInfeasibilities(double oldTolerance = 0.0); + /** Changes infeasible costs for each variable + The indices are row indices and need converting to sequences + */ + void checkInfeasibilities(int numberInArray, const int * index); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + On input array is empty (but indices exist). On exit just + changed costs will be stored as normal CoinIndexedVector + */ + void checkChanged(int numberInArray, CoinIndexedVector * update); + /** Goes through one bound for each variable. + If multiplier*work[iRow]>0 goes down, otherwise up. + The indices are row indices and need converting to sequences + Temporary offsets may be set + Rhs entries are increased + */ + void goThru(int numberInArray, double multiplier, + const int * index, const double * work, + double * rhs); + /** Takes off last iteration (i.e. offsets closer to 0) + */ + void goBack(int numberInArray, const int * index, + double * rhs); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + At the end of this all temporary offsets are zero + */ + void goBackAll(const CoinIndexedVector * update); + /// Temporary zeroing of feasible costs + void zapCosts(); + /// Refreshes costs always makes row costs zero + void refreshCosts(const double * columnCosts); + /// Puts feasible bounds into lower and upper + void feasibleBounds(); + /// Refresh - assuming regions OK + void refresh(); + /** Sets bounds and cost for one variable + Returns change in cost + May need to be inline for speed */ + double setOne(int sequence, double solutionValue); + /** Sets bounds and infeasible cost and true cost for one variable + This is for gub and column generation etc */ + void setOne(int sequence, double solutionValue, double lowerValue, double upperValue, + double costValue = 0.0); + /** Sets bounds and cost for outgoing variable + may change value + Returns direction */ + int setOneOutgoing(int sequence, double &solutionValue); + /// Returns nearest bound + double nearest(int sequence, double solutionValue); + /** Returns change in cost - one down if alpha >0.0, up if <0.0 + Value is current - new + */ + inline double changeInCost(int sequence, double alpha) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = cost_[iRange] - cost_[iRange+1]; + } + if (CLP_METHOD2) { + returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_; + } + return returnValue; + } + inline double changeUpInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1)) + returnValue = cost_[iRange] - cost_[iRange+1]; + else + returnValue = -1.0e100; + } + if (CLP_METHOD2) { + returnValue = -infeasibilityWeight_; + } + return returnValue; + } + inline double changeDownInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange != start_[sequence] && !infeasible(iRange - 1)) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = 1.0e100; + } + if (CLP_METHOD2) { + returnValue = infeasibilityWeight_; + } + return returnValue; + } + /// This also updates next bound + inline double changeInCost(int sequence, double alpha, double &rhs) { + double returnValue = 0.0; +#ifdef NONLIN_DEBUG + double saveRhs = rhs; +#endif + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) { + assert(iRange - 1 >= start_[sequence]); + offset_[sequence]--; + rhs += lower_[iRange] - lower_[iRange-1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange-1]); + } else { + assert(iRange + 1 < start_[sequence+1] - 1); + offset_[sequence]++; + rhs += lower_[iRange+2] - lower_[iRange+1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange+1]); + } + } + if (CLP_METHOD2) { +#ifdef NONLIN_DEBUG + double saveRhs1 = rhs; + rhs = saveRhs; +#endif + unsigned char iStatus = status_[sequence]; + int iWhere = currentStatus(iStatus); + if (iWhere == CLP_SAME) + iWhere = originalStatus(iStatus); + // rhs always increases + if (iWhere == CLP_FEASIBLE) { + if (alpha > 0.0) { + // going below + iWhere = CLP_BELOW_LOWER; + rhs = COIN_DBL_MAX; + } else { + // going above + iWhere = CLP_ABOVE_UPPER; + rhs = COIN_DBL_MAX; + } + } else if (iWhere == CLP_BELOW_LOWER) { + assert (alpha < 0); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += bound_[sequence] - model_->upperRegion()[sequence]; + } else { + assert (iWhere == CLP_ABOVE_UPPER); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += model_->lowerRegion()[sequence] - bound_[sequence]; + } + setCurrentStatus(status_[sequence], iWhere); +#ifdef NONLIN_DEBUG + assert(saveRhs1 == rhs); +#endif + returnValue = fabs(alpha) * infeasibilityWeight_; + } + return returnValue; + } + /// Returns current lower bound + inline double lower(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence]]; + } + /// Returns current upper bound + inline double upper(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence] + 1]; + } + /// Returns current cost + inline double cost(int sequence) const { + return cost_[whichRange_[sequence] + offset_[sequence]]; + } + //@} + + + /**@name Gets and sets */ + //@{ + /// Number of infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Change in cost + inline double changeInCost() const { + return changeCost_; + } + /// Feasible cost + inline double feasibleCost() const { + return feasibleCost_; + } + /// Feasible cost with offset and direction (i.e. for reporting) + double feasibleReportCost() const; + /// Sum of infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Largest infeasibility + inline double largestInfeasibility() const { + return largestInfeasibility_; + } + /// Average theta + inline double averageTheta() const { + return averageTheta_; + } + inline void setAverageTheta(double value) { + averageTheta_ = value; + } + inline void setChangeInCost(double value) { + changeCost_ = value; + } + inline void setMethod(int value) { + method_ = value; + } + /// See if may want to look both ways + inline bool lookBothWays() const { + return bothWays_; + } + //@} + ///@name Private functions to deal with infeasible regions + inline bool infeasible(int i) const { + return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setInfeasible(int i, bool trueFalse) { + unsigned int & value = infeasible_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + inline unsigned char * statusArray() const { + return status_; + } + /// For debug + void validate(); + //@} + +private: + /**@name Data members */ + //@{ + /// Change in cost because of infeasibilities + double changeCost_; + /// Feasible cost + double feasibleCost_; + /// Current infeasibility weight + double infeasibilityWeight_; + /// Largest infeasibility + double largestInfeasibility_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Average theta - kept here as only for primal + double averageTheta_; + /// Number of rows (mainly for checking and copy) + int numberRows_; + /// Number of columns (mainly for checking and copy) + int numberColumns_; + /// Starts for each entry (columns then rows) + int * start_; + /// Range for each entry (columns then rows) + int * whichRange_; + /// Temporary range offset for each entry (columns then rows) + int * offset_; + /** Lower bound for each range (upper bound is next lower). + For various reasons there is always an infeasible range + at bottom - even if lower bound is - infinity */ + double * lower_; + /// Cost for each range + double * cost_; + /// Model + ClpSimplex * model_; + // Array to say which regions are infeasible + unsigned int * infeasible_; + /// Number of infeasibilities found + int numberInfeasibilities_; + // new stuff + /// Contains status at beginning and current + unsigned char * status_; + /// Bound which has been replaced in lower_ or upper_ + double * bound_; + /// Feasible cost array + double * cost2_; + /// Method 1 old, 2 new, 3 both! + int method_; + /// If all non-linear costs convex + bool convex_; + /// If we should look both ways for djs + bool bothWays_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpObjective.hpp b/thirdparty/linux/include/coin/coin/ClpObjective.hpp new file mode 100644 index 0000000..f98903a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpObjective.hpp @@ -0,0 +1,134 @@ +/* $Id: ClpObjective.hpp 1825 2011-11-20 16:02:57Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpObjective_H +#define ClpObjective_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Objective Abstract Base Class + +Abstract Base Class for describing an objective function + +*/ +class ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Linear then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, + double & offset, bool refresh, + int includeLinear = 2) = 0; + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts) = 0; + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj) = 0; + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const = 0; + /// Resize objective + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale objective + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpObjective(); + + /// Copy constructor + ClpObjective(const ClpObjective &); + + /// Assignment operator + ClpObjective & operator=(const ClpObjective& rhs); + + /// Destructor + virtual ~ClpObjective (); + + /// Clone + virtual ClpObjective * clone() const = 0; + /** Subset clone. Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + ///@name Other + //@{ + /// Returns type (above 63 is extra information) + inline int type() const { + return type_; + } + /// Sets type (above 63 is extra information) + inline void setType(int value) { + type_ = value; + } + /// Whether activated + inline int activated() const { + return activated_; + } + /// Set whether activated + inline void setActivated(int value) { + activated_ = value; + } + + /// Objective offset + inline double nonlinearOffset () const { + return offset_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Value of non-linear part of objective + double offset_; + /// Type of objective - linear is 1 + int type_; + /// Whether activated + int activated_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPackedMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpPackedMatrix.hpp new file mode 100644 index 0000000..ec0c0b9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPackedMatrix.hpp @@ -0,0 +1,638 @@ +/* $Id: ClpPackedMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPackedMatrix_H +#define ClpPackedMatrix_H + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements CoinPackedMatrix as derived from ClpMatrixBase. + + It adds a few methods that know about model as well as matrix + + For details see CoinPackedMatrix */ + +class ClpPackedMatrix2; +class ClpPackedMatrix3; +class ClpPackedMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const { + return matrix_; + } + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return matrix_->isColOrdered(); + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return matrix_->getNumElements(); + } + /** Number of columns. */ + virtual int getNumCols() const { + return matrix_->getNumCols(); + } + /** Number of rows. */ + virtual int getNumRows() const { + return matrix_->getNumRows(); + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const { + return matrix_->getElements(); + } + /// Mutable elements + inline double * getMutableElements() const { + return matrix_->getMutableElements(); + } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return matrix_->getIndices(); + } + + virtual const CoinBigIndex * getVectorStarts() const { + return matrix_->getVectorStarts(); + } + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const { + return matrix_->getVectorLengths(); + } + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const { + return matrix_->getVectorSize(index); + } + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + /** Replace the elements of a vector. The indices remain the same. + This is only needed if scaling and a row copy is used. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + virtual void replaceVector(const int index, + const int numReplace, const double * newElements) { + matrix_->replaceVector(index, numReplace, newElements); + } + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Creates scales for column copy (rowCopy in model may be modified) + returns non-zero if no scaling done */ + virtual int scale(ClpModel * model, const ClpSimplex * baseModel = NULL) const ; + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * model) const ; + /// Creates scaled column copy if scales exist + void createScaledMatrix(ClpSimplex * model) const; + /** Realy really scales column copy + Only called if scales already exist. + Up to user ro delete */ + virtual ClpMatrixBase * scaledColumnCopy(ClpModel * model) const ; + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * model, + double smallest, double largest, + int check = 15); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const { } + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// makes sure active columns correct + virtual int refresh(ClpSimplex * model); + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return <code>y - pi * A</code> in <code>y</code>. + @pre <code>pi</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> + This just does subset (but puts in correct place in y) */ + void transposeTimesSubset( int number, + const int * which, + const double * pi, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Note - If x packed mode - then z packed mode + This does by column and knows no gaps + Squashes small elements and knows about ClpSimplex */ + void transposeTimesByColumn(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); +#if COIN_LONG_WORK + // For long double versions + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; +#endif +//@} + + /**@name Other */ + //@{ + /// Returns CoinPackedMatrix (non const) + inline CoinPackedMatrix * matrix() const { + return matrix_; + } + /** Just sets matrix_ to NULL so it can be used elsewhere. + used in GUB + */ + inline void setMatrixNull() { + matrix_ = NULL; + } + /// Say we want special column copy + inline void makeSpecialColumnCopy() { + flags_ |= 16; + } + /// Say we don't want special column copy + void releaseSpecialColumnCopy(); + /// Are there zeros? + inline bool zeros() const { + return ((flags_ & 1) != 0); + } + /// Do we want special column copy + inline bool wantsSpecialColumnCopy() const { + return ((flags_ & 16) != 0); + } + /// Flags + inline int flags() const { + return flags_; + } + /// Sets flags_ correctly + inline void checkGaps() { + flags_ = (matrix_->hasGaps()) ? (flags_ | 2) : (flags_ & (~2)); + } + /// number of active columns (normally same as number of columns) + inline int numberActiveColumns() const + { return numberActiveColumns_;} + /// Set number of active columns (normally same as number of columns) + inline void setNumberActiveColumns(int value) + { numberActiveColumns_ = value;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix(); + /** Destructor */ + virtual ~ClpPackedMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix(const ClpPackedMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpPackedMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPackedMatrix (const ClpPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpPackedMatrix(CoinPackedMatrix * matrix); + + ClpPackedMatrix& operator=(const ClpPackedMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /// Copy contents - resizing if necessary - otherwise re-use memory + virtual void copy(const ClpPackedMatrix * from); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// make special row copy + void specialRowCopy(ClpSimplex * model, const ClpMatrixBase * rowCopy); + /// make special column copy + void specialColumnCopy(ClpSimplex * model); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} +private: + /// Meat of transposeTimes by column when not scaled + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when scaled + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when not scaled and skipping + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /** Meat of transposeTimes by column when not scaled and skipping + and doing part of dualColumn */ + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + int * COIN_RESTRICT spareIndex, + double * COIN_RESTRICT spareArray, + const double * COIN_RESTRICT reducedCost, + double & upperTheta, + double & bestPossible, + double acceptablePivot, + double dualTolerance, + int & numberRemaining, + const double zeroTolerance) const; + /// Meat of transposeTimes by column when scaled and skipping + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /// Meat of transposeTimes by row n > K if packed - returns number nonzero + int gutsOfTransposeTimesByRowGEK(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int numberColumns, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + double * COIN_RESTRICT array2, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3a(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int * COIN_RESTRICT lookup, + char * COIN_RESTRICT marked, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n == 2 if packed + void gutsOfTransposeTimesByRowEQ2(const CoinIndexedVector * piVector, CoinIndexedVector * output, + CoinIndexedVector * spareVector, const double tolerance, const double scalar) const; + /// Meat of transposeTimes by row n == 1 if packed + void gutsOfTransposeTimesByRowEQ1(const CoinIndexedVector * piVector, CoinIndexedVector * output, + const double tolerance, const double scalar) const; + /// Gets rid of special copies + void clearCopies(); + + +protected: + /// Check validity + void checkFlags(int type) const; + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + CoinPackedMatrix * matrix_; + /// number of active columns (normally same as number of columns) + int numberActiveColumns_; + /** Flags - + 1 - has zero elements + 2 - has gaps + 4 - has special row copy + 8 - has special column copy + 16 - wants special column copy + */ + mutable int flags_; + /// Special row copy + ClpPackedMatrix2 * rowCopy_; + /// Special column copy + ClpPackedMatrix3 * columnCopy_; + //@} +}; +#ifdef THREAD +#include <pthread.h> +typedef struct { + double acceptablePivot; + const ClpSimplex * model; + double * spare; + int * spareIndex; + double * arrayTemp; + int * indexTemp; + int * numberInPtr; + double * bestPossiblePtr; + double * upperThetaPtr; + int * posFreePtr; + double * freePivotPtr; + int * numberOutPtr; + const unsigned short * count; + const double * pi; + const CoinBigIndex * rowStart; + const double * element; + const unsigned short * column; + int offset; + int numberInRowArray; + int numberLook; +} dualColumn0Struct; +#endif +class ClpPackedMatrix2 { + +public: + /**@name Useful methods */ + //@{ + /** Return <code>x * -1 * A in <code>z</code>. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const CoinPackedMatrix * rowCopy, + const CoinIndexedVector * x, + CoinIndexedVector * spareArray, + CoinIndexedVector * z) const; + /// Returns true if copy has useful information + inline bool usefulInfo() const { + return rowStart_ != NULL; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix2(); + /** Constructor from copy. */ + ClpPackedMatrix2(ClpSimplex * model, const CoinPackedMatrix * rowCopy); + /** Destructor */ + virtual ~ClpPackedMatrix2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix2(const ClpPackedMatrix2&); + ClpPackedMatrix2& operator=(const ClpPackedMatrix2&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of rows + int numberRows_; + /// Column offset for each block (plus one at end) + int * offset_; + /// Counts of elements in each part of row + mutable unsigned short * count_; + /// Row starts + mutable CoinBigIndex * rowStart_; + /// columns within block + unsigned short * column_; + /// work arrays + double * work_; +#ifdef THREAD + pthread_t * threadId_; + dualColumn0Struct * info_; +#endif + //@} +}; +typedef struct { + CoinBigIndex startElements_; // point to data + int startIndices_; // point to column_ + int numberInBlock_; + int numberPrice_; // at beginning + int numberElements_; // number elements per column +} blockStruct; +class ClpPackedMatrix3 { + +public: + /**@name Useful methods */ + //@{ + /** Return <code>x * -1 * A in <code>z</code>. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const double * pi, + CoinIndexedVector * output) const; + /// Updates two arrays for steepest + void transposeTimes2(const ClpSimplex * model, + const double * pi, CoinIndexedVector * dj1, + const double * piWeight, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix3(); + /** Constructor from copy. */ + ClpPackedMatrix3(ClpSimplex * model, const CoinPackedMatrix * columnCopy); + /** Destructor */ + virtual ~ClpPackedMatrix3(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix3(const ClpPackedMatrix3&); + ClpPackedMatrix3& operator=(const ClpPackedMatrix3&); + //@} + /**@name Sort methods */ + //@{ + /** Sort blocks */ + void sortBlocks(const ClpSimplex * model); + /// Swap one variable + void swapOne(const ClpSimplex * model, const ClpPackedMatrix * matrix, + int iColumn); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of columns + int numberColumns_; + /// Column indices and reverse lookup (within block) + int * column_; + /// Starts for odd/long vectors + CoinBigIndex * start_; + /// Rows + int * row_; + /// Elements + double * element_; + /// Blocks (ordinary start at 0 and go to first block) + blockStruct * block_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpParameters.hpp b/thirdparty/linux/include/coin/coin/ClpParameters.hpp new file mode 100644 index 0000000..7252d2b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpParameters.hpp @@ -0,0 +1,126 @@ +/* $Id: ClpParameters.hpp 2046 2014-08-14 04:13:10Z tkr $ */ +// Copyright (C) 2000, 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _ClpParameters_H +#define _ClpParameters_H + +/** This is where to put any useful stuff. + +*/ +enum ClpIntParam { + /** The maximum number of iterations Clp can execute in the simplex methods + */ + ClpMaxNumIteration = 0, + /** The maximum number of iterations Clp can execute in hotstart before + terminating */ + ClpMaxNumIterationHotStart, + /** The name discipline; specifies how the solver will handle row and + column names. + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + ClpNameDiscipline, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastIntParam +}; + +enum ClpDblParam { + /** Set Dual objective limit. This is to be used as a termination criteria + in methods where the dual objective monotonically changes (dual + simplex). */ + ClpDualObjectiveLimit, + /** Primal objective limit. This is to be used as a termination + criteria in methods where the primal objective monotonically changes + (e.g., primal simplex) */ + ClpPrimalObjectiveLimit, + /** The maximum amount the dual constraints can be violated and still be + considered feasible. */ + ClpDualTolerance, + /** The maximum amount the primal constraints can be violated and still be + considered feasible. */ + ClpPrimalTolerance, + /** Objective function constant. This the value of the constant term in + the objective function. */ + ClpObjOffset, + /// Maximum time in seconds - after, this action is as max iterations + ClpMaxSeconds, + /// Maximum wallclock running time in seconds - after, this action is as max iterations + ClpMaxWallSeconds, + /// Tolerance to use in presolve + ClpPresolveTolerance, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastDblParam +}; + + +enum ClpStrParam { + /** Name of the problem. This is the found on the Name card of + an mps file. */ + ClpProbName = 0, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastStrParam +}; + +/// Copy (I don't like complexity of Coin version) +template <class T> inline void +ClpDisjointCopyN( const T * array, const int size, T * newArray) +{ + memcpy(reinterpret_cast<void *> (newArray), array, size * sizeof(T)); +} +/// And set +template <class T> inline void +ClpFillN( T * array, const int size, T value) +{ + int i; + for (i = 0; i < size; i++) + array[i] = value; +} +/// This returns a non const array filled with input from scalar or actual array +template <class T> inline T* +ClpCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) + ClpDisjointCopyN(array, size, arrayNew); + else + ClpFillN ( arrayNew, size, value); + return arrayNew; +} + +/// This returns a non const array filled with actual array (or NULL) +template <class T> inline T* +ClpCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + ClpDisjointCopyN(array, size, arrayNew); + return arrayNew; + } else { + return NULL; + } +} +/// For a structure to be used by trusted code +typedef struct { + int typeStruct; // allocated as 1,2 etc + int typeCall; + void * data; +} ClpTrustedData; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPdcoBase.hpp b/thirdparty/linux/include/coin/coin/ClpPdcoBase.hpp new file mode 100644 index 0000000..cb8fd8f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPdcoBase.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpPdcoBase.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPdcoBase_H +#define ClpPdcoBase_H + +#include "CoinPragma.hpp" + +#include "CoinPackedMatrix.hpp" +#include "CoinDenseVector.hpp" +class ClpInterior; + +/** Abstract base class for tailoring everything for Pcdo + + Since this class is abstract, no object of this type can be created. + + If a derived class provides all methods then all ClpPcdo algorithms + should work. + + Eventually we should be able to use ClpObjective and ClpMatrixBase. +*/ + +class ClpPdcoBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + virtual void matVecMult(ClpInterior * model, int mode, double * x, double * y) const = 0; + + virtual void getGrad(ClpInterior * model, CoinDenseVector<double> &x, CoinDenseVector<double> &grad) const = 0; + + virtual void getHessian(ClpInterior * model, CoinDenseVector<double> &x, CoinDenseVector<double> &H) const = 0; + + virtual double getObj(ClpInterior * model, CoinDenseVector<double> &x) const = 0; + + virtual void matPrecon(ClpInterior * model, double delta, double * x, double * y) const = 0; + + //@} + //@{ + ///@name Other + /// Clone + virtual ClpPdcoBase * clone() const = 0; + /// Returns type + inline int type() const { + return type_; + }; + /// Sets type + inline void setType(int type) { + type_ = type; + }; + /// Returns size of d1 + inline int sizeD1() const { + return 1; + }; + /// Returns d1 as scalar + inline double getD1() const { + return d1_; + }; + /// Returns size of d2 + inline int sizeD2() const { + return 1; + }; + /// Returns d2 as scalar + inline double getD2() const { + return d2_; + }; + //@} + + +protected: + + /**@name Constructors, destructor<br> + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpPdcoBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpPdcoBase(); +protected: + // Copy + ClpPdcoBase(const ClpPdcoBase&); + // Assignment + ClpPdcoBase& operator=(const ClpPdcoBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Should be dense vectors + double d1_; + double d2_; + /// type (may be useful) + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPlusMinusOneMatrix.hpp b/thirdparty/linux/include/coin/coin/ClpPlusMinusOneMatrix.hpp new file mode 100644 index 0000000..0cf27a4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPlusMinusOneMatrix.hpp @@ -0,0 +1,290 @@ +/* $Id: ClpPlusMinusOneMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPlusMinusOneMatrix_H +#define ClpPlusMinusOneMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple +- one matrix as derived from ClpMatrixBase. + +*/ + +class ClpPlusMinusOneMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const ; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const; + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + // and for advanced use + int * getMutableIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const; + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /// Just checks matrix valid - will say if dimensions not quite right if detail + void checkValid(bool detail) const; + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + /**@name Other */ + //@{ + /// Return starts of +1s + inline CoinBigIndex * startPositive() const { + return startPositive_; + } + /// Return starts of -1s + inline CoinBigIndex * startNegative() const { + return startNegative_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPlusMinusOneMatrix(); + /** Destructor */ + virtual ~ClpPlusMinusOneMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix&); + /** The copy constructor from an CoinPlusMinusOneMatrix. + If not a valid matrix then getIndices will be NULL and + startPositive[0] will have number of +1, + startPositive[1] will have number of -1, + startPositive[2] will have number of others, + */ + ClpPlusMinusOneMatrix(const CoinPackedMatrix&); + /// Constructor from arrays + ClpPlusMinusOneMatrix(int numberRows, int numberColumns, + bool columnOrdered, const int * indices, + const CoinBigIndex * startPositive, const CoinBigIndex * startNegative); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + ClpPlusMinusOneMatrix& operator=(const ClpPlusMinusOneMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// pass in copy (object takes ownership) + void passInCopy(int numberRows, int numberColumns, + bool columnOrdered, int * indices, + CoinBigIndex * startPositive, CoinBigIndex * startNegative); + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Start of +1's for each + CoinBigIndex * COIN_RESTRICT startPositive_; + /// Start of -1's for each + CoinBigIndex * COIN_RESTRICT startNegative_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * COIN_RESTRICT indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; +#ifdef CLP_PLUS_ONE_MATRIX + /** Other flags (could have columnOrdered_?) + 1 bit - says just +1 + */ + mutable int otherFlags_; +#endif + /// True if column ordered + bool columnOrdered_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPresolve.hpp b/thirdparty/linux/include/coin/coin/ClpPresolve.hpp new file mode 100644 index 0000000..5e28289 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPresolve.hpp @@ -0,0 +1,299 @@ +/* $Id: ClpPresolve.hpp 2134 2015-03-22 16:40:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPresolve_H +#define ClpPresolve_H +#include "ClpSimplex.hpp" + +class CoinPresolveAction; +#include "CoinPresolveMatrix.hpp" +/** This is the Clp interface to CoinPresolve + +*/ +class ClpPresolve { +public: + /**@name Main Constructor, destructor */ + //@{ + /// Default constructor + ClpPresolve(); + + /// Virtual destructor + virtual ~ClpPresolve(); + //@} + /**@name presolve - presolves a model, transforming the model + * and saving information in the ClpPresolve object needed for postsolving. + * This underlying (protected) method is virtual; the idea is that in the future, + * one could override this method to customize how the various + * presolve techniques are applied. + + This version of presolve returns a pointer to a new presolved + model. NULL if infeasible or unbounded. + This should be paired with postsolve + below. The advantage of going back to original model is that it + will be exactly as it was i.e. 0.0 will not become 1.0e-19. + If keepIntegers is true then bounds may be tightened in + original. Bounds will be moved by up to feasibilityTolerance + to try and stay feasible. + Names will be dropped in presolved model if asked + */ + ClpSimplex * presolvedModel(ClpSimplex & si, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +#ifndef CLP_NO_STD + /** This version saves data in a file. The passed in model + is updated to be presolved model. + Returns non-zero if infeasible*/ + int presolvedModelToFile(ClpSimplex &si, std::string fileName, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false); +#endif + /** Return pointer to presolved model, + Up to user to destroy */ + ClpSimplex * model() const; + /// Return pointer to original model + ClpSimplex * originalModel() const; + /// Set pointer to original model + void setOriginalModel(ClpSimplex * model); + + /// return pointer to original columns + const int * originalColumns() const; + /// return pointer to original rows + const int * originalRows() const; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) { + nonLinearValue_ = value; + } + inline double nonLinearValue() const { + return nonLinearValue_; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (presolveActions_ & 1) == 0; + } + inline void setDoDual(bool doDual) { + if (doDual) presolveActions_ &= ~1; + else presolveActions_ |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (presolveActions_ & 2) == 0; + } + inline void setDoSingleton(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~2; + else presolveActions_ |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (presolveActions_ & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton) { + if (doDoubleton) presolveActions_ &= ~4; + else presolveActions_ |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (presolveActions_ & 8) == 0; + } + inline void setDoTripleton(bool doTripleton) { + if (doTripleton) presolveActions_ &= ~8; + else presolveActions_ |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (presolveActions_ & 16) == 0; + } + inline void setDoTighten(bool doTighten) { + if (doTighten) presolveActions_ &= ~16; + else presolveActions_ |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (presolveActions_ & 32) == 0; + } + inline void setDoForcing(bool doForcing) { + if (doForcing) presolveActions_ &= ~32; + else presolveActions_ |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (presolveActions_ & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) presolveActions_ &= ~64; + else presolveActions_ |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (presolveActions_ & 128) == 0; + } + inline void setDoDupcol(bool doDupcol) { + if (doDupcol) presolveActions_ &= ~128; + else presolveActions_ |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (presolveActions_ & 256) == 0; + } + inline void setDoDuprow(bool doDuprow) { + if (doDuprow) presolveActions_ &= ~256; + else presolveActions_ |= 256; + } + /// Whether we want to do dependency part of presolve + inline bool doDependency() const { + return (presolveActions_ & 32768) != 0; + } + inline void setDoDependency(bool doDependency) { + if (doDependency) presolveActions_ |= 32768; + else presolveActions_ &= ~32768; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (presolveActions_ & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~512; + else presolveActions_ |= 512; + } + /// Whether we want to do gubrow part of presolve + inline bool doGubrow() const { + return (presolveActions_ & 1024) == 0; + } + inline void setDoGubrow(bool doGubrow) { + if (doGubrow) presolveActions_ &= ~1024; + else presolveActions_ |= 1024; + } + /// Whether we want to do twoxtwo part of presolve + inline bool doTwoxTwo() const { + return (presolveActions_ & 2048) != 0; + } + inline void setDoTwoxtwo(bool doTwoxTwo) { + if (!doTwoxTwo) presolveActions_ &= ~2048; + else presolveActions_ |= 2048; + } + /// Whether we want to allow duplicate intersections + inline bool doIntersection() const { + return (presolveActions_ & 4096) != 0; + } + inline void setDoIntersection(bool doIntersection) { + if (doIntersection) presolveActions_ &= ~4096; + else presolveActions_ |= 4096; + } + /** How much we want to zero small values from aggregation - ratio + 0 - 1.0e-12, 1 1.0e-11, 2 1.0e-10, 3 1.0e-9 */ + inline int zeroSmall() const { + return (presolveActions_&(8192|16384))>>13; + } + inline void setZeroSmall(int value) { + presolveActions_ &= ~(8192|16384); + presolveActions_ |= value<<13; + } + /// Set whole group + inline int presolveActions() const { + return presolveActions_ & 0xffff; + } + inline void setPresolveActions(int action) { + presolveActions_ = (presolveActions_ & 0xffff0000) | (action & 0xffff); + } + /// Substitution level + inline void setSubstitution(int value) { + substitution_ = value; + } + /// Asks for statistics + inline void statistics() { + presolveActions_ |= 0x80000000; + } + /// Return presolve status (0,1,2) + int presolveStatus() const; + + /**@name postsolve - postsolve the problem. If the problem + has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept + of "basic" rows/cols, then set updateStatus + + Note that if you modified the original problem after presolving, + then you must ``undo'' these modifications before calling postsolve. + This version updates original*/ + virtual void postsolve(bool updateStatus = true); + + /// Gets rid of presolve actions (e.g.when infeasible) + void destroyPresolve(); + + /**@name private or protected data */ +private: + /// Original model - must not be destroyed before postsolve + ClpSimplex * originalModel_; + + /// ClpPresolved model - up to user to destroy by deleteClpPresolvedModel + ClpSimplex * presolvedModel_; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + /// Original column numbers + int * originalColumn_; + /// Original row numbers + int * originalRow_; + /// Row objective + double * rowObjective_; + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /// The postsolved problem will expand back to its former size + /// as postsolve transformations are applied. + /// It is efficient to allocate data structures for the final size + /// of the problem rather than expand them as needed. + /// These fields give the size of the original problem. + int ncols_; + int nrows_; + CoinBigIndex nelems_; + /// Number of major passes + int numberPasses_; + /// Substitution level + int substitution_; +#ifndef CLP_NO_STD + /// Name of saved model file + std::string saveFile_; +#endif + /** Whether we want to skip dual part of presolve etc. + 512 bit allows duplicate column processing on integer columns + and dual stuff on integers + */ + int presolveActions_; +protected: + /// If you want to apply the individual presolve routines differently, + /// or perhaps add your own to the mix, + /// define a derived class and override this method + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /// Postsolving is pretty generic; just apply the transformations + /// in reverse order. + /// You will probably only be interested in overriding this method + /// if you want to add code to test for consistency + /// while debugging new presolve techniques. + virtual void postsolve(CoinPostsolveMatrix &prob); + /** This is main part of Presolve */ + virtual ClpSimplex * gutsOfPresolvedModel(ClpSimplex * originalModel, + double feasibilityTolerance, + bool keepIntegers, + int numberPasses, + bool dropNames, + bool doRowObjective, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPrimalColumnDantzig.hpp b/thirdparty/linux/include/coin/coin/ClpPrimalColumnDantzig.hpp new file mode 100644 index 0000000..7289ead --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPrimalColumnDantzig.hpp @@ -0,0 +1,72 @@ +/* $Id: ClpPrimalColumnDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnDantzig_H +#define ClpPrimalColumnDantzig_H + +#include "ClpPrimalColumnPivot.hpp" + +//############################################################################# + +/** Primal Column Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpPrimalColumnDantzig : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + Lumbers over all columns - slow + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Can just do full price if you really want to be slow + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /// Just sets model + virtual void saveWeights(ClpSimplex * model, int) { + model_ = model; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnDantzig(); + + /// Copy constructor + ClpPrimalColumnDantzig(const ClpPrimalColumnDantzig &); + + /// Assignment operator + ClpPrimalColumnDantzig & operator=(const ClpPrimalColumnDantzig& rhs); + + /// Destructor + virtual ~ClpPrimalColumnDantzig (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPrimalColumnPivot.hpp b/thirdparty/linux/include/coin/coin/ClpPrimalColumnPivot.hpp new file mode 100644 index 0000000..678da30 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPrimalColumnPivot.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpPrimalColumnPivot.hpp 1732 2011-05-31 08:09:41Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalcolumnPivot_H +#define ClpPrimalcolumnPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Primal Column Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose column pivot in primal simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. For Dantzig +the only one of any importance is pivotColumn. + +If you wish to inherit from this look at ClpPrimalColumnDantzig.cpp +as that is simplest version. +*/ + +class ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none + + Normally updates reduced costs using result of last iteration + before selecting incoming column. + + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + + Inside pivotColumn the pivotRow_ and reduced cost from last iteration + are also used. + + So in the simplest case i.e. feasible we compute the row of the + tableau corresponding to last pivot and add a multiple of this + to current reduced costs. + + We can use other arrays to help updates + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2) = 0; + + /// Updates weights - part 1 (may be empty) + virtual void updateWeights(CoinIndexedVector * input); + + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) forces some initialization e.g. weights + Also sets model + */ + virtual void saveWeights(ClpSimplex * model, int mode) = 0; + /** Signals pivot row choice: + -2 (default) - use normal pivot row choice + -1 to numberRows-1 - use this (will be checked) + way should be -1 to go to lower bound, +1 to upper bound + */ + virtual int pivotRow(double & way) { + way = 0; + return -2; + } + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const { + return looksOptimal_; + } + /// Sets optimality flag (for advanced use) + virtual void setLooksOptimal(bool flag) { + looksOptimal_ = flag; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnPivot(); + + /// Copy constructor + ClpPrimalColumnPivot(const ClpPrimalColumnPivot &); + + /// Assignment operator + ClpPrimalColumnPivot & operator=(const ClpPrimalColumnPivot& rhs); + + /// Destructor + virtual ~ClpPrimalColumnPivot (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + /// Sets model + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of column pivot algorithm + int type_; + /// Says if looks optimal (normally computed) + bool looksOptimal_; + //@} +}; +#ifndef CLP_PRIMAL_SLACK_MULTIPLIER +#define CLP_PRIMAL_SLACK_MULTIPLIER 1.01 +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpPrimalColumnSteepest.hpp b/thirdparty/linux/include/coin/coin/ClpPrimalColumnSteepest.hpp new file mode 100644 index 0000000..2da7542 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpPrimalColumnSteepest.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpPrimalColumnSteepest.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnSteepest_H +#define ClpPrimalColumnSteepest_H + +#include "ClpPrimalColumnPivot.hpp" +#include <bitset> + +//############################################################################# +class CoinIndexedVector; + + +/** Primal Column Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + + +class ClpPrimalColumnSteepest : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Parts of operation split out into separate functions for + profiling and speed + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// For quadratic or funny nonlinearities + int pivotColumnOldMethod(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Just update djs + void justDjs(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs doing partial pricing (dantzig) + int partialPricing(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + int numberWanted, + int numberLook); + /// Update djs, weights for Devex using djs + void djsAndDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using djs + void djsAndSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Devex using pivot row + void djsAndDevex2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using pivot row + void djsAndSteepest2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Devex + void justDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Steepest + void justSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Updates two arrays for steepest + void transposeTimes2(const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + CoinIndexedVector * spare, double scaleFactor); + + /// Updates weights - part 1 - also checks accuracy + virtual void updateWeights(CoinIndexedVector * input); + + /// Checks accuracy - just for debug + void checkAccuracy(int sequence, double relativeTolerance, + CoinIndexedVector * rowArray1, + CoinIndexedVector * rowArray2); + + /// Initialize weights + void initializeWeights(); + + /** Save weights - this may initialize weights as well + mode is - + 1) before factorization + 2) after factorization + 3) just redo infeasibilities + 4) restore weights + 5) at end of values pass (so need initialization) + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + +//@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + */ + ClpPrimalColumnSteepest(int mode = 3); + + /// Copy constructor + ClpPrimalColumnSteepest(const ClpPrimalColumnSteepest & rhs); + + /// Assignment operator + ClpPrimalColumnSteepest & operator=(const ClpPrimalColumnSteepest& rhs); + + /// Destructor + virtual ~ClpPrimalColumnSteepest (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + ///@name Private functions to deal with devex + /** reference would be faster using ClpSimplex's status_, + but I prefer to keep modularity. + */ + inline bool reference(int i) const { + return ((reference_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setReference(int i, bool trueFalse) { + unsigned int & value = reference_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } + + //@} + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + // Update weight + double devex_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible columns) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + double * savedWeights_; + // Array for exact devex to say what is in reference framework + unsigned int * reference_; + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + 5 is always partial dantzig + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + + New dubious option is >=10 which does mini-sprint + + */ + int mode_; + /// Life of weights + Persistence persistence_; + /// Number of times switched from partial dantzig to 0/2 + int numberSwitched_; + // This is pivot row (or pivot sequence round re-factorization) + int pivotSequence_; + // This is saved pivot sequence + int savedPivotSequence_; + // This is saved outgoing variable + int savedSequenceOut_; + // Iteration when last rectified + int lastRectified_; + // Size of factorization at invert (used to decide algorithm) + int sizeFactorization_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpQuadraticObjective.hpp b/thirdparty/linux/include/coin/coin/ClpQuadraticObjective.hpp new file mode 100644 index 0000000..a52b097 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpQuadraticObjective.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpQuadraticObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpQuadraticObjective_H +#define ClpQuadraticObjective_H + +#include "ClpObjective.hpp" +#include "CoinPackedMatrix.hpp" + +//############################################################################# + +/** Quadratic Objective Class + +*/ + +class ClpQuadraticObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Quadratic then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /// Resize objective + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpQuadraticObjective(); + + /// Constructor from objective + ClpQuadraticObjective(const double * linearObjective, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns_ = -1); + + /** Copy constructor . + If type is -1 then make sure half symmetric, + if +1 then make sure full + */ + ClpQuadraticObjective(const ClpQuadraticObjective & rhs, int type = 0); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpQuadraticObjective (const ClpQuadraticObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpQuadraticObjective & operator=(const ClpQuadraticObjective& rhs); + + /// Destructor + virtual ~ClpQuadraticObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns = -1); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + //@} + ///@name Gets and sets + //@{ + /// Quadratic objective + inline CoinPackedMatrix * quadraticObjective() const { + return quadraticObjective_; + } + /// Linear objective + inline double * linearObjective() const { + return objective_; + } + /// Length of linear objective which could be bigger + inline int numberExtendedColumns() const { + return numberExtendedColumns_; + } + /// Number of columns in quadratic objective + inline int numberColumns() const { + return numberColumns_; + } + /// If a full or half matrix + inline bool fullMatrix() const { + return fullMatrix_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Quadratic objective + CoinPackedMatrix * quadraticObjective_; + /// Objective + double * objective_; + /// Gradient + double * gradient_; + /// Useful to have number of columns about + int numberColumns_; + /// Also length of linear objective which could be bigger + int numberExtendedColumns_; + /// True if full symmetric matrix, false if half + bool fullMatrix_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpSimplex.hpp b/thirdparty/linux/include/coin/coin/ClpSimplex.hpp new file mode 100644 index 0000000..bab4506 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSimplex.hpp @@ -0,0 +1,1797 @@ +/* $Id: ClpSimplex.hpp 2114 2015-02-10 12:12:46Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplex_H +#define ClpSimplex_H + +#include <iostream> +#include <cfloat> +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "ClpConfig.h" +class ClpDualRowPivot; +class ClpPrimalColumnPivot; +class ClpFactorization; +class CoinIndexedVector; +class ClpNonLinearCost; +class ClpNodeStuff; +class CoinStructuredModel; +class OsiClpSolverInterface; +class CoinWarmStartBasis; +class ClpDisasterHandler; +class ClpConstraint; +/* + May want to use Clp defaults so that with ABC defined but not used + it behaves as Clp (and ABC used will be different than if not defined) + */ +#ifdef ABC_INHERIT +#ifndef CLP_INHERIT_MODE +#define CLP_INHERIT_MODE 1 +#endif +#ifndef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 0 +#endif +#else +#undef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 1 +#endif +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +class AbcTolerancesEtc; +class AbcSimplex; +#include "CoinAbcCommon.hpp" +#endif +/** This solves LPs using the simplex method + + It inherits from ClpModel and all its arrays are created at + algorithm time. Originally I tried to work with model arrays + but for simplicity of coding I changed to single arrays with + structural variables then row variables. Some coding is still + based on old style and needs cleaning up. + + For a description of algorithms: + + for dual see ClpSimplexDual.hpp and at top of ClpSimplexDual.cpp + for primal see ClpSimplexPrimal.hpp and at top of ClpSimplexPrimal.cpp + + There is an algorithm data member. + for primal variations + and - for dual variations + +*/ + +class ClpSimplex : public ClpModel { + friend void ClpSimplexUnitTest(const std::string & mpsDir); + +public: + /** enums for status of various sorts. + First 4 match CoinWarmStartBasis, + isFixed means fixed at lower bound and out of basis + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04, + isFixed = 0x05 + }; + // For Dual + enum FakeBound { + noFake = 0x00, + lowerFake = 0x01, + upperFake = 0x02, + bothFake = 0x03 + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplex (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpSimplex & rhs, int scalingMode = -1); + /** Copy constructor from model. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpModel & rhs, int scalingMode = -1); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpSimplex * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** This constructor modifies original ClpSimplex and stores + original stuff in created ClpSimplex. It is only to be used in + conjunction with originalModel */ + ClpSimplex (ClpSimplex * wholeModel, + int numberColumns, const int * whichColumns); + /** This copies back stuff from miniModel and then deletes miniModel. + Only to be used with mini constructor */ + void originalModel(ClpSimplex * miniModel); + inline int abcState() const + { return abcState_;} + inline void setAbcState(int state) + { abcState_=state;} +#ifdef ABC_INHERIT + inline AbcSimplex * abcSimplex() const + { return abcSimplex_;} + inline void setAbcSimplex(AbcSimplex * simplex) + { abcSimplex_=simplex;} + /// Returns 0 if dual can be skipped + int doAbcDual(); + /// Returns 0 if primal can be skipped + int doAbcPrimal(int ifValuesPass); +#endif + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + void setPersistenceFlag(int value); + /// Save a copy of model with certain state - normally without cuts + void makeBaseModel(); + /// Switch off base model + void deleteBaseModel(); + /// See if we have base model + inline ClpSimplex * baseModel() const { + return baseModel_; + } + /** Reset to base model (just size and arrays needed) + If model NULL use internal copy + */ + void setToBaseModel(ClpSimplex * model = NULL); + /// Assignment operator. This copies the data + ClpSimplex & operator=(const ClpSimplex & rhs); + /// Destructor + ~ClpSimplex ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinModel & modelObject, bool keepSolution = false); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + int readLp(const char *filename, const double epsilon = 1e-5); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one, but sets scaling on etc. */ + void borrowModel(ClpModel & otherModel); + void borrowModel(ClpSimplex & otherModel); + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Puts solution back into small model + void getbackSolution(const ClpSimplex & smallModel, const int * whichRow, const int * whichColumn); + /** Load nonlinear part of problem from AMPL info + Returns 0 if linear + 1 if quadratic objective + 2 if quadratic constraints + 3 if nonlinear objective + 4 if nonlinear constraints + -1 on failure + */ + int loadNonLinear(void * info, int & numberConstraints, + ClpConstraint ** & constraints); +#ifdef ABC_INHERIT + /// Loads tolerances etc + void loadTolerancesEtc(const AbcTolerancesEtc & data); + /// Unloads tolerances etc + void unloadTolerancesEtc(AbcTolerancesEtc & data); +#endif + //@} + + /**@name Functions most useful to user */ + //@{ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + int initialSolve(ClpSolve & options); + /// Default initial solve + int initialSolve(); + /// Dual initial solve + int initialDualSolve(); + /// Primal initial solve + int initialPrimalSolve(); + /// Barrier initial solve + int initialBarrierSolve(); + /// Barrier initial solve, not to be followed by crossover + int initialBarrierNoCrossSolve(); + /** Dual algorithm - see ClpSimplexDual.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int dual(int ifValuesPass = 0, int startFinishOptions = 0); + // If using Debug + int dualDebug(int ifValuesPass = 0, int startFinishOptions = 0); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + /** Solves nonlinear problem using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solves problem with nonlinear constraints using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + /** Solves using barrier (assumes you have good cholesky factor code). + Does crossover to simplex if asked*/ + int barrier(bool crossover = true); + /** Solves non-linear using reduced gradient. Phase = 0 get feasible, + =1 use solution */ + int reducedGradient(int phase = 0); + /// Solve using structure of model and maybe in parallel + int solve(CoinStructuredModel * model); +#ifdef ABC_INHERIT + /** solvetype 0 for dual, 1 for primal + startup 1 for values pass + interrupt whether to pass across interrupt handler + add 10 to return AbcSimplex + */ + AbcSimplex * dealWithAbc(int solveType,int startUp,bool interrupt=false); + //void dealWithAbc(int solveType,int startUp,bool interrupt=false); +#endif + /** This loads a model from a CoinStructuredModel object - returns number of errors. + If originalOrder then keep to order stored in blocks, + otherwise first column/rows correspond to first block - etc. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinStructuredModel & modelObject, + bool originalOrder = true, bool keepSolution = false); + /** + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + + return code as dual/primal + */ + int cleanup(int cleanupScaling); + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + Returns non-zero if infeasible unbounded etc + */ + int dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + Returns non-zero if infeasible unbounded etc + */ + int primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** + Modifies coefficients etc and if necessary pivots in and out. + All at same status will be done (basis may go singular). + User can tell which others have been done (i.e. if status matches). + If called from outside will change status and return 0. + If called from event handler returns non-zero if user has to take action. + indices>=numberColumns are slacks (obviously no coefficients) + status array is (char) Status enum + */ + int modifyCoefficientsAndPivot(int number, + const int * which, + const CoinBigIndex * start, + const int * row, + const double * newCoefficient, + const unsigned char * newStatus=NULL, + const double * newLower=NULL, + const double * newUpper=NULL, + const double * newObjective=NULL); + /** Take out duplicate rows (includes scaled rows and intersections). + On exit whichRows has rows to delete - return code is number can be deleted + or -1 if would be infeasible. + If tolerance is -1.0 use primalTolerance for equality rows and infeasibility + If cleanUp not zero then spend more time trying to leave more stable row + and make row bounds exact multiple of cleanUp if close enough + */ + int outDuplicateRows(int numberLook,int * whichRows, bool noOverlaps=false, double tolerance=-1.0, + double cleanUp=0.0); + /** Try simple crash like techniques to get closer to primal feasibility + returns final sum of infeasibilities */ + double moveTowardsPrimalFeasible(); + /** Try simple crash like techniques to remove super basic slacks + but only if > threshold */ + void removeSuperBasicSlacks(int threshold=0); + /** Mini presolve (faster) + Char arrays must be numberRows and numberColumns long + on entry second part must be filled in as follows - + 0 - possible + >0 - take out and do something (depending on value - TBD) + -1 row/column can't vanish but can have entries removed/changed + -2 don't touch at all + on exit <=0 ones will be in presolved problem + struct will be created and will be long enough + (information on length etc in first entry) + user must delete struct + */ + ClpSimplex * miniPresolve(char * rowType, char * columnType,void ** info); + /// After mini presolve + void miniPostsolve(const ClpSimplex * presolvedModel,void * info); + /// mini presolve and solve + void miniSolve(char * rowType, char *columnType,int algorithm, int startUp); + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex (later) + </ul> + + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /** Read a basis from the given filename, + returns -1 on file error, 0 if no values, 1 if values */ + int readBasis(const char *filename); + /// Returns a basis (to be deleted by user) + CoinWarmStartBasis * getBasis() const; + /// Passes in factorization + void setFactorization( ClpFactorization & factorization); + // Swaps factorization + ClpFactorization * swapFactorization( ClpFactorization * factorization); + /// Copies in factorization to existing one + void copyFactorization( ClpFactorization & factorization); + /** Tightens primal bounds to make dual faster. Unless + fixed or doTight>10, bounds are slightly looser than they could be. + This is to make dual go faster and is probably not needed + with a presolve. Returns non-zero if problem infeasible. + + Fudge for branch and bound - put bounds on columns of factor * + largest value (at continuous) - should improve stability + in branch and bound on infeasible branches (0.0 is off) + */ + int tightenPrimalBounds(double factor = 0.0, int doTight = 0, bool tightIntegers = false); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + ( If pivot -1 then can be made super basic!) + + If "pivot" is + -1 No pivoting - always primal + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + int crash(double gap, int pivot); + /// Sets row pivot choice algorithm in dual + void setDualRowPivotAlgorithm(ClpDualRowPivot & choice); + /// Sets column pivot choice algorithm in primal + void setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice); + /// Create a hotstart point of the optimization process + void markHotStart(void * & saveStuff); + /// Optimize starting from the hotstart + void solveFromHotStart(void * saveStuff); + /// Delete the snapshot + void unmarkHotStart(void * saveStuff); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// Fathom - 1 if solution + int fathom(void * stuff); + /** Do up to N deep - returns + -1 - no solution nNodes_ valid nodes + >= if solution and that node gives solution + ClpNode array is 2**N long. Values for N and + array are in stuff (nNodes_ also in stuff) */ + int fathomMany(void * stuff); + /// Double checks OK + double doubleCheck(); + /// Starts Fast dual2 + int startFastDual2(ClpNodeStuff * stuff); + /// Like Fast dual + int fastDual2(ClpNodeStuff * stuff); + /// Stops Fast dual2 + void stopFastDual2(ClpNodeStuff * stuff); + /** Deals with crunch aspects + mode 0 - in + 1 - out with solution + 2 - out without solution + returns small model or NULL + */ + ClpSimplex * fastCrunch(ClpNodeStuff * stuff, int mode); + //@} + + /**@name Needed for functionality of OsiSimplexInterface */ + //@{ + /** Pivot in a variable and out a variable. Returns 0 if okay, + 1 if inaccuracy forced re-factorization, -1 if would be singular. + Also updates primal/dual infeasibilities. + Assumes sequenceIn_ and pivotRow_ set and also directionIn and Out. + */ + int pivot(); + + /** Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ (or NULL if no pivot) + Return codes as before but -1 means no acceptable pivot + */ + int primalPivotResult(); + + /** Pivot out a variable and choose an incoing one. Assumes dual + feasible - will not go through a reduced cost. + Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int dualPivotResultPart1(); + /** Do actual pivot + state is 0 if need tableau column, 1 if in rowArray_[1] + */ + int pivotResultPart2(int algorithm,int state); + + /** Common bits of coding for dual and primal. Return 0 if okay, + 1 if bad matrix, 2 if very bad factorization + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + + */ + int startup(int ifValuesPass, int startFinishOptions = 0); + void finish(int startFinishOptions = 0); + + /** Factorizes and returns true if optimal. Used by user */ + bool statusOfProblem(bool initial = false); + /// If user left factorization frequency then compute + void defaultFactorizationFrequency(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(const ClpSimplex * rhs); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (numberPrimalInfeasibilities_ == 0); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (numberDualInfeasibilities_ == 0); + } + /// factorization + inline ClpFactorization * factorization() const { + return factorization_; + } + /// Sparsity on or off + bool sparseFactorization() const; + void setSparseFactorization(bool value); + /// Factorization frequency + int factorizationFrequency() const; + void setFactorizationFrequency(int value); + /// Dual bound + inline double dualBound() const { + return dualBound_; + } + void setDualBound(double value); + /// Infeasibility cost + inline double infeasibilityCost() const { + return infeasibilityCost_; + } + void setInfeasibilityCost(double value); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + inline int perturbation() const { + return perturbation_; + } + void setPerturbation(int value); + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Return true if the objective limit test can be relied upon + bool isObjectiveLimitTestValid() const ; + /// Sum of dual infeasibilities + inline double sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + inline void setSumDualInfeasibilities(double value) { + sumDualInfeasibilities_ = value; + } + /// Sum of relaxed dual infeasibilities + inline double sumOfRelaxedDualInfeasibilities() const { + return sumOfRelaxedDualInfeasibilities_; + } + inline void setSumOfRelaxedDualInfeasibilities(double value) { + sumOfRelaxedDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities + inline int numberDualInfeasibilities() const { + return numberDualInfeasibilities_; + } + inline void setNumberDualInfeasibilities(int value) { + numberDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities (without free) + inline int numberDualInfeasibilitiesWithoutFree() const { + return numberDualInfeasibilitiesWithoutFree_; + } + /// Sum of primal infeasibilities + inline double sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + inline void setSumPrimalInfeasibilities(double value) { + sumPrimalInfeasibilities_ = value; + } + /// Sum of relaxed primal infeasibilities + inline double sumOfRelaxedPrimalInfeasibilities() const { + return sumOfRelaxedPrimalInfeasibilities_; + } + inline void setSumOfRelaxedPrimalInfeasibilities(double value) { + sumOfRelaxedPrimalInfeasibilities_ = value; + } + /// Number of primal infeasibilities + inline int numberPrimalInfeasibilities() const { + return numberPrimalInfeasibilities_; + } + inline void setNumberPrimalInfeasibilities(int value) { + numberPrimalInfeasibilities_ = value; + } + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + int saveModel(const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + int restoreModel(const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc. + If setToBounds 0 then primal column values not changed + and used to compute primal row activity values. If 1 or 2 + then status used - so all nonbasic variables set to + indicated bound and if any values changed (or ==2) basic values re-computed. + */ + void checkSolution(int setToBounds = 0); + /** Just check solution (for internal use) - sets sum of + infeasibilities etc. */ + void checkSolutionInternal(); + /// Check unscaled primal solution but allow for rounding error + void checkUnscaledSolution(); + /// Useful row length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * rowArray(int index) const { + return rowArray_[index]; + } + /// Useful column length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * columnArray(int index) const { + return columnArray_[index]; + } + //@} + + /******************** End of most useful part **************/ + /**@name Functions less likely to be useful to casual user */ + //@{ + /** Given an existing factorization computes and checks + primal and dual solutions. Uses input arrays for variables at + bounds. Returns feasibility states */ + int getSolution ( const double * rowActivities, + const double * columnActivities); + /** Given an existing factorization computes and checks + primal and dual solutions. Uses current problem arrays for + bounds. Returns feasibility states */ + int getSolution (); + /** Constructs a non linear cost from list of non-linearities (columns only) + First lower of each column is taken as real lower + Last lower is taken as real upper and cost ignored + + Returns nonzero if bad data e.g. lowers not monotonic + */ + int createPiecewiseLinearCosts(const int * starts, + const double * lower, const double * gradient); + /// dual row pivot choice + inline ClpDualRowPivot * dualRowPivot() const { + return dualRowPivot_; + } + /// primal column pivot choice + inline ClpPrimalColumnPivot * primalColumnPivot() const { + return primalColumnPivot_; + } + /// Returns true if model looks OK + inline bool goodAccuracy() const { + return (largestPrimalError_ < 1.0e-7 && largestDualError_ < 1.0e-7); + } + /** Return model - updates any scalars */ + void returnModel(ClpSimplex & otherModel); + /** Factorizes using current basis. + solveType - 1 iterating, 0 initial, -1 external + If 10 added then in primal values pass + Return codes are as from ClpFactorization unless initial factorization + when total number of singularities is returned. + Special case is numberRows_+1 -> all slack basis. + */ + int internalFactorize(int solveType); + /// Save data + ClpDataSave saveData() ; + /// Restore data + void restoreData(ClpDataSave saved); + /// Clean up status + void cleanStatus(); + /// Factorizes using current basis. For external use + int factorize(); + /** Computes duals from scratch. If givenDjs then + allows for nonzero basic djs */ + void computeDuals(double * givenDjs); + /// Computes primals from scratch + void computePrimals ( const double * rowActivities, + const double * columnActivities); + /** Adds multiple of a column into an array */ + void add(double * array, + int column, double multiplier) const; + /** + Unpacks one column of the matrix into indexed array + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray) const ; + /** + Unpacks one column of the matrix into indexed array + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray, int sequence) const; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray) ; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray, int sequence); +#ifndef CLP_USER_DRIVEN +protected: +#endif + /** + This does basis housekeeping and does values for in/out variables. + Can also decide to re-factorize + */ + int housekeeping(double objectiveChange); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Primal) */ + void checkPrimalSolution(const double * rowActivities = NULL, + const double * columnActivies = NULL); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Dual) */ + void checkDualSolution(); + /** This sets sum and number of infeasibilities (Dual and Primal) */ + void checkBothSolutions(); + /** If input negative scales objective so maximum <= -value + and returns scale factor used. If positive unscales and also + redoes dual stuff + */ + double scaleObjective(double value); + /// Solve using Dantzig-Wolfe decomposition and maybe in parallel + int solveDW(CoinStructuredModel * model, ClpSolve & options); + /// Solve using Benders decomposition and maybe in parallel + int solveBenders(CoinStructuredModel * model, ClpSolve & options); +public: + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility + or incoming largest infeasibility. + If allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + void setValuesPassAction(double incomingInfeasibility, + double allowedInfeasibility); + /** Get a clean factorization - i.e. throw out singularities + may do more later */ + int cleanFactorization(int ifValuesPass); + //@} + /**@name most useful gets and sets */ + //@{ +public: + /// Initial value for alpha accuracy calculation (-1.0 off) + inline double alphaAccuracy() const { + return alphaAccuracy_; + } + inline void setAlphaAccuracy(double value) { + alphaAccuracy_ = value; + } +public: + /// Objective value + //inline double objectiveValue() const { + //return (objectiveValue_-bestPossibleImprovement_)*optimizationDirection_ - dblParam_[ClpObjOffset]; + //} + /// Set disaster handler + inline void setDisasterHandler(ClpDisasterHandler * handler) { + disasterArea_ = handler; + } + /// Get disaster handler + inline ClpDisasterHandler * disasterHandler() const { + return disasterArea_; + } + /// Large bound value (for complementarity etc) + inline double largeValue() const { + return largeValue_; + } + void setLargeValue( double value) ; + /// Largest error on Ax-b + inline double largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline double largestDualError() const { + return largestDualError_; + } + /// Largest error on Ax-b + inline void setLargestPrimalError(double value) { + largestPrimalError_ = value; + } + /// Largest error on basic duals + inline void setLargestDualError(double value) { + largestDualError_ = value; + } + /// Get zero tolerance + inline double zeroTolerance() const { + return zeroTolerance_;/*factorization_->zeroTolerance();*/ + } + /// Set zero tolerance + inline void setZeroTolerance( double value) { + zeroTolerance_ = value; + } + /// Basic variables pivoting on which rows + inline int * pivotVariable() const { + return pivotVariable_; + } + /// If automatic scaling on + inline bool automaticScaling() const { + return automaticScale_ != 0; + } + inline void setAutomaticScaling(bool onOff) { + automaticScale_ = onOff ? 1 : 0; + } + /// Current dual tolerance + inline double currentDualTolerance() const { + return dualTolerance_; + } + inline void setCurrentDualTolerance(double value) { + dualTolerance_ = value; + } + /// Current primal tolerance + inline double currentPrimalTolerance() const { + return primalTolerance_; + } + inline void setCurrentPrimalTolerance(double value) { + primalTolerance_ = value; + } + /// How many iterative refinements to do + inline int numberRefinements() const { + return numberRefinements_; + } + void setNumberRefinements( int value) ; + /// Alpha (pivot element) for use by classes e.g. steepestedge + inline double alpha() const { + return alpha_; + } + inline void setAlpha(double value) { + alpha_ = value; + } + /// Reduced cost of last incoming for use by classes e.g. steepestedge + inline double dualIn() const { + return dualIn_; + } + /// Set reduced cost of last incoming to force error + inline void setDualIn(double value) { + dualIn_ = value; + } + /// Pivot Row for use by classes e.g. steepestedge + inline int pivotRow() const { + return pivotRow_; + } + inline void setPivotRow(int value) { + pivotRow_ = value; + } + /// value of incoming variable (in Dual) + double valueIncomingDual() const; + //@} + +#ifndef CLP_USER_DRIVEN +protected: +#endif + /**@name protected methods */ + //@{ + /** May change basis and then returns number changed. + Computation of solutions may be overriden by given pi and solution + */ + int gutsOfSolution ( double * givenDuals, + const double * givenPrimals, + bool valuesPass = false); + /// Does most of deletion (0 = all, 1 = most, 2 most + factorization) + void gutsOfDelete(int type); + /// Does most of copying + void gutsOfCopy(const ClpSimplex & rhs); + /** puts in format I like (rowLower,rowUpper) also see StandardMatrix + 1 bit does rows (now and columns), (2 bit does column bounds), 4 bit does objective(s). + 8 bit does solution scaling in + 16 bit does rowArray and columnArray indexed vectors + and makes row copy if wanted, also sets columnStart_ etc + Also creates scaling arrays if needed. It does scaling if needed. + 16 also moves solutions etc in to work arrays + On 16 returns false if problem "bad" i.e. matrix or bounds bad + If startFinishOptions is -1 then called by user in getSolution + so do arrays but keep pivotVariable_ + */ + bool createRim(int what, bool makeRowCopy = false, int startFinishOptions = 0); + /// Does rows and columns + void createRim1(bool initial); + /// Does objective + void createRim4(bool initial); + /// Does rows and columns and objective + void createRim5(bool initial); + /** releases above arrays and does solution scaling out. May also + get rid of factorization data - + 0 get rid of nothing, 1 get rid of arrays, 2 also factorization + */ + void deleteRim(int getRidOfFactorizationData = 2); + /// Sanity check on input rim data (after scaling) - returns true if okay + bool sanityCheck(); + //@} +public: + /**@name public methods */ + //@{ + /** Return row or column sections - not as much needed as it + once was. These just map into single arrays */ + inline double * solutionRegion(int section) const { + if (!section) return rowActivityWork_; + else return columnActivityWork_; + } + inline double * djRegion(int section) const { + if (!section) return rowReducedCost_; + else return reducedCostWork_; + } + inline double * lowerRegion(int section) const { + if (!section) return rowLowerWork_; + else return columnLowerWork_; + } + inline double * upperRegion(int section) const { + if (!section) return rowUpperWork_; + else return columnUpperWork_; + } + inline double * costRegion(int section) const { + if (!section) return rowObjectiveWork_; + else return objectiveWork_; + } + /// Return region as single array + inline double * solutionRegion() const { + return solution_; + } + inline double * djRegion() const { + return dj_; + } + inline double * lowerRegion() const { + return lower_; + } + inline double * upperRegion() const { + return upper_; + } + inline double * costRegion() const { + return cost_; + } + inline Status getStatus(int sequence) const { + return static_cast<Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + /// Start or reset using maximumRows_ and Columns_ - true if change + bool startPermanentArrays(); + /** Normally the first factorization does sparse coding because + the factorization could be singular. This allows initial dense + factorization when it is known to be safe + */ + void setInitialDenseFactorization(bool onOff); + bool initialDenseFactorization() const; + /** Return sequence In or Out */ + inline int sequenceIn() const { + return sequenceIn_; + } + inline int sequenceOut() const { + return sequenceOut_; + } + /** Set sequenceIn or Out */ + inline void setSequenceIn(int sequence) { + sequenceIn_ = sequence; + } + inline void setSequenceOut(int sequence) { + sequenceOut_ = sequence; + } + /** Return direction In or Out */ + inline int directionIn() const { + return directionIn_; + } + inline int directionOut() const { + return directionOut_; + } + /** Set directionIn or Out */ + inline void setDirectionIn(int direction) { + directionIn_ = direction; + } + inline void setDirectionOut(int direction) { + directionOut_ = direction; + } + /// Value of Out variable + inline double valueOut() const { + return valueOut_; + } + /// Set value of out variable + inline void setValueOut(double value) { + valueOut_ = value; + } + /// Dual value of Out variable + inline double dualOut() const { + return dualOut_; + } + /// Set dual value of out variable + inline void setDualOut(double value) { + dualOut_ = value; + } + /// Set lower of out variable + inline void setLowerOut(double value) { + lowerOut_ = value; + } + /// Set upper of out variable + inline void setUpperOut(double value) { + upperOut_ = value; + } + /// Set theta of out variable + inline void setTheta(double value) { + theta_ = value; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Return row or column values + inline double solution(int sequence) { + return solution_[sequence]; + } + /// Return address of row or column values + inline double & solutionAddress(int sequence) { + return solution_[sequence]; + } + inline double reducedCost(int sequence) { + return dj_[sequence]; + } + inline double & reducedCostAddress(int sequence) { + return dj_[sequence]; + } + inline double lower(int sequence) { + return lower_[sequence]; + } + /// Return address of row or column lower bound + inline double & lowerAddress(int sequence) { + return lower_[sequence]; + } + inline double upper(int sequence) { + return upper_[sequence]; + } + /// Return address of row or column upper bound + inline double & upperAddress(int sequence) { + return upper_[sequence]; + } + inline double cost(int sequence) { + return cost_[sequence]; + } + /// Return address of row or column cost + inline double & costAddress(int sequence) { + return cost_[sequence]; + } + /// Return original lower bound + inline double originalLower(int iSequence) const { + if (iSequence < numberColumns_) return columnLower_[iSequence]; + else + return rowLower_[iSequence-numberColumns_]; + } + /// Return original lower bound + inline double originalUpper(int iSequence) const { + if (iSequence < numberColumns_) return columnUpper_[iSequence]; + else + return rowUpper_[iSequence-numberColumns_]; + } + /// Theta (pivot change) + inline double theta() const { + return theta_; + } + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + inline double bestPossibleImprovement() const { + return bestPossibleImprovement_; + } + /// Return pointer to details of costs + inline ClpNonLinearCost * nonLinearCost() const { + return nonLinearCost_; + } + /** Return more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - if factorization kept can still declare optimal at once + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + */ + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - no free or superBasic variables + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + 1048576 bit - don't perturb even if long time + 2097152 bit - no primal in fastDual2 if feasible + 4194304 bit - tolerances have been changed by code + 8388608 bit - tolerances are dynamic (at first) + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + //@} + /**@name status methods */ + //@{ + inline void setFakeBound(int sequence, FakeBound fakeBound) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~24); + st_byte = static_cast<unsigned char>(st_byte | (fakeBound << 3)); + } + inline FakeBound getFakeBound(int sequence) const { + return static_cast<FakeBound> ((status_[sequence] >> 3) & 3); + } + inline void setRowStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence+numberColumns_]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + inline Status getRowStatus(int sequence) const { + return static_cast<Status> (status_[sequence+numberColumns_] & 7); + } + inline void setColumnStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + inline Status getColumnStatus(int sequence) const { + return static_cast<Status> (status_[sequence] & 7); + } + inline void setPivoted( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 32); + } + inline void clearPivoted( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~32); + } + inline bool pivoted(int sequence) const { + return (((status_[sequence] >> 5) & 1) != 0); + } + /// To flag a variable (not inline to allow for column generation) + void setFlagged( int sequence); + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say row active in primal pivot row choice + inline void setActive( int iRow) { + status_[iRow] = static_cast<unsigned char>(status_[iRow] | 128); + } + inline void clearActive( int iRow) { + status_[iRow] = static_cast<unsigned char>(status_[iRow] & ~128); + } + inline bool active(int iRow) const { + return ((status_[iRow] & 128) != 0); + } + /// To say perturbed + inline void setPerturbed( int iSequence) { + status_[iSequence] = static_cast<unsigned char>(status_[iSequence] | 128); + } + inline void clearPerturbed( int iSequence) { + status_[iSequence] = static_cast<unsigned char>(status_[iSequence] & ~128); + } + inline bool perturbed(int iSequence) const { + return ((status_[iSequence] & 128) != 0); + } + /** Set up status array (can be used by OsiClp). + Also can be used to set up all slack basis */ + void createStatus() ; + /** Sets up all slack basis and resets solution to + as it was after initial load or readMps */ + void allSlackBasis(bool resetSolution = false); + + /// So we know when to be cautious + inline int lastBadIteration() const { + return lastBadIteration_; + } + /// Set so we know when to be cautious + inline void setLastBadIteration(int value) { + lastBadIteration_=value; + } + /// Progress flag - at present 0 bit says artificials out + inline int progressFlag() const { + return (progressFlag_ & 3); + } + /// For dealing with all issues of cycling etc + inline ClpSimplexProgress * progress() + { return &progress_;} + /// Force re-factorization early value + inline int forceFactorization() const { + return forceFactorization_ ; + } + /// Force re-factorization early + inline void forceFactorization(int value) { + forceFactorization_ = value; + } + /// Raw objective value (so always minimize in primal) + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// Compute objective value from solution and put in objectiveValue_ + void computeObjectiveValue(bool useWorkingSolution = false); + /// Compute minimization objective value from internal solution without perturbation + double computeInternalObjectiveValue(); + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + inline int numberExtraRows() const { + return numberExtraRows_; + } + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + inline int maximumBasic() const { + return maximumBasic_; + } + /// Iteration when we entered dual or primal + inline int baseIteration() const { + return baseIteration_; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, bool defaultFactor = false); + /// Gets clean and emptyish factorization + ClpFactorization * getEmptyFactorization(); + /// May delete or may make clean and emptyish factorization + void setEmptyFactorization(); + /// Move status and solution across + void moveInfo(const ClpSimplex & rhs, bool justStatus = false); + //@} + + ///@name Basis handling + // These are only to be used using startFinishOptions (ClpSimplexDual, ClpSimplexPrimal) + // *** At present only without scaling + // *** Slacks havve -1.0 element (so == row activity) - take care + ///Get a row of the tableau (slack part in slack if not NULL) + void getBInvARow(int row, double* z, double * slack = NULL); + + ///Get a row of the basis inverse + void getBInvRow(int row, double* z); + + ///Get a column of the tableau + void getBInvACol(int col, double* vec); + + ///Get a column of the basis inverse + void getBInvCol(int col, double* vec); + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + void getBasics(int* index); + + //@} + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double newlower, double newupper ) { + setColumnBounds(elementIndex, newlower, newupper); + } + + /** Set the bounds on a number of columns simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + double bestPossibleImprovement_; + /// Zero tolerance + double zeroTolerance_; + /// Sequence of worst (-1 if feasible) + int columnPrimalSequence_; + /// Sequence of worst (-1 if feasible) + int rowPrimalSequence_; + /// "Best" objective value + double bestObjectiveValue_; + /// More special options - see set for details + int moreSpecialOptions_; + /// Iteration when we entered dual or primal + int baseIteration_; + /// Primal tolerance needed to make dual feasible (<largeTolerance) + double primalToleranceToGetOptimal_; + /// Large bound value (for complementarity etc) + double largeValue_; + /// Largest error on Ax-b + double largestPrimalError_; + /// Largest error on basic duals + double largestDualError_; + /// For computing whether to re-factorize + double alphaAccuracy_; + /// Dual bound + double dualBound_; + /// Alpha (pivot element) + double alpha_; + /// Theta (pivot change) + double theta_; + /// Lower Bound on In variable + double lowerIn_; + /// Value of In variable + double valueIn_; + /// Upper Bound on In variable + double upperIn_; + /// Reduced cost of In variable + double dualIn_; + /// Lower Bound on Out variable + double lowerOut_; + /// Value of Out variable + double valueOut_; + /// Upper Bound on Out variable + double upperOut_; + /// Infeasibility (dual) or ? (primal) of Out variable + double dualOut_; + /// Current dual tolerance for algorithm + double dualTolerance_; + /// Current primal tolerance for algorithm + double primalTolerance_; + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Weight assigned to being infeasible in primal + double infeasibilityCost_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Acceptable pivot value just after factorization + double acceptablePivot_; + /// Minimum primal tolerance + double minimumPrimalTolerance_; + /// Last few infeasibilities +#define CLP_INFEAS_SAVE 5 + double averageInfeasibility_[CLP_INFEAS_SAVE]; + /// Working copy of lower bounds (Owner of arrays below) + double * lower_; + /// Row lower bounds - working copy + double * rowLowerWork_; + /// Column lower bounds - working copy + double * columnLowerWork_; + /// Working copy of upper bounds (Owner of arrays below) + double * upper_; + /// Row upper bounds - working copy + double * rowUpperWork_; + /// Column upper bounds - working copy + double * columnUpperWork_; + /// Working copy of objective (Owner of arrays below) + double * cost_; + /// Row objective - working copy + double * rowObjectiveWork_; + /// Column objective - working copy + double * objectiveWork_; + /// Useful row length arrays + CoinIndexedVector * rowArray_[6]; + /// Useful column length arrays + CoinIndexedVector * columnArray_[6]; + /// Sequence of In variable + int sequenceIn_; + /// Direction of In, 1 going up, -1 going down, 0 not a clude + int directionIn_; + /// Sequence of Out variable + int sequenceOut_; + /// Direction of Out, 1 to upper bound, -1 to lower bound, 0 - superbasic + int directionOut_; + /// Pivot Row + int pivotRow_; + /// Last good iteration (immediately after a re-factorization) + int lastGoodIteration_; + /// Working copy of reduced costs (Owner of arrays below) + double * dj_; + /// Reduced costs of slacks not same as duals (or - duals) + double * rowReducedCost_; + /// Possible scaled reduced costs + double * reducedCostWork_; + /// Working copy of primal solution (Owner of arrays below) + double * solution_; + /// Row activities - working copy + double * rowActivityWork_; + /// Column activities - working copy + double * columnActivityWork_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of dual infeasibilities (without free) + int numberDualInfeasibilitiesWithoutFree_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /// How many iterative refinements to do + int numberRefinements_; + /// dual row pivot choice + ClpDualRowPivot * dualRowPivot_; + /// primal column pivot choice + ClpPrimalColumnPivot * primalColumnPivot_; + /// Basic variables pivoting on which rows + int * pivotVariable_; + /// factorization + ClpFactorization * factorization_; + /// Saved version of solution + double * savedSolution_; + /// Number of times code has tentatively thought optimal + int numberTimesOptimal_; + /// Disaster handler + ClpDisasterHandler * disasterArea_; + /// If change has been made (first attempt at stopping looping) + int changeMade_; + /// Algorithm >0 == Primal, <0 == Dual + int algorithm_; + /** Now for some reliability aids + This forces re-factorization early */ + int forceFactorization_; + /** Perturbation: + -50 to +50 - perturb by this power of ten (-6 sounds good) + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + */ + int perturbation_; + /// Saved status regions + unsigned char * saveStatus_; + /** Very wasteful way of dealing with infeasibilities in primal. + However it will allow non-linearities and use of dual + analysis. If it doesn't work it can easily be replaced. + */ + ClpNonLinearCost * nonLinearCost_; + /// So we know when to be cautious + int lastBadIteration_; + /// So we know when to open up again + int lastFlaggedIteration_; + /// Can be used for count of fake bounds (dual) or fake costs (primal) + int numberFake_; + /// Can be used for count of changed costs (dual) or changed bounds (primal) + int numberChanged_; + /// Progress flag - at present 0 bit says artificials out, 1 free in + int progressFlag_; + /// First free/super-basic variable (-1 if none) + int firstFree_; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + int numberExtraRows_; + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + int maximumBasic_; + /// If may skip final factorize then allow up to this pivots (default 20) + int dontFactorizePivots_; + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility. + if allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + double incomingInfeasibility_; + double allowedInfeasibility_; + /// Automatic scaling of objective and rhs and bounds + int automaticScale_; + /// Maximum perturbation array size (take out when code rewritten) + int maximumPerturbationSize_; + /// Perturbation array (maximumPerturbationSize_) + double * perturbationArray_; + /// A copy of model with certain state - normally without cuts + ClpSimplex * baseModel_; + /// For dealing with all issues of cycling etc + ClpSimplexProgress progress_; +#ifdef ABC_INHERIT + AbcSimplex * abcSimplex_; +#define CLP_ABC_WANTED 1 +#define CLP_ABC_WANTED_PARALLEL 2 +#define CLP_ABC_FULL_DONE 8 + // bits 256,512,1024 for crash +#endif +#define CLP_ABC_BEEN_FEASIBLE 65536 + int abcState_; + /// Number of degenerate pivots since last perturbed + int numberDegeneratePivots_; +public: + /// Spare int array for passing information [0]!=0 switches on + mutable int spareIntArray_[4]; + /// Spare double array for passing information [0]!=0 switches on + mutable double spareDoubleArray_[4]; +protected: + /// Allow OsiClp certain perks + friend class OsiClpSolverInterface; + /// And OsiCLP + friend class OsiCLPSolverInterface; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpSimplex class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpSimplexUnitTest(const std::string & mpsDir); + +// For Devex stuff +#define DEVEX_TRY_NORM 1.0e-4 +#define DEVEX_ADD_ONE 1.0 +#if defined(ABC_INHERIT) || defined(CBC_THREAD) || defined(THREADS_IN_ANALYZE) +// Use pthreads +#include <pthread.h> +typedef struct { + double result; + //const CoinIndexedVector * constVector; // can get rid of + //CoinIndexedVector * vectors[2]; // can get rid of + void * extraInfo; + void * extraInfo2; + int status; + int stuff[4]; +} CoinThreadInfo; +class CoinPthreadStuff { +public: + /**@name Constructors and destructor and copy */ + //@{ + /** Main constructor + */ + CoinPthreadStuff (int numberThreads=0, + void * parallelManager(void * stuff)=NULL); + /// Assignment operator. This copies the data + CoinPthreadStuff & operator=(const CoinPthreadStuff & rhs); + /// Destructor + ~CoinPthreadStuff ( ); + /// set stop start + inline void setStopStart(int value) + { stopStart_=value;} +#ifndef NUMBER_THREADS +#define NUMBER_THREADS 8 +#endif + // For waking up thread + inline pthread_mutex_t * mutexPointer(int which,int thread=0) + { return mutex_+which+3*thread;} +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + inline pthread_barrier_t * barrierPointer() + { return &barrier_;} +#endif + inline int whichLocked(int thread=0) const + { return locked_[thread];} + inline CoinThreadInfo * threadInfoPointer(int thread=0) + { return threadInfo_+thread;} + void startParallelTask(int type,int iThread,void * info=NULL); + int waitParallelTask(int type, int & iThread,bool allowIdle); + void waitAllTasks(); + /// so thread can find out which one it is + int whichThread() const; + void sayIdle(int iThread); + //void startThreads(int numberThreads); + //void stopThreads(); + // For waking up thread + pthread_mutex_t mutex_[3*(NUMBER_THREADS+1)]; +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + pthread_barrier_t barrier_; +#endif + CoinThreadInfo threadInfo_[NUMBER_THREADS+1]; + pthread_t abcThread_[NUMBER_THREADS+1]; + int locked_[NUMBER_THREADS+1]; + int stopStart_; + int numberThreads_; +}; +void * clp_parallelManager(void * stuff); +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpSimplexDual.hpp b/thirdparty/linux/include/coin/coin/ClpSimplexDual.hpp new file mode 100644 index 0000000..77cc577 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSimplexDual.hpp @@ -0,0 +1,300 @@ +/* $Id: ClpSimplexDual.hpp 1761 2011-07-06 16:06:24Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexDual_H +#define ClpSimplexDual_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the dual simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexDual : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Dual algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of updatedDualBound_ being + given to getting dual feasible. In this version I have used the + idea that this weight can be thought of as a fake bound. If the + distance between the lower and upper bounds on a variable is less + than the feasibility weight then we are always better off flipping + to other bound to make dual feasible. If the distance is greater + then we make up a fake bound updatedDualBound_ away from one bound. + If we end up optimal or primal infeasible, we check to see if + bounds okay. If so we have finished, if not we increase updatedDualBound_ + and continue (after checking if unbounded). I am undecided about + free variables - there is coding but I am not sure about it. At + present I put them in basis anyway. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find outgoing variable for + Dantzig row choice. For steepest edge we keep an updated list + of infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and some + of what I think is the dual analog of Gill et al. + I am still not sure of the exact details. + + The flow of dual is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by flipping variables so + dual feasible. If looks finished check fake dual bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot row (outgoing variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot row in tableau + + Choose incoming column. If we don't find one then we look + primal infeasible so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find incoming column, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve flipping variables to stay + dual feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot out option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int dual(int ifValuesPass, int startFinishOptions = 0); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// This does first part of StrongBranching + ClpFactorization * setupForStrongBranching(char * arrays, int numberRows, + int numberColumns, bool solveLp = false); + /// This cleans up after strong branching + void cleanupAfterStrongBranching(ClpFactorization * factorization); + //@} + + /**@name Functions used in dual */ + //@{ + /** This has the flow between re-factorizations + Broken out for clarity and will be used by strong branching + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + + If givenPi not NULL then in values pass + */ + int whileIterating(double * & givenPi, int ifValuesPass); + /** The duals are updated by the given arrays. + Returns number of infeasibilities. + After rowArray and columnArray will just have those which + have been flipped. + Variables may be flipped between bounds to stay dual feasible. + The output vector has movement of primal + solution (row length array) */ + int updateDualsInDual(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * outputArray, + double theta, + double & objectiveChange, + bool fullRecompute); + /** The duals are updated by the given arrays. + This is in values pass - so no changes to primal is made + */ + void updateDualsInValuesPass(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double theta); + /** While updateDualsInDual sees what effect is of flip + this does actual flipping. + */ + void flipBounds(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray); + /** + Row array has row part of pivot row + Column array has column part. + This chooses pivot column. + Spare arrays are used to save pivots which will go infeasible + We will check for basic so spare array will never overflow. + If necessary will modify costs + For speed, we may need to go to a bucket approach when many + variables are being flipped. + Returns best possible pivot value + */ + double dualColumn(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + CoinIndexedVector * spareArray2, + double accpetablePivot, + CoinBigIndex * dubiousWeights); + /// Does first bit of dualColumn + int dualColumn0(const CoinIndexedVector * rowArray, + const CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + double acceptablePivot, + double & upperReturn, double &bestReturn, double & badFree); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in dual values pass + if sequenceIn==sequenceOut can change dual on chosen row and leave variable in basis + */ + void checkPossibleValuesMove(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in branch and bound cleanup + If sequenceIn_ < 0 then can't do anything + */ + void checkPossibleCleanup(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + This sees if we can move duals in dual values pass. + This is done before any pivoting + */ + void doEasyOnesInValuesPass(double * givenReducedCosts); + /** + Chooses dual pivot row + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first rows we look at + + If alreadyChosen >=0 then in values pass and that row has been + selected + */ + void dualRow(int alreadyChosen); + /** Checks if any fake bounds active - if so returns number and modifies + updatedDualBound_ and everything. + Free variables will be left as free + Returns number of bounds changed if >=0 + Returns -1 if not initialize and no effect + Fills in changeVector which can be used to see if unbounded + and cost of change vector + If 2 sets to original (just changed) + */ + int changeBounds(int initialize, CoinIndexedVector * outputArray, + double & changeCost); + /** As changeBounds but just changes new bounds for a single variable. + Returns true if change */ + bool changeBound( int iSequence); + /// Restores bound to original bound + void originalBound(int iSequence); + /** Checks if tentative optimal actually means unbounded in dual + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInDual(int & lastCleaned, int type, + double * givenDjs, ClpDataSave & saveData, + int ifValuesPass); + /** Perturbs problem (method depends on perturbation()) + returns nonzero if should go to dual */ + int perturb(); + /** Fast iterations. Misses out a lot of initialization. + Normally stops on maximum iterations, first re-factorization + or tentative optimum. If looks interesting then continues as + normal. Returns 0 if finished properly, 1 otherwise. + */ + int fastDual(bool alwaysFinish = false); + /** Checks number of variables at fake bounds. This is used by fastDual + so can exit gracefully before end */ + int numberAtFakeBound(); + + /** Pivot in a variable and choose an outgoing one. Assumes dual + feasible - will not go through a reduced cost. Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int pivotResultPart1(); + /** Get next free , -1 if none */ + int nextSuperBasic(); + /** Startup part of dual (may be extended to other algorithms) + returns 0 if good, 1 if bad */ + int startupSolve(int ifValuesPass, double * saveDuals, int startFinishOptions); + void finishSolve(int startFinishOptions); + void gutsOfDual(int ifValuesPass, double * & saveDuals, int initialStatus, + ClpDataSave & saveData); + //int dual2(int ifValuesPass,int startFinishOptions=0); + void resetFakeBounds(int type); + + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpSimplexNonlinear.hpp b/thirdparty/linux/include/coin/coin/ClpSimplexNonlinear.hpp new file mode 100644 index 0000000..6c1088b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSimplexNonlinear.hpp @@ -0,0 +1,117 @@ +/* $Id: ClpSimplexNonlinear.hpp 2025 2014-03-19 12:49:55Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexNonlinear_H +#define ClpSimplexNonlinear_H + +class ClpNonlinearInfo; +class ClpQuadraticObjective; +class ClpConstraint; + +#include "ClpSimplexPrimal.hpp" + +/** This solves non-linear LPs using the primal simplex method + + It inherits from ClpSimplexPrimal. It has no data of its own and + is never created - only cast from a ClpSimplexPrimal object at algorithm time. + If needed create new class and pass around + +*/ + +class ClpSimplexNonlinear : public ClpSimplexPrimal { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithms for reduced gradient + At present we have two algorithms: + + */ + /// A reduced gradient method. + int primal(); + /** Primal algorithm for quadratic + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + */ + int primalSLP(int numberPasses, double deltaTolerance, + int otherOptions=0); + /// May use a cut approach for solving any LP + int primalDualCuts(char * rowsIn, int startUp, int algorithm); + /** Primal algorithm for nonlinear constraints + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + + */ + int primalSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + + /** Creates direction vector. note longArray is long enough + for rows and columns. If numberNonBasic 0 then is updated + otherwise mode is ignored and those are used. + Norms are only for those > 1.0e3*dualTolerance + If mode is nonzero then just largest dj */ + void directionVector (CoinIndexedVector * longArray, + CoinIndexedVector * spare1, CoinIndexedVector * spare2, + int mode, + double & normFlagged, double & normUnflagged, + int & numberNonBasic); + /// Main part. + int whileIterating (int & pivotMode); + /** + longArray has direction + pivotMode - + 0 - use all dual infeasible variables + 1 - largest dj + while >= 10 trying startup phase + Returns 0 - can do normal iteration (basis change) + 1 - no basis change + 2 - if wants singleton + 3 - if time to re-factorize + If sequenceIn_ >=0 then that will be incoming variable + */ + int pivotColumn(CoinIndexedVector * longArray, + CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spare, + int & pivotMode, + double & solutionError, + double * array1); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + double & bestObjectiveWhenFlagged); + /** Do last half of an iteration. + Return codes + Reasons to come out normal mode + -1 normal + -2 factorize now - good iteration + -3 slight inaccuracy - refactorize - iteration done + -4 inaccuracy - refactorize - no iteration + -5 something flagged - go round again + +2 looks unbounded + +3 max iterations (iteration done) + + */ + int pivotNonlinearResult(); + //@} + +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/ClpSimplexOther.hpp b/thirdparty/linux/include/coin/coin/ClpSimplexOther.hpp new file mode 100644 index 0000000..c5014ec --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSimplexOther.hpp @@ -0,0 +1,277 @@ +/* $Id: ClpSimplexOther.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexOther_H +#define ClpSimplexOther_H + +#include "ClpSimplex.hpp" + +/** This is for Simplex stuff which is neither dual nor primal + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexOther : public ClpSimplex { + +public: + + /**@name Methods */ + //@{ + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + When here - guaranteed optimal + */ + void dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + When here - guaranteed optimal + */ + void primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + and similarly for objective. + It starts at startingTheta and returns ending theta in endingTheta. + If reportIncrement 0.0 it will report on any movement + If reportIncrement >0.0 it will report at startingTheta+k*reportIncrement. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, double reportIncrement, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs, + const double * changeObjective); + /** Version of parametrics which reads from file + See CbcClpParam.cpp for details of format + Returns -2 if unable to open file */ + int parametrics(const char * dataFile); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + It starts at startingTheta and returns ending theta in endingTheta. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Event handler may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs); + int parametricsObj(double startingTheta, double & endingTheta, + const double * changeObjective); + /// Finds best possible pivot + double bestPivot(bool justColumns=false); + typedef struct { + double startingTheta; + double endingTheta; + double maxTheta; + double acceptableMaxTheta; // if this far then within tolerances + double * lowerChange; // full array of lower bound changes + int * lowerList; // list of lower bound changes + double * upperChange; // full array of upper bound changes + int * upperList; // list of upper bound changes + char * markDone; // mark which ones looked at + int * backwardBasic; // from sequence to pivot row + int * lowerActive; + double * lowerGap; + double * lowerCoefficient; + int * upperActive; + double * upperGap; + double * upperCoefficient; + int unscaledChangesOffset; + bool firstIteration; // so can update rhs for accuracy + } parametricsData; + +private: + /** Parametrics - inner loop + This first attempt is when reportIncrement non zero and may + not report endingTheta correctly + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + */ + int parametricsLoop(parametricsData & paramData, double reportIncrement, + const double * changeLower, const double * changeUpper, + const double * changeObjective, ClpDataSave & data, + bool canTryQuick); + int parametricsLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + int parametricsObjLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + /** Refactorizes if necessary + Checks if finished. Updates status. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInParametrics(int type, ClpDataSave & saveData); + void statusOfProblemInParametricsObj(int type, ClpDataSave & saveData); + /** This has the flow between re-factorizations + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + */ + int whileIterating(parametricsData & paramData, double reportIncrement, + const double * changeObjective); + /** Computes next theta and says if objective or bounds (0= bounds, 1 objective, -1 none). + theta is in theta_. + type 1 bounds, 2 objective, 3 both. + */ + int nextTheta(int type, double maxTheta, parametricsData & paramData, + const double * changeObjective); + int whileIteratingObj(parametricsData & paramData); + int nextThetaObj(double maxTheta, parametricsData & paramData); + /// Restores bound to original bound + void originalBound(int iSequence, double theta, const double * changeLower, + const double * changeUpper); + /// Compute new rowLower_ etc (return negative if infeasible - otherwise largest change) + double computeRhsEtc(parametricsData & paramData); + /// Redo lower_ from rowLower_ etc + void redoInternalArrays(); + /** + Row array has row part of pivot row + Column array has column part. + This is used in dual ranging + */ + void checkDualRatios(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double & costIncrease, int & sequenceIncrease, double & alphaIncrease, + double & costDecrease, int & sequenceDecrease, double & alphaDecrease); + /** + Row array has pivot column + This is used in primal ranging + */ + void checkPrimalRatios(CoinIndexedVector * rowArray, + int direction); + /// Returns new value of whichOther when whichIn enters basis + double primalRanging1(int whichIn, int whichOther); + +public: + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex (later) + </ul> + + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /// Read a basis from the given filename + int readBasis(const char *filename); + /** Creates dual of a problem if looks plausible + (defaults will always create model) + fractionRowRanges is fraction of rows allowed to have ranges + fractionColumnRanges is fraction of columns allowed to have ranges + */ + ClpSimplex * dualOfModel(double fractionRowRanges = 1.0, double fractionColumnRanges = 1.0) const; + /** Restores solution from dualized problem + non-zero return code indicates minor problems + */ + int restoreFromDual(const ClpSimplex * dualProblem, + bool checkAccuracy=false); + /** Sets solution in dualized problem + non-zero return code indicates minor problems + */ + int setInDual(ClpSimplex * dualProblem); + /** Does very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + ClpSimplex * crunch(double * rhs, int * whichRows, int * whichColumns, + int & nBound, bool moreBounds = false, bool tightenBounds = false); + /** After very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + void afterCrunch(const ClpSimplex & small, + const int * whichRows, const int * whichColumns, + int nBound); + /** Returns gub version of model or NULL + whichRows has to be numberRows + whichColumns has to be numberRows+numberColumns */ + ClpSimplex * gubVersion(int * whichRows, int * whichColumns, + int neededGub, + int factorizationFrequency=50); + /// Sets basis from original + void setGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns); + /// Restores basis to original + void getGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns) const; + /// Quick try at cleaning up duals if postsolve gets wrong + void cleanupAfterPostsolve(); + /** Tightens integer bounds - returns number tightened or -1 if infeasible + */ + int tightenIntegerBounds(double * rhsSpace); + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput, + double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement, int reConstruct = -1) const; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/ClpSimplexPrimal.hpp b/thirdparty/linux/include/coin/coin/ClpSimplexPrimal.hpp new file mode 100644 index 0000000..d78e54e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSimplexPrimal.hpp @@ -0,0 +1,244 @@ +/* $Id: ClpSimplexPrimal.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexPrimal_H +#define ClpSimplexPrimal_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the primal simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexPrimal : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of infeasibilityCost_ being + given to getting primal feasible. In this version I have tried to + be clever in a stupid way. The idea of fake bounds in dual + seems to work so the primal analogue would be that of getting + bounds on reduced costs (by a presolve approach) and using + these for being above or below feasible region. I decided to waste + memory and keep these explicitly. This allows for non-linear + costs! I have not tested non-linear costs but will be glad + to do something if a reasonable example is provided. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find incoming variable for + Dantzig row choice. For steepest edge we keep an updated list + of dual infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. This method has not been coded. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and which was + extended by Gill et al. I am still not sure whether we will also + need explicit perturbation. + + The flow of primal is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by changing bounds so + primal feasible. If looks finished check fake primal bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot column (incoming variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot column in tableau + + Choose outgoing row. If we don't find one then we look + primal unbounded so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find outgoing row, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve changing bounds on + variables to stay primal feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot in option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + //@} + + /**@name For advanced users */ + //@{ + /// Do not change infeasibility cost and always say optimal + void alwaysOptimal(bool onOff); + bool alwaysOptimal() const; + /** Normally outgoing variables can go out to slightly negative + values (but within tolerance) - this is to help stability and + and degeneracy. This can be switched off + */ + void exactOutgoing(bool onOff); + bool exactOutgoing() const; + //@} + + /**@name Functions used in primal */ + //@{ + /** This has the flow between re-factorizations + + Returns a code to say where decision to exit was made + Problem status set to: + + -2 re-factorize + -4 Looks optimal/infeasible + -5 Looks unbounded + +3 max iterations + + valuesOption has original value of valuesPass + */ + int whileIterating(int valuesOption); + + /** Do last half of an iteration. This is split out so people can + force incoming variable. If solveType_ is 2 then this may + re-factorize while normally it would exit to re-factorize. + Return codes + Reasons to come out (normal mode/user mode): + -1 normal + -2 factorize now - good iteration/ NA + -3 slight inaccuracy - refactorize - iteration done/ same but factor done + -4 inaccuracy - refactorize - no iteration/ NA + -5 something flagged - go round again/ pivot not possible + +2 looks unbounded + +3 max iterations (iteration done) + + With solveType_ ==2 this should + Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ + */ + int pivotResult(int ifValuesPass = 0); + + + /** The primals are updated by the given array. + Returns number of infeasibilities. + After rowArray will have cost changes for use next iteration + */ + int updatePrimalsInPrimal(CoinIndexedVector * rowArray, + double theta, + double & objectiveChange, + int valuesPass); + /** + Row array has pivot column + This chooses pivot row. + Rhs array is used for distance to next bound (for speed) + For speed, we may need to go to a bucket approach when many + variables go through bounds + If valuesPass non-zero then compute dj for direction + */ + void primalRow(CoinIndexedVector * rowArray, + CoinIndexedVector * rhsArray, + CoinIndexedVector * spareArray, + int valuesPass); + /** + Chooses primal pivot column + updateArray has cost updates (also use pivotRow_ from last iteration) + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first columns we look at + */ + void primalColumn(CoinIndexedVector * updateArray, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /** Checks if tentative optimal actually means unbounded in primal + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + saveModel is normally NULL but may not be if doing Sprint + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + int ifValuesPass, + ClpSimplex * saveModel = NULL); + /// Perturbs problem (method depends on perturbation()) + void perturb(int type); + /// Take off effect of perturbation and say whether to try dual + bool unPerturb(); + /// Unflag all variables and return number unflagged + int unflag(); + /** Get next superbasic -1 if none, + Normal type is 1 + If type is 3 then initializes sorted list + if 2 uses list. + */ + int nextSuperBasic(int superBasicType, CoinIndexedVector * columnArray); + + /// Create primal ray + void primalRay(CoinIndexedVector * rowArray); + /// Clears all bits and clears rowArray[1] etc + void clearAll(); + + /// Sort of lexicographic resolve + int lexSolve(); + + //@} +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/ClpSolve.hpp b/thirdparty/linux/include/coin/coin/ClpSolve.hpp new file mode 100644 index 0000000..280e33d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ClpSolve.hpp @@ -0,0 +1,446 @@ +/* $Id: ClpSolve.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSolve_H +#define ClpSolve_H + +/** + This is a very simple class to guide algorithms. It is used to tidy up + passing parameters to initialSolve and maybe for output from that + +*/ + +class ClpSolve { + +public: + + /** enums for solve function */ + enum SolveType { + useDual = 0, + usePrimal, + usePrimalorSprint, + useBarrier, + useBarrierNoCross, + automatic, + tryDantzigWolfe, + tryBenders, + notImplemented + }; + enum PresolveType { + presolveOn = 0, + presolveOff, + presolveNumber, + presolveNumberCost + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSolve ( ); + /// Constructor when you really know what you are doing + ClpSolve ( SolveType method, PresolveType presolveType, + int numberPasses, int options[6], + int extraInfo[6], int independentOptions[3]); + /// Generates code for above constructor + void generateCpp(FILE * fp); + /// Copy constructor. + ClpSolve(const ClpSolve &); + /// Assignment operator. This copies the data + ClpSolve & operator=(const ClpSolve & rhs); + /// Destructor + ~ClpSolve ( ); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Special options - bits + 0 4 - use crash (default allslack in dual, idiot in primal) + 8 - all slack basis in primal + 2 16 - switch off interrupt handling + 3 32 - do not try and make plus minus one matrix + 64 - do not use sprint even if problem looks good + */ + /** which translation is: + which: + 0 - startup in Dual (nothing if basis exists).: + 0 - no basis + 1 - crash + 2 - use initiative about idiot! but no crash + 1 - startup in Primal (nothing if basis exists): + 0 - use initiative + 1 - use crash + 2 - use idiot and look at further info + 3 - use sprint and look at further info + 4 - use all slack + 5 - use initiative but no idiot + 6 - use initiative but no sprint + 7 - use initiative but no crash + 8 - do allslack or idiot + 9 - do allslack or sprint + 10 - slp before + 11 - no nothing and primal(0) + 2 - interrupt handling - 0 yes, 1 no (for threadsafe) + 3 - whether to make +- 1matrix - 0 yes, 1 no + 4 - for barrier + 0 - dense cholesky + 1 - Wssmp allowing some long columns + 2 - Wssmp not allowing long columns + 3 - Wssmp using KKT + 4 - Using Florida ordering + 8 - bit set to do scaling + 16 - set to be aggressive with gamma/delta? + 32 - Use KKT + 5 - for presolve + 1 - switch off dual stuff + 6 - extra switches + + */ + void setSpecialOption(int which, int value, int extraInfo = -1); + int getSpecialOption(int which) const; + + /// Solve types + void setSolveType(SolveType method, int extraInfo = -1); + SolveType getSolveType(); + + // Presolve types + void setPresolveType(PresolveType amount, int extraInfo = -1); + PresolveType getPresolveType(); + int getPresolvePasses() const; + /// Extra info for idiot (or sprint) + int getExtraInfo(int which) const; + /** Say to return at once if infeasible, + default is to solve */ + void setInfeasibleReturn(bool trueFalse); + inline bool infeasibleReturn() const { + return independentOptions_[0] != 0; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (independentOptions_[1] & 1) == 0; + } + inline void setDoDual(bool doDual_) { + if (doDual_) independentOptions_[1] &= ~1; + else independentOptions_[1] |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (independentOptions_[1] & 2) == 0; + } + inline void setDoSingleton(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~2; + else independentOptions_[1] |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (independentOptions_[1] & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton_) { + if (doDoubleton_) independentOptions_[1] &= ~4; + else independentOptions_[1] |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (independentOptions_[1] & 8) == 0; + } + inline void setDoTripleton(bool doTripleton_) { + if (doTripleton_) independentOptions_[1] &= ~8; + else independentOptions_[1] |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (independentOptions_[1] & 16) == 0; + } + inline void setDoTighten(bool doTighten_) { + if (doTighten_) independentOptions_[1] &= ~16; + else independentOptions_[1] |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (independentOptions_[1] & 32) == 0; + } + inline void setDoForcing(bool doForcing_) { + if (doForcing_) independentOptions_[1] &= ~32; + else independentOptions_[1] |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (independentOptions_[1] & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) independentOptions_[1] &= ~64; + else independentOptions_[1] |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (independentOptions_[1] & 128) == 0; + } + inline void setDoDupcol(bool doDupcol_) { + if (doDupcol_) independentOptions_[1] &= ~128; + else independentOptions_[1] |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (independentOptions_[1] & 256) == 0; + } + inline void setDoDuprow(bool doDuprow_) { + if (doDuprow_) independentOptions_[1] &= ~256; + else independentOptions_[1] |= 256; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (independentOptions_[1] & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~512; + else independentOptions_[1] |= 512; + } + /// Whether we want to kill small substitutions + inline bool doKillSmall() const { + return (independentOptions_[1] & 8192) == 0; + } + inline void setDoKillSmall(bool doKill) { + if (doKill) independentOptions_[1] &= ~8192; + else independentOptions_[1] |= 8192; + } + /// Set whole group + inline int presolveActions() const { + return independentOptions_[1] & 0xffff; + } + inline void setPresolveActions(int action) { + independentOptions_[1] = (independentOptions_[1] & 0xffff0000) | (action & 0xffff); + } + /// Largest column for substitution (normally 3) + inline int substitution() const { + return independentOptions_[2]; + } + inline void setSubstitution(int value) { + independentOptions_[2] = value; + } + inline void setIndependentOption(int type,int value) { + independentOptions_[type] = value; + } + inline int independentOption(int type) const { + return independentOptions_[type]; + } + //@} + +////////////////// data ////////////////// +private: + + /**@name data. + */ + //@{ + /// Solve type + SolveType method_; + /// Presolve type + PresolveType presolveType_; + /// Amount of presolve + int numberPasses_; + /// Options - last is switch for OsiClp + int options_[7]; + /// Extra information + int extraInfo_[7]; + /** Extra algorithm dependent options + 0 - if set return from clpsolve if infeasible + 1 - To be copied over to presolve options + 2 - max substitution level + If Dantzig Wolfe/benders 0 is number blocks, 2 is #passes (notional) + */ + int independentOptions_[3]; + //@} +}; + +/// For saving extra information to see if looping. +class ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplexProgress ( ); + + /// Constructor from model + ClpSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + ClpSimplexProgress(const ClpSimplexProgress &); + + /// Assignment operator. This copies the data + ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs); + /// Destructor + ~ClpSimplexProgress ( ); + /// Resets as much as possible + void reset(); + /// Fill from model + void fillFromModel ( ClpSimplex * model ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + /// Start check at beginning of whileIterating + void startCheck(); + /// Returns cycle length in whileIterating + int cycle(int in, int out, int wayIn, int wayOut); + + /// Returns previous objective (if -1) - current if (0) + double lastObjective(int back = 1) const; + /// Set real primal infeasibility and move back + void setInfeasibility(double value); + /// Returns real primal infeasibility (if -1) - current if (0) + double lastInfeasibility(int back = 1) const; + /// Returns number of primal infeasibilities (if -1) - current if (0) + int numberInfeasibilities(int back = 1) const; + /// Modify objective e.g. if dual infeasible in dual + void modifyObjective(double value); + /// Returns previous iteration number (if -1) - current if (0) + int lastIterationNumber(int back = 1) const; + /// clears all iteration numbers (to switch off panic) + void clearIterationNumbers(); + /// Odd state + inline void newOddState() { + oddState_ = - oddState_ - 1; + } + inline void endOddState() { + oddState_ = abs(oddState_); + } + inline void clearOddState() { + oddState_ = 0; + } + inline int oddState() const { + return oddState_; + } + /// number of bad times + inline int badTimes() const { + return numberBadTimes_; + } + inline void clearBadTimes() { + numberBadTimes_ = 0; + } + /// number of really bad times + inline int reallyBadTimes() const { + return numberReallyBadTimes_; + } + inline void incrementReallyBadTimes() { + numberReallyBadTimes_++; + } + /// number of times flagged + inline int timesFlagged() const { + return numberTimesFlagged_; + } + inline void clearTimesFlagged() { + numberTimesFlagged_ = 0; + } + inline void incrementTimesFlagged() { + numberTimesFlagged_++; + } + + //@} + /**@name Data */ +#define CLP_PROGRESS 5 + //#define CLP_PROGRESS_WEIGHT 10 + //@{ + /// Objective values + double objective_[CLP_PROGRESS]; + /// Sum of infeasibilities for algorithm + double infeasibility_[CLP_PROGRESS]; + /// Sum of real primal infeasibilities for primal + double realInfeasibility_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Objective values for weights + double objectiveWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of infeasibilities for algorithm for weights + double infeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of real primal infeasibilities for primal for weights + double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Drop for weights + double drop_; + /// Best? for weights + double best_; +#endif + /// Initial weight for weights + double initialWeight_; +#define CLP_CYCLE 12 + /// For cycle checking + //double obj_[CLP_CYCLE]; + int in_[CLP_CYCLE]; + int out_[CLP_CYCLE]; + char way_[CLP_CYCLE]; + /// Pointer back to model so we can get information + ClpSimplex * model_; + /// Number of infeasibilities + int numberInfeasibilities_[CLP_PROGRESS]; + /// Iteration number at which occurred + int iterationNumber_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Number of infeasibilities for weights + int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT]; + /// Iteration number at which occurred for weights + int iterationNumberWeight_[CLP_PROGRESS_WEIGHT]; +#endif + /// Number of times checked (so won't stop too early) + int numberTimes_; + /// Number of times it looked like loop + int numberBadTimes_; + /// Number really bad times + int numberReallyBadTimes_; + /// Number of times no iterations as flagged + int numberTimesFlagged_; + /// If things are in an odd state + int oddState_; + //@} +}; + +#include "ClpConfig.h" +#if CLP_HAS_ABC +#include "AbcCommon.hpp" +/// For saving extra information to see if looping. +class AbcSimplexProgress : public ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + AbcSimplexProgress ( ); + + /// Constructor from model + AbcSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + AbcSimplexProgress(const AbcSimplexProgress &); + + /// Assignment operator. This copies the data + AbcSimplexProgress & operator=(const AbcSimplexProgress & rhs); + /// Destructor + ~AbcSimplexProgress ( ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + + //@} + /**@name Data */ + //@} +}; +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/Clp_C_Interface.h b/thirdparty/linux/include/coin/coin/Clp_C_Interface.h new file mode 100644 index 0000000..b91b2d2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/Clp_C_Interface.h @@ -0,0 +1,525 @@ +/* $Id: Clp_C_Interface.h 2019 2014-01-31 05:18:01Z stefan $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpSimplexC_H +#define ClpSimplexC_H + +/* include all defines and ugly stuff */ +#include "Coin_C_defines.h" + +#if defined (CLP_EXTERN_C) +typedef struct { + ClpSolve options; +} Clp_Solve; +#else +typedef void Clp_Solve; +#endif + +/** This is a first "C" interface to Clp. + It has similarities to the OSL V3 interface + and only has most common functions +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /**@name Version info + * + * A Clp library has a version number of the form <major>.<minor>.<release>, + * where each of major, minor, and release are nonnegative integers. + * For a checkout of the Clp stable branch, release is 9999. + * For a checkout of the Clp development branch, major, minor, and release are 9999. + */ + /*@{*/ + /** Clp library version number as string. */ + COINLIBAPI const char* COINLINKAGE Clp_Version(void); + /** Major number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMajor(void); + /** Minor number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMinor(void); + /** Release number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionRelease(void); + /*@}*/ + + /**@name Constructors and destructor + These do not have an exact analogue in C++. + The user does not need to know structure of Clp_Simplex or Clp_Solve. + + For (almost) all Clp_* functions outside this group there is an exact C++ + analogue created by taking the first parameter out, removing the Clp_ + from name and applying the method to an object of type ClpSimplex. + + Similarly, for all ClpSolve_* functions there is an exact C++ + analogue created by taking the first parameter out, removing the ClpSolve_ + from name and applying the method to an object of type ClpSolve. + */ + /*@{*/ + + /** Default constructor */ + COINLIBAPI Clp_Simplex * COINLINKAGE Clp_newModel(void); + /** Destructor */ + COINLIBAPI void COINLINKAGE Clp_deleteModel(Clp_Simplex * model); + /** Default constructor */ + COINLIBAPI Clp_Solve * COINLINKAGE ClpSolve_new(); + /** Destructor */ + COINLIBAPI void COINLINKAGE ClpSolve_delete(Clp_Solve * solve); + /*@}*/ + + /**@name Load model - loads some stuff and initializes others */ + /*@{*/ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + COINLIBAPI void COINLINKAGE Clp_loadProblem (Clp_Simplex * model, const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /* read quadratic part of the objective (the matrix part) */ + COINLIBAPI void COINLINKAGE + Clp_loadQuadraticObjective(Clp_Simplex * model, + const int numberColumns, + const CoinBigIndex * start, + const int * column, + const double * element); + /** Read an mps file from the given filename */ + COINLIBAPI int COINLINKAGE Clp_readMps(Clp_Simplex * model, const char *filename, + int keepNames, + int ignoreErrors); + /** Copy in integer informations */ + COINLIBAPI void COINLINKAGE Clp_copyInIntegerInformation(Clp_Simplex * model, const char * information); + /** Drop integer informations */ + COINLIBAPI void COINLINKAGE Clp_deleteIntegerInformation(Clp_Simplex * model); + /** Resizes rim part of model */ + COINLIBAPI void COINLINKAGE Clp_resize (Clp_Simplex * model, int newNumberRows, int newNumberColumns); + /** Deletes rows */ + COINLIBAPI void COINLINKAGE Clp_deleteRows(Clp_Simplex * model, int number, const int * which); + /** Add rows */ + COINLIBAPI void COINLINKAGE Clp_addRows(Clp_Simplex * model, int number, const double * rowLower, + const double * rowUpper, + const int * rowStarts, const int * columns, + const double * elements); + + /** Deletes columns */ + COINLIBAPI void COINLINKAGE Clp_deleteColumns(Clp_Simplex * model, int number, const int * which); + /** Add columns */ + COINLIBAPI void COINLINKAGE Clp_addColumns(Clp_Simplex * model, int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const int * columnStarts, const int * rows, + const double * elements); + /** Change row lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowLower(Clp_Simplex * model, const double * rowLower); + /** Change row upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowUpper(Clp_Simplex * model, const double * rowUpper); + /** Change column lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnLower(Clp_Simplex * model, const double * columnLower); + /** Change column upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnUpper(Clp_Simplex * model, const double * columnUpper); + /** Change objective coefficients */ + COINLIBAPI void COINLINKAGE Clp_chgObjCoefficients(Clp_Simplex * model, const double * objIn); + /** Drops names - makes lengthnames 0 and names empty */ + COINLIBAPI void COINLINKAGE Clp_dropNames(Clp_Simplex * model); + /** Copies in names */ + COINLIBAPI void COINLINKAGE Clp_copyNames(Clp_Simplex * model, const char * const * rowNames, + const char * const * columnNames); + + /*@}*/ + /**@name gets and sets - you will find some synonyms at the end of this file */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_numberRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_numberColumns(Clp_Simplex * model); + /** Primal tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_primalTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPrimalTolerance(Clp_Simplex * model, double value) ; + /** Dual tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_dualTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualTolerance(Clp_Simplex * model, double value) ; + /** Dual objective limit */ + COINLIBAPI double COINLINKAGE Clp_dualObjectiveLimit(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualObjectiveLimit(Clp_Simplex * model, double value); + /** Objective offset */ + COINLIBAPI double COINLINKAGE Clp_objectiveOffset(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setObjectiveOffset(Clp_Simplex * model, double value); + /** Fills in array with problem name */ + COINLIBAPI void COINLINKAGE Clp_problemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /* Sets problem name. Must have \0 at end. */ + COINLIBAPI int COINLINKAGE + Clp_setProblemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_numberIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setNumberIterations(Clp_Simplex * model, int numberIterations); + /** Maximum number of iterations */ + COINLIBAPI int maximumIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumIterations(Clp_Simplex * model, int value); + /** Maximum time in seconds (from when set called) */ + COINLIBAPI double COINLINKAGE Clp_maximumSeconds(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumSeconds(Clp_Simplex * model, double value); + /** Returns true if hit maximum iterations (or time) */ + COINLIBAPI int COINLINKAGE Clp_hitMaximumIterations(Clp_Simplex * model); + /** Status of problem: + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations etc + 4 - stopped due to errors + */ + COINLIBAPI int COINLINKAGE Clp_status(Clp_Simplex * model); + /** Set problem status */ + COINLIBAPI void COINLINKAGE Clp_setProblemStatus(Clp_Simplex * model, int problemStatus); + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached + 2 - scaled problem optimal - unscaled has primal infeasibilities + 3 - scaled problem optimal - unscaled has dual infeasibilities + 4 - scaled problem optimal - unscaled has both dual and primal infeasibilities + */ + COINLIBAPI int COINLINKAGE Clp_secondaryStatus(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSecondaryStatus(Clp_Simplex * model, int status); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_optimizationDirection(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setOptimizationDirection(Clp_Simplex * model, double value); + /** Primal row solution */ + COINLIBAPI double * COINLINKAGE Clp_primalRowSolution(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI double * COINLINKAGE Clp_primalColumnSolution(Clp_Simplex * model); + /** Dual row solution */ + COINLIBAPI double * COINLINKAGE Clp_dualRowSolution(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI double * COINLINKAGE Clp_dualColumnSolution(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI double* COINLINKAGE Clp_rowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI double* COINLINKAGE Clp_rowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI double * COINLINKAGE Clp_objective(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI double * COINLINKAGE Clp_columnLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI double * COINLINKAGE Clp_columnUpper(Clp_Simplex * model); + /** Number of elements in matrix */ + COINLIBAPI int COINLINKAGE Clp_getNumElements(Clp_Simplex * model); + /* Column starts in matrix */ + COINLIBAPI const CoinBigIndex * COINLINKAGE Clp_getVectorStarts(Clp_Simplex * model); + /* Row indices in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getIndices(Clp_Simplex * model); + /* Column vector lengths in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getVectorLengths(Clp_Simplex * model); + /* Element values in matrix */ + COINLIBAPI const double * COINLINKAGE Clp_getElements(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_objectiveValue(Clp_Simplex * model); + /** Integer information */ + COINLIBAPI char * COINLINKAGE Clp_integerInformation(Clp_Simplex * model); + /** Gives Infeasibility ray. + * + * Use Clp_freeRay to free the returned array. + * + * @return infeasibility ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_infeasibilityRay(Clp_Simplex * model); + /** Gives ray in which the problem is unbounded. + * + * Use Clp_freeRay to free the returned array. + * + * @return unbounded ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_unboundedRay(Clp_Simplex * model); + /** Frees a infeasibility or unbounded ray. */ + COINLIBAPI void COINLINKAGE Clp_freeRay(Clp_Simplex * model, double * ray); + /** See if status array exists (partly for OsiClp) */ + COINLIBAPI int COINLINKAGE Clp_statusExists(Clp_Simplex * model); + /** Return address of status array (char[numberRows+numberColumns]) */ + COINLIBAPI unsigned char * COINLINKAGE Clp_statusArray(Clp_Simplex * model); + /** Copy in status vector */ + COINLIBAPI void COINLINKAGE Clp_copyinStatus(Clp_Simplex * model, const unsigned char * statusArray); + /* status values are as in ClpSimplex.hpp i.e. 0 - free, 1 basic, 2 at upper, + 3 at lower, 4 superbasic, (5 fixed) */ + /* Get variable basis info */ + COINLIBAPI int COINLINKAGE Clp_getColumnStatus(Clp_Simplex * model, int sequence); + /* Get row basis info */ + COINLIBAPI int COINLINKAGE Clp_getRowStatus(Clp_Simplex * model, int sequence); + /* Set variable basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setColumnStatus(Clp_Simplex * model, + int sequence, int value); + /* Set row basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setRowStatus(Clp_Simplex * model, + int sequence, int value); + + /** User pointer for whatever reason */ + COINLIBAPI void COINLINKAGE Clp_setUserPointer (Clp_Simplex * model, void * pointer); + COINLIBAPI void * COINLINKAGE Clp_getUserPointer (Clp_Simplex * model); + /*@}*/ + /**@name Message handling. Call backs are handled by ONE function */ + /*@{*/ + /** Pass in Callback function. + Message numbers up to 1000000 are Clp, Coin ones have 1000000 added */ + COINLIBAPI void COINLINKAGE Clp_registerCallBack(Clp_Simplex * model, + clp_callback userCallBack); + /** Unset Callback function */ + COINLIBAPI void COINLINKAGE Clp_clearCallBack(Clp_Simplex * model); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + COINLIBAPI void COINLINKAGE Clp_setLogLevel(Clp_Simplex * model, int value); + COINLIBAPI int COINLINKAGE Clp_logLevel(Clp_Simplex * model); + /** length of names (0 means no names0 */ + COINLIBAPI int COINLINKAGE Clp_lengthNames(Clp_Simplex * model); + /** Fill in array (at least lengthNames+1 long) with a row name */ + COINLIBAPI void COINLINKAGE Clp_rowName(Clp_Simplex * model, int iRow, char * name); + /** Fill in array (at least lengthNames+1 long) with a column name */ + COINLIBAPI void COINLINKAGE Clp_columnName(Clp_Simplex * model, int iColumn, char * name); + + /*@}*/ + + + /**@name Functions most useful to user */ + /*@{*/ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + COINLIBAPI int COINLINKAGE Clp_initialSolve(Clp_Simplex * model); + /** Pass solve options. (Exception to direct analogue rule) */ + COINLIBAPI int COINLINKAGE Clp_initialSolveWithOptions(Clp_Simplex * model, Clp_Solve *); + /** Dual initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialDualSolve(Clp_Simplex * model); + /** Primal initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialPrimalSolve(Clp_Simplex * model); + /** Barrier initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierSolve(Clp_Simplex * model); + /** Barrier initial solve, no crossover */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierNoCrossSolve(Clp_Simplex * model); + /** Dual algorithm - see ClpSimplexDual.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_dual(Clp_Simplex * model, int ifValuesPass); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_primal(Clp_Simplex * model, int ifValuesPass); +#ifndef SLIM_CLP + /** Solve the problem with the idiot code */ + COINLIBAPI void COINLINKAGE Clp_idiot(Clp_Simplex * model, int tryhard); +#endif + /** Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */ + COINLIBAPI void COINLINKAGE Clp_scaling(Clp_Simplex * model, int mode); + /** Gets scalingFlag */ + COINLIBAPI int COINLINKAGE Clp_scalingFlag(Clp_Simplex * model); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + + If "pivot" is + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + COINLIBAPI int COINLINKAGE Clp_crash(Clp_Simplex * model, double gap, int pivot); + /*@}*/ + + + /**@name most useful gets and sets */ + /*@{*/ + /** If problem is primal feasible */ + COINLIBAPI int COINLINKAGE Clp_primalFeasible(Clp_Simplex * model); + /** If problem is dual feasible */ + COINLIBAPI int COINLINKAGE Clp_dualFeasible(Clp_Simplex * model); + /** Dual bound */ + COINLIBAPI double COINLINKAGE Clp_dualBound(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualBound(Clp_Simplex * model, double value); + /** Infeasibility cost */ + COINLIBAPI double COINLINKAGE Clp_infeasibilityCost(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setInfeasibilityCost(Clp_Simplex * model, double value); + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + COINLIBAPI int COINLINKAGE Clp_perturbation(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPerturbation(Clp_Simplex * model, int value); + /** Current (or last) algorithm */ + COINLIBAPI int COINLINKAGE Clp_algorithm(Clp_Simplex * model); + /** Set algorithm */ + COINLIBAPI void COINLINKAGE Clp_setAlgorithm(Clp_Simplex * model, int value); + /** Sum of dual infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumDualInfeasibilities(Clp_Simplex * model); + /** Number of dual infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberDualInfeasibilities(Clp_Simplex * model); + /** Sum of primal infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumPrimalInfeasibilities(Clp_Simplex * model); + /** Number of primal infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberPrimalInfeasibilities(Clp_Simplex * model); + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + COINLIBAPI int COINLINKAGE Clp_saveModel(Clp_Simplex * model, const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + COINLIBAPI int COINLINKAGE Clp_restoreModel(Clp_Simplex * model, const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc */ + COINLIBAPI void COINLINKAGE Clp_checkSolution(Clp_Simplex * model); + /*@}*/ + + /******************** End of most useful part **************/ + /**@name gets and sets - some synonyms */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_getNumRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_getNumCols(Clp_Simplex * model); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_getIterationCount(Clp_Simplex * model); + /** Are there a numerical difficulties? */ + COINLIBAPI int COINLINKAGE Clp_isAbandoned(Clp_Simplex * model); + /** Is optimality proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenOptimal(Clp_Simplex * model); + /** Is primal infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenPrimalInfeasible(Clp_Simplex * model); + /** Is dual infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenDualInfeasible(Clp_Simplex * model); + /** Is the given primal objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isPrimalObjectiveLimitReached(Clp_Simplex * model) ; + /** Is the given dual objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isDualObjectiveLimitReached(Clp_Simplex * model) ; + /** Iteration limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isIterationLimitReached(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_getObjSense(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI void COINLINKAGE Clp_setObjSense(Clp_Simplex * model, double objsen); + /** Primal row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowActivity(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI const double * COINLINKAGE Clp_getColSolution(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setColSolution(Clp_Simplex * model, const double * input); + /** Dual row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowPrice(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI const double * COINLINKAGE Clp_getReducedCost(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI const double* COINLINKAGE Clp_getRowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI const double* COINLINKAGE Clp_getRowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI const double * COINLINKAGE Clp_getObjCoefficients(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI const double * COINLINKAGE Clp_getColLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI const double * COINLINKAGE Clp_getColUpper(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_getObjValue(Clp_Simplex * model); + /** Print model for debugging purposes */ + COINLIBAPI void COINLINKAGE Clp_printModel(Clp_Simplex * model, const char * prefix); + /* Small element value - elements less than this set to zero, + default is 1.0e-20 */ + COINLIBAPI double COINLINKAGE Clp_getSmallElementValue(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSmallElementValue(Clp_Simplex * model, double value); + /*@}*/ + + + /**@name Get and set ClpSolve options + */ + /*@{*/ + COINLIBAPI void COINLINKAGE ClpSolve_setSpecialOption(Clp_Solve *, int which, int value, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSpecialOption(Clp_Solve *, int which); + + /** method: (see ClpSolve::SolveType) + 0 - dual simplex + 1 - primal simplex + 2 - primal or sprint + 3 - barrier + 4 - barrier no crossover + 5 - automatic + 6 - not implemented + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setSolveType(Clp_Solve *, int method, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSolveType(Clp_Solve *); + + /** amount: (see ClpSolve::PresolveType) + 0 - presolve on + 1 - presolve off + 2 - presolve number + 3 - presolve number cost + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve *, int amount, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getPresolveType(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_getPresolvePasses(Clp_Solve *); + COINLIBAPI int COINLINKAGE ClpSolve_getExtraInfo(Clp_Solve *, int which); + COINLIBAPI void COINLINKAGE ClpSolve_setInfeasibleReturn(Clp_Solve *, int trueFalse); + COINLIBAPI int COINLINKAGE ClpSolve_infeasibleReturn(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_doDual(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDual(Clp_Solve *, int doDual); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingleton(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doDoubleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDoubleton(Clp_Solve *, int doDoubleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTripleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTripleton(Clp_Solve *, int doTripleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTighten(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTighten(Clp_Solve *, int doTighten); + + COINLIBAPI int COINLINKAGE ClpSolve_doForcing(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoForcing(Clp_Solve *, int doForcing); + + COINLIBAPI int COINLINKAGE ClpSolve_doImpliedFree(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoImpliedFree(Clp_Solve *, int doImpliedFree); + + COINLIBAPI int COINLINKAGE ClpSolve_doDupcol(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDupcol(Clp_Solve *, int doDupcol); + + COINLIBAPI int COINLINKAGE ClpSolve_doDuprow(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDuprow(Clp_Solve *, int doDuprow); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingletonColumn(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingletonColumn(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_presolveActions(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveActions(Clp_Solve *, int action); + + COINLIBAPI int COINLINKAGE ClpSolve_substitution(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setSubstitution(Clp_Solve *, int value); + + /*@}*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinAlloc.hpp b/thirdparty/linux/include/coin/coin/CoinAlloc.hpp new file mode 100644 index 0000000..8f6b08c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinAlloc.hpp @@ -0,0 +1,176 @@ +/* $Id: CoinAlloc.hpp 1438 2011-06-09 18:14:12Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinAlloc_hpp +#define CoinAlloc_hpp + +#include "CoinUtilsConfig.h" +#include <cstdlib> + +#if !defined(COINUTILS_MEMPOOL_MAXPOOLED) +# define COINUTILS_MEMPOOL_MAXPOOLED -1 +#endif + +#if (COINUTILS_MEMPOOL_MAXPOOLED >= 0) + +#ifndef COINUTILS_MEMPOOL_ALIGNMENT +#define COINUTILS_MEMPOOL_ALIGNMENT 16 +#endif + +/* Note: + This memory pool implementation assumes that sizeof(size_t) and + sizeof(void*) are both <= COINUTILS_MEMPOOL_ALIGNMENT. + Choosing an alignment of 4 will cause segfault on 64-bit platforms and may + lead to bad performance on 32-bit platforms. So 8 is a mnimum recommended + alignment. Probably 16 does not waste too much space either and may be even + better for performance. One must play with it. +*/ + +//############################################################################# + +#if (COINUTILS_MEMPOOL_ALIGNMENT == 16) +static const std::size_t CoinAllocPtrShift = 4; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)15); +#elif (COINUTILS_MEMPOOL_ALIGNMENT == 8) +static const std::size_t CoinAllocPtrShift = 3; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)7); +#else +#error "COINUTILS_MEMPOOL_ALIGNMENT must be defined as 8 or 16 (or this code needs to be changed :-)" +#endif + +//############################################################################# + +#ifndef COIN_MEMPOOL_SAVE_BLOCKHEADS +# define COIN_MEMPOOL_SAVE_BLOCKHEADS 0 +#endif + +//############################################################################# + +class CoinMempool +{ +private: +#if (COIN_MEMPOOL_SAVE_BLOCKHEADS == 1) + char** block_heads; + std::size_t block_num; + std::size_t max_block_num; +#endif +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_t mutex_; +#endif + int last_block_size_; + char* first_free_; + const std::size_t entry_size_; + +private: + CoinMempool(const CoinMempool&); + CoinMempool& operator=(const CoinMempool&); + +private: + char* allocate_new_block(); + inline void lock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_lock(&mutex_); +#endif + } + inline void unlock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_unlock(&mutex_); +#endif + } + +public: + CoinMempool(std::size_t size = 0); + ~CoinMempool(); + + char* alloc(); + inline void dealloc(char *p) + { + char** pp = (char**)p; + lock_mutex(); + *pp = first_free_; + first_free_ = p; + unlock_mutex(); + } +}; + +//############################################################################# + +/** A memory pool allocator. + + If a request arrives for allocating \c n bytes then it is first + rounded up to the nearest multiple of \c sizeof(void*) (this is \c + n_roundup), then one more \c sizeof(void*) is added to this + number. If the result is no more than maxpooled_ then + the appropriate pool is used to get a chunk of memory, if not, + then malloc is used. In either case, the size of the allocated + chunk is written into the first \c sizeof(void*) bytes and a + pointer pointing afterwards is returned. +*/ + +class CoinAlloc +{ +private: + CoinMempool* pool_; + int maxpooled_; +public: + CoinAlloc(); + ~CoinAlloc() {} + + inline void* alloc(const std::size_t n) + { + if (maxpooled_ <= 0) { + return std::malloc(n); + } + char *p = NULL; + const std::size_t to_alloc = + ((n+COINUTILS_MEMPOOL_ALIGNMENT-1) & CoinAllocRoundMask) + + COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = NULL; + if (maxpooled_ > 0 && to_alloc >= (size_t)maxpooled_) { + p = static_cast<char*>(std::malloc(to_alloc)); + if (p == NULL) throw std::bad_alloc(); + } else { + pool = pool_ + (to_alloc >> CoinAllocPtrShift); + p = pool->alloc(); + } + *((CoinMempool**)p) = pool; + return static_cast<void*>(p+COINUTILS_MEMPOOL_ALIGNMENT); + } + + inline void dealloc(void* p) + { + if (maxpooled_ <= 0) { + std::free(p); + return; + } + if (p) { + char* base = static_cast<char*>(p)-COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = *((CoinMempool**)base); + if (!pool) { + std::free(base); + } else { + pool->dealloc(base); + } + } + } +}; + +extern CoinAlloc CoinAllocator; + +//############################################################################# + +#if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1) +void* operator new(std::size_t size) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); +#endif + +#endif /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/ +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinBuild.hpp b/thirdparty/linux/include/coin/coin/CoinBuild.hpp new file mode 100644 index 0000000..770c269 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinBuild.hpp @@ -0,0 +1,149 @@ +/* $Id: CoinBuild.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinBuild_H +#define CoinBuild_H + + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" + + +/** + In many cases it is natural to build a model by adding one row at a time. In Coin this + is inefficient so this class gives some help. An instance of CoinBuild can be built up + more efficiently and then added to the Clp/OsiModel in one go. + + It may be more efficient to have fewer arrays and re-allocate them but this should + give a large gain over addRow. + + I have now extended it to columns. + +*/ + +class CoinBuild { + +public: + /**@name Useful methods */ + //@{ + /// add a row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX); + /// add a column + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0); + /// add a column + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue);} + /// Return number of rows or maximum found so far + inline int numberRows() const + { return (type_==0) ? numberItems_ : numberOther_;} + /// Return number of columns or maximum found so far + inline int numberColumns() const + { return (type_==1) ? numberItems_ : numberOther_;} + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /** Returns number of elements in a row and information in row + */ + int row(int whichRow, double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current row and information in row + Used as rows may be stored in a chain + */ + int currentRow(double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /// Set current row + void setCurrentRow(int whichRow); + /// Returns current row number + int currentRow() const; + /** Returns number of elements in a column and information in column + */ + int column(int whichColumn, + double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current column and information in column + Used as columns may be stored in a chain + */ + int currentColumn( double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current column + void setCurrentColumn(int whichColumn); + /// Returns current column number + int currentColumn() const; + /// Returns type + inline int type() const + { return type_;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinBuild(); + /** Constructor with type 0==for addRow, 1== for addColumn. */ + CoinBuild(int type); + /** Destructor */ + ~CoinBuild(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinBuild(const CoinBuild&); + /// = + CoinBuild& operator=(const CoinBuild&); + //@} +private: + /// Set current + void setMutableCurrent(int which) const; + /// add a item + void addItem(int numberInItem, const int * indices, + const double * elements, + double itemLower, + double itemUpper, double objectiveValue); + /** Returns number of elements in a item and information in item + */ + int item(int whichItem, + double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current item and information in item + Used as items may be stored in a chain + */ + int currentItem( double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current item + void setCurrentItem(int whichItem); + /// Returns current item number + int currentItem() const; + +private: + /**@name Data members */ + //@{ + /// Current number of items + int numberItems_; + /// Current number of other dimension i.e. Columns if addRow (i.e. max) + int numberOther_; + /// Current number of elements + CoinBigIndex numberElements_; + /// Current item pointer + mutable double * currentItem_; + /// First item pointer + double * firstItem_; + /// Last item pointer + double * lastItem_; + /// Type of build - 0 for row, 1 for column, -1 unset + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinDenseFactorization.hpp b/thirdparty/linux/include/coin/coin/CoinDenseFactorization.hpp new file mode 100644 index 0000000..3ba7528 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinDenseFactorization.hpp @@ -0,0 +1,419 @@ +/* $Id: CoinDenseFactorization.hpp 1759 2014-11-18 11:07:23Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +/* + Authors + + John Forrest + + */ +#ifndef CoinDenseFactorization_H +#define CoinDenseFactorization_H + +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFactorization.hpp" +#if COIN_FACTORIZATION_DENSE_CODE == 2 +#undef COIN_FACTORIZATION_DENSE_CODE +#endif +class CoinPackedMatrix; +/// Abstract base class which also has some scalars so can be used from Dense or Simp +class CoinOtherFactorization { + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOtherFactorization ( ); + /// Copy constructor + CoinOtherFactorization ( const CoinOtherFactorization &other); + + /// Destructor + virtual ~CoinOtherFactorization ( ); + /// = copy + CoinOtherFactorization & operator = ( const CoinOtherFactorization & other ); + + /// Clone + virtual CoinOtherFactorization * clone() const = 0; + //@} + + /**@name general stuff such as status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /** Get solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline int solveMode() const + { return solveMode_ ;} + /** Set solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline void setSolveMode(int value) + { solveMode_ = value;} + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Get rid of all memory + virtual void clearArrays() {} + //@} + /**@name virtual general stuff such as permutation */ + //@{ + /// Returns array to put basis indices in + virtual int * indices() const = 0; + /// Returns permute in + virtual int * permute() const = 0; + /// Total number of elements in factorization + virtual int numberElements ( ) const = 0; + //@} + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ) = 0; + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ) = 0; + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ) = 0; + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable) = 0; + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns) = 0; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8)=0; + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) = 0; + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const = 0; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false) = 0; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const = 0; + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Columns in factorization + int numberColumns_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Status of factorization + int status_; + /// Maximum rows ever (i.e. use to copy arrays etc) + int maximumRows_; + /// Maximum length of iterating area + CoinBigIndex maximumSpace_; + /// Pivot row + int * pivotRow_; + /** Elements of factorization and updates + length is maxR*maxR+maxSpace + will always be long enough so can have nR*nR ints in maxSpace + */ + CoinFactorizationDouble * elements_; + /// Work area of numberRows_ + CoinFactorizationDouble * workArea_; + /** Solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + int solveMode_; + //@} +}; +/** This deals with Factorization and Updates + This is a simple dense version so other people can write a better one + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + + +class CoinDenseFactorization : public CoinOtherFactorization { + friend void CoinDenseFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinDenseFactorization ( ); + /// Copy constructor + CoinDenseFactorization ( const CoinDenseFactorization &other); + + /// Destructor + virtual ~CoinDenseFactorization ( ); + /// = copy + CoinDenseFactorization & operator = ( const CoinDenseFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual inline int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool = false) + { return updateColumn(regionSparse,regionSparse2);} + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + virtual inline int * indices() const + { return reinterpret_cast<int *> (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinDenseFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinDenseVector.hpp b/thirdparty/linux/include/coin/coin/CoinDenseVector.hpp new file mode 100644 index 0000000..77ff9af --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinDenseVector.hpp @@ -0,0 +1,383 @@ +/* $Id: CoinDenseVector.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinDenseVector_H +#define CoinDenseVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <cassert> +#include <cstdlib> +#include <cmath> +#include "CoinHelperFunctions.hpp" + +//############################################################################# +/** A function that tests the methods in the CoinDenseVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ + template <typename T> void + CoinDenseVectorUnitTest(T dummy); + +//############################################################################# +/** Dense Vector + +Stores a dense (or expanded) vector of floating point values. +Type of vector elements is controlled by templating. +(Some working quantities such as accumulated sums +are explicitly declared of type double). This allows the +components of the vector integer, single or double precision. + +Here is a sample usage: +@verbatim + const int ne = 4; + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinDenseVector<double> r(ne,el); + + // access each element + assert( r.getElements()[0]==10. ); + assert( r.getElements()[1]==40. ); + assert( r.getElements()[2]== 1. ); + assert( r.getElements()[3]==50. ); + + // Test for equality + CoinDenseVector<double> r1; + r1=r; + + // Add dense vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinDenseVector<double> add = r + r1; + assert( add[0] == 10.+10. ); + assert( add[1] == 40.+40. ); + assert( add[2] == 1.+ 1. ); + assert( add[3] == 50.+50. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +template <typename T> class CoinDenseVector { +private: + /**@name Private member data */ + //@{ + /// Size of element vector + int nElements_; + ///Vector elements + T * elements_; + //@} + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + inline int size() const { return nElements_; } + /// Get element values + inline const T * getElements() const { return elements_; } + /// Get element values + inline T * getElements() { return elements_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (i.e. set all elemenets to zero) + void clear(); + /** Assignment operator */ + CoinDenseVector & operator=(const CoinDenseVector &); + /** Member of array operator */ + T & operator[](int index) const; + + /** Set vector size, and elements. + Size is the length of the elements vector. + The element vector is copied into this class instance's + member data. */ + void setVector(int size, const T * elems); + + + /** Elements set to have the same scalar value */ + void setConstant(int size, T elems); + + + /** Set an existing element in the dense vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, T element); + /** Resize the dense vector to be the first newSize elements. + If length is decreased, vector is truncated. If increased + new entries, set to new default element */ + void resize(int newSize, T fill=T()); + + /** Append a dense vector to this dense vector */ + void append(const CoinDenseVector &); + //@} + + /**@name norms, sum and scale */ + //@{ + /// 1-norm of vector + inline T oneNorm() const { + T norm = 0; + for (int i=0; i<nElements_; i++) + norm += CoinAbs(elements_[i]); + return norm; + } + /// 2-norm of vector + inline double twoNorm() const { + double norm = 0.; + for (int i=0; i<nElements_; i++) + norm += elements_[i] * elements_[i]; + // std namespace removed because it was causing a compile + // problem with Microsoft Visual C++ + return /*std::*/sqrt(norm); + } + /// infinity-norm of vector + inline T infNorm() const { + T norm = 0; + for (int i=0; i<nElements_; i++) + norm = CoinMax(norm, CoinAbs(elements_[i])); + return norm; + } + /// sum of vector elements + inline T sum() const { + T sume = 0; + for (int i=0; i<nElements_; i++) + sume += elements_[i]; + return sume; + } + /// scale vector elements + inline void scale(T factor) { + for (int i=0; i<nElements_; i++) + elements_[i] *= factor; + return; + } + //@} + + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(T value); + /// subtract <code>value</code> from every entry + void operator-=(T value); + /// multiply every entry by <code>value</code> + void operator*=(T value); + /// divide every entry by <code>value</code> + void operator/=(T value); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinDenseVector(); + /** Alternate Constructors - set elements to vector of Ts */ + CoinDenseVector(int size, const T * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinDenseVector(int size, T element=T()); + /** Copy constructors */ + CoinDenseVector(const CoinDenseVector &); + + /** Destructor */ + ~CoinDenseVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, const T * elems); + /// Set all elements to a given value + void gutsOfSetConstant(int size, T value); + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on dense vectors. + + <strong>NOTE</strong>: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + <em>very</em> inefficient... + */ +//@{ +/// Return the sum of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + elements2[i]; + return op3; +} + +/// Return the difference of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] - elements2[i]; + return op3; +} + + +/// Return the element-wise product of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * elements2[i]; + return op3; +} + +/// Return the element-wise ratio of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] / elements2[i]; + return op3; +} +//@} + +/**@name Arithmetic operators on dense vector and a constant. + These functions create a dense vector as a result. That dense vector will + have the same indices as <code>op1</code> and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + dvalue; + return op3; +} + +/// Return the difference of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] - dvalue; + return op3; +} + +/// Return the element-wise product of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * dvalue; + return op3; +} + +/// Return the element-wise ratio of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] / dvalue; + return op3; +} + +/// Return the sum of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator+(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + dvalue; + return op3; +} + +/// Return the difference of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator-(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = dvalue - elements1[i]; + return op3; +} + +/// Return the element-wise product of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator*(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * dvalue; + return op3; +} + +/// Return the element-wise ratio of a a constant and dense vector +template <typename T> inline +CoinDenseVector<T> operator/(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = dvalue / elements1[i]; + return op3; +} +//@} + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinDistance.hpp b/thirdparty/linux/include/coin/coin/CoinDistance.hpp new file mode 100644 index 0000000..acaa908 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinDistance.hpp @@ -0,0 +1,48 @@ +/* $Id: CoinDistance.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinDistance_H +#define CoinDistance_H + +#include <iterator> + +//------------------------------------------------------------------- +// +// Attempt to provide an std::distance function +// that will work on multiple platforms +// +//------------------------------------------------------------------- + +/** CoinDistance + +This is the Coin implementation of the std::function that is +designed to work on multiple platforms. +*/ +template <class ForwardIterator, class Distance> +void coinDistance(ForwardIterator first, ForwardIterator last, + Distance& n) +{ +#if defined(__SUNPRO_CC) + n = 0; + std::distance(first,last,n); +#else + n = std::distance(first,last); +#endif +} + +template <class ForwardIterator> +size_t coinDistance(ForwardIterator first, ForwardIterator last) +{ + size_t retVal; +#if defined(__SUNPRO_CC) + retVal = 0; + std::distance(first,last,retVal); +#else + retVal = std::distance(first,last); +#endif + return retVal; +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinError.hpp b/thirdparty/linux/include/coin/coin/CoinError.hpp new file mode 100644 index 0000000..704cfea --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinError.hpp @@ -0,0 +1,257 @@ +/* $Id: CoinError.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinError_H +#define CoinError_H + +#include <string> +#include <iostream> +#include <cassert> +#include <cstring> + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +/** A function to block the popup windows that windows creates when the code + crashes */ +void WindowsErrorPopupBlocker(); + +//------------------------------------------------------------------- +// +// Error class used to throw exceptions +// +// Errors contain: +// +//------------------------------------------------------------------- + +/** Error Class thrown by an exception + +This class is used when exceptions are thrown. +It contains: + <ul> + <li>message text + <li>name of method throwing exception + <li>name of class throwing exception or hint + <li>name of file if assert + <li>line number + </ul> + For asserts class=> optional hint +*/ +class CoinError { + friend void CoinErrorUnitTest(); + +private: + CoinError() + : + message_(), + method_(), + class_(), + file_(), + lineNumber_() + { + // nothing to do here + } + +public: + + //------------------------------------------------------------------- + // Get methods + //------------------------------------------------------------------- + /**@name Get error attributes */ + //@{ + /// get message text + inline const std::string & message() const + { return message_; } + /// get name of method instantiating error + inline const std::string & methodName() const + { return method_; } + /// get name of class instantiating error (or hint for assert) + inline const std::string & className() const + { return class_; } + /// get name of file for assert + inline const std::string & fileName() const + { return file_; } + /// get line number of assert (-1 if not assert) + inline int lineNumber() const + { return lineNumber_; } + /// Just print (for asserts) + inline void print(bool doPrint = true) const + { + if (! doPrint) + return; + if (lineNumber_<0) { + std::cout<<message_<<" in "<<class_<<"::"<<method_<<std::endl; + } else { + std::cout<<file_<<":"<<lineNumber_<<" method "<<method_ + <<" : assertion \'"<<message_<<"\' failed."<<std::endl; + if(class_!="") + std::cout<<"Possible reason: "<<class_<<std::endl; + } + } + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Alternate Constructor + CoinError ( + std::string message__, + std::string methodName__, + std::string className__, + std::string fileName_ = std::string(), + int line = -1) + : + message_(message__), + method_(methodName__), + class_(className__), + file_(fileName_), + lineNumber_(line) + { + print(printErrors_); + } + + /// Copy constructor + CoinError (const CoinError & source) + : + message_(source.message_), + method_(source.method_), + class_(source.class_), + file_(source.file_), + lineNumber_(source.lineNumber_) + { + // nothing to do here + } + + /// Assignment operator + CoinError & operator=(const CoinError& rhs) + { + if (this != &rhs) { + message_=rhs.message_; + method_=rhs.method_; + class_=rhs.class_; + file_=rhs.file_; + lineNumber_ = rhs.lineNumber_; + } + return *this; + } + + /// Destructor + virtual ~CoinError () + { + // nothing to do here + } + //@} + +private: + + /**@name Private member data */ + //@{ + /// message test + std::string message_; + /// method name + std::string method_; + /// class name or hint + std::string class_; + /// file name + std::string file_; + /// Line number + int lineNumber_; + //@} + +public: + /// Whether to print every error + static bool printErrors_; +}; + +#ifndef __STRING +#define __STRING(x) #x +#endif + +#ifndef __GNUC_PREREQ +# define __GNUC_PREREQ(maj, min) (0) +#endif + +#ifndef COIN_ASSERT +# define CoinAssertDebug(expression) assert(expression) +# define CoinAssertDebugHint(expression,hint) assert(expression) +# define CoinAssert(expression) assert(expression) +# define CoinAssertHint(expression,hint) assert(expression) +#else +# ifdef NDEBUG +# define CoinAssertDebug(expression) {} +# define CoinAssertDebugHint(expression,hint) {} +# else +# if defined(__GNUC__) && __GNUC_PREREQ(2, 6) +# define CoinAssertDebug(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + "", __FILE__, __LINE__); \ + } \ + } +# define CoinAssertDebugHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + hint, __FILE__,__LINE__); \ + } \ + } +# else +# define CoinAssertDebug(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + "", __FILE__,__LINE__); \ + } \ + } +# define CoinAssertDebugHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + hint, __FILE__,__LINE__); \ + } \ + } +# endif +# endif +# if defined(__GNUC__) && __GNUC_PREREQ(2, 6) +# define CoinAssert(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + "", __FILE__, __LINE__); \ + } \ + } +# define CoinAssertHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + hint, __FILE__,__LINE__); \ + } \ + } +# else +# define CoinAssert(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + "", __FILE__,__LINE__); \ + } \ + } +# define CoinAssertHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + hint, __FILE__,__LINE__); \ + } \ + } +# endif +#endif + + +//############################################################################# +/** A function that tests the methods in the CoinError class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinErrorUnitTest(); + +#ifdef __LINE__ +#define CoinErrorFL(x, y, z) CoinError((x), (y), (z), __FILE__, __LINE__) +#endif + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinFactorization.hpp b/thirdparty/linux/include/coin/coin/CoinFactorization.hpp new file mode 100644 index 0000000..0a532bf --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinFactorization.hpp @@ -0,0 +1,2044 @@ +/* $Id: CoinFactorization.hpp 1767 2015-01-05 12:36:13Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + Authors + + John Forrest + + */ +#ifndef CoinFactorization_H +#define CoinFactorization_H +//#define COIN_ONE_ETA_COPY 100 + +#include <iostream> +#include <string> +#include <cassert> +#include <cstdio> +#include <cmath> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" + +class CoinPackedMatrix; +/** This deals with Factorization and Updates + + This class started with a parallel simplex code I was writing in the + mid 90's. The need for parallelism led to many complications and + I have simplified as much as I could to get back to this. + + I was aiming at problems where I might get speed-up so I was looking at dense + problems or ones with structure. This led to permuting input and output + vectors and to increasing the number of rows each rank-one update. This is + still in as a minor overhead. + + I have also put in handling for hyper-sparsity. I have taken out + all outer loop unrolling, dense matrix handling and most of the + book-keeping for slacks. Also I always use FTRAN approach to updating + even if factorization fairly dense. All these could improve performance. + + I blame some of the coding peculiarities on the history of the code + but mostly it is just because I can't do elegant code (or useful + comments). + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + +class CoinFactorization { + friend void CoinFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinFactorization ( ); + /// Copy constructor + CoinFactorization ( const CoinFactorization &other); + + /// Destructor + ~CoinFactorization ( ); + /// Delete all stuff (leaves as after CoinFactorization()) + void almostDestructor(); + /// Debug show object (shows one representation) + void show_self ( ) const; + /// Debug - save on file - 0 if no error + int saveFactorization (const char * file ) const; + /** Debug - restore from file - 0 if no error on file. + If factor true then factorizes as if called from ClpFactorization + */ + int restoreFactorization (const char * file , bool factor=false) ; + /// Debug - sort so can compare + void sort ( ) const; + /// = copy + CoinFactorization & operator = ( const CoinFactorization & other ); + //@} + + /**@name Do factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + /** When given as triplets. + Actually does factorization. maximumL is guessed maximum size of L part of + final factorization, maximumU of U part. These are multiplied by + areaFactor which can be computed by user or internally. + Arrays are copied in. I could add flag to delete arrays to save a + bit of memory. + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorize ( int numberRows, + int numberColumns, + CoinBigIndex numberElements, + CoinBigIndex maximumL, + CoinBigIndex maximumU, + const int indicesRow[], + const int indicesColumn[], const double elements[] , + int permutation[], + double areaFactor = 0.0); + /** Two part version for maximum flexibility + This part creates arrays for user to fill. + estimateNumberElements is safe estimate of number + returns 0 -okay, -99 memory */ + int factorizePart1 ( int numberRows, + int numberColumns, + CoinBigIndex estimateNumberElements, + int * indicesRow[], + int * indicesColumn[], + CoinFactorizationDouble * elements[], + double areaFactor = 0.0); + /** This is part two of factorization + Arrays belong to factorization and were returned by part 1 + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorizePart2 (int permutation[],int exactNumberElements); + /// Condition number - product of pivots after factorization + double conditionNumber() const; + + //@} + + /**@name general stuff such as permutation or status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Returns address of permute region + inline int *permute ( ) const { + return permute_.array(); + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + return pivotColumn_.array(); + } + /// Returns address of pivot region + inline CoinFactorizationDouble *pivotRegion ( ) const { + return pivotRegion_.array(); + } + /// Returns address of permuteBack region + inline int *permuteBack ( ) const { + return permuteBack_.array(); + } + /// Returns address of lastRow region + inline int *lastRow ( ) const { + return lastRow_.array(); + } + /** Returns address of pivotColumnBack region (also used for permuting) + Now uses firstCount to save memory allocation */ + inline int *pivotColumnBack ( ) const { + //return firstCount_.array(); + return pivotColumnBack_.array(); + } + /// Start of each row in L + inline CoinBigIndex * startRowL() const + { return startRowL_.array();} + + /// Start of each column in L + inline CoinBigIndex * startColumnL() const + { return startColumnL_.array();} + + /// Index of column in row for L + inline int * indexColumnL() const + { return indexColumnL_.array();} + + /// Row indices of L + inline int * indexRowL() const + { return indexRowL_.array();} + + /// Elements in L (row copy) + inline CoinFactorizationDouble * elementByRowL() const + { return elementByRowL_.array();} + + /// Number of Rows after iterating + inline int numberRowsExtra ( ) const { + return numberRowsExtra_; + } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Number in L + inline CoinBigIndex numberL() const + { return numberL_;} + + /// Base of L + inline CoinBigIndex baseL() const + { return baseL_;} + /// Maximum of Rows after iterating + inline int maximumRowsExtra ( ) const { + return maximumRowsExtra_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Total number of elements in factorization + inline int numberElements ( ) const { + return totalElements_; + } + /// Length of FT vector + inline int numberForrestTomlin ( ) const { + return numberInColumn_.array()[numberColumnsExtra_]; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + return areaFactor_; + } + inline void areaFactor ( double value ) { + areaFactor_=value; + } + /// Returns areaFactor but adjusted for dense + double adjustedAreaFactor() const; + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Level of detail of messages + inline int messageLevel ( ) const { + return messageLevel_ ; + } + void messageLevel ( int value ); + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + void maximumPivots ( int value ); + + /// Gets dense threshold + inline int denseThreshold() const + { return denseThreshold_;} + /// Sets dense threshold + inline void setDenseThreshold(int value) + { denseThreshold_ = value;} + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// true if Forrest Tomlin update, false if PFI + inline bool forrestTomlin() const + { return doForrestTomlin_;} + inline void setForrestTomlin(bool value) + { doForrestTomlin_=value;} + /// True if FT update and space + inline bool spaceForForrestTomlin() const + { + CoinBigIndex start = startColumnU_.array()[maximumColumnsExtra_]; + CoinBigIndex space = lengthAreaU_ - ( start + numberRowsExtra_ ); + return (space>=0)&&doForrestTomlin_; + } + //@} + + /**@name some simple stuff */ + //@{ + + /// Returns number of dense rows + inline int numberDense() const + { return numberDense_;} + + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + return lengthU_; + } + /// Setss number in U area + inline void setNumberElementsU(CoinBigIndex value) + { lengthU_ = value; } + /// Returns length of U area + inline CoinBigIndex lengthAreaU ( ) const { + return lengthAreaU_; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + return lengthL_; + } + /// Returns length of L area + inline CoinBigIndex lengthAreaL ( ) const { + return lengthAreaL_; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + return lengthR_; + } + /// Number of compressions done + inline CoinBigIndex numberCompressions() const + { return numberCompressions_;} + /// Number of entries in each row + inline int * numberInRow() const + { return numberInRow_.array();} + /// Number of entries in each column + inline int * numberInColumn() const + { return numberInColumn_.array();} + /// Elements of U + inline CoinFactorizationDouble * elementU() const + { return elementU_.array();} + /// Row indices of U + inline int * indexRowU() const + { return indexRowU_.array();} + /// Start of each column in U + inline CoinBigIndex * startColumnU() const + { return startColumnU_.array();} + /// Maximum number of Columns after iterating + inline int maximumColumnsExtra() + { return maximumColumnsExtra_;} + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + inline int biasLU() const + { return biasLU_;} + inline void setBiasLU(int value) + { biasLU_=value;} + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const + { return persistenceFlag_;} + void setPersistenceFlag(int value); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + /** Combines BtranU and delete elements + If deleted is NULL then delete elements + otherwise store where elements are + */ + void replaceColumnU ( CoinIndexedVector * regionSparse, + CoinBigIndex * deleted, + int internalPivotRow); +#ifdef ABC_USE_COIN_FACTORIZATION + /** returns empty fake vector carved out of existing + later - maybe use associated arrays */ + CoinIndexedVector * fakeVector(CoinIndexedVector * vector, + int already=0) const; + void deleteFakeVector(CoinIndexedVector * vector, + CoinIndexedVector * fakeVector) const; + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update already in U */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + int pivotRow); + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update in vector */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow); + /** Checks if can replace one Column in basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots */ + int checkReplacePart2 ( int pivotRow, + double btranAlpha, + double ftranAlpha, + double ftAlpha, + double acceptablePivot = 1.0e-8); + /** Replaces one Column to basis, + partial update already in U */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + int pivotRow, + double alpha ); + /** Replaces one Column to basis, + partial update in vector */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow, + double alpha ); + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + long regions + */ + int updateColumnFT ( CoinIndexedVector & regionSparse); + int updateColumnFTPart1 ( CoinIndexedVector & regionSparse) ; + void updateColumnFTPart2 ( CoinIndexedVector & regionSparse) ; + /** Updates one column (FTRAN) - long region + Tries to do FT update + puts partial update in vector */ + void updateColumnFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & partialUpdate, + int which); + /** Updates one column (FTRAN) long region */ + int updateColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) from regionFT + Tries to do FT update + number returned is negative if no room. + Also updates regionOther - long region*/ + int updateTwoColumnsFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & regionSparseOther); + /** Updates one column (BTRAN) - long region*/ + int updateColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) - long region */ + void updateColumnCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one column (BTRAN) - long region */ + void updateColumnTransposeCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one full column (FTRAN) - long region */ + void updateFullColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one full column (BTRAN) - long region */ + void updateFullColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column for dual steepest edge weights (FTRAN) - long region */ + void updateWeights ( CoinIndexedVector & regionSparse) const; + /// Returns true if wants tableauColumn in replaceColumn + inline bool wantsTableauColumn() const + {return false;} + /// Pivot tolerance + inline double minimumPivotTolerance ( ) const { + return pivotTolerance_ ; + } + inline void minimumPivotTolerance ( double value ) + { pivotTolerance(value);} + /// Says parallel + inline void setParallelMode(int value) + { parallelMode_=value;} + /// Sets solve mode + inline void setSolveMode(int value) + { parallelMode_ &= 3;parallelMode_ |= (value<<2);} + /// Sets solve mode + inline int solveMode() const + { return parallelMode_ >> 2;} + /// Update partial Ftran by R update + void updatePartialUpdate(CoinIndexedVector & partialUpdate); + /// Makes a non-singular basis by replacing variables + void makeNonSingular(int * COIN_RESTRICT sequence); +#endif + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3=false) ; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /** get sparse threshold */ + inline int sparseThreshold ( ) const + { return sparseThreshold_;} + /** set sparse threshold */ + void sparseThreshold ( int value ); + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization (return code number elements) + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + //@} + + /**@name various updates - none of which have been written! */ + //@{ + + /** Adds given elements to Basis and updates factorization, + can increase size of basis. Returns rank */ + int add ( CoinBigIndex numberElements, + int indicesRow[], + int indicesColumn[], double elements[] ); + + /** Adds one Column to basis, + can increase size of basis. Returns rank */ + int addColumn ( CoinBigIndex numberElements, + int indicesRow[], double elements[] ); + + /** Adds one Row to basis, + can increase size of basis. Returns rank */ + int addRow ( CoinBigIndex numberElements, + int indicesColumn[], double elements[] ); + + /// Deletes one Column from basis, returns rank + int deleteColumn ( int Row ); + /// Deletes one Row from basis, returns rank + int deleteRow ( int Row ); + + /** Replaces one Row in basis, + At present assumes just a singleton on row is in basis + returns 0=OK, 1=Probably OK, 2=singular, 3 no space */ + int replaceRow ( int whichRow, int numberElements, + const int indicesColumn[], const double elements[] ); + /// Takes out all entries for given rows + void emptyRows(int numberToEmpty, const int which[]); + //@} + /**@name used by ClpFactorization */ + /// See if worth going sparse + void checkSparse(); + /// For statistics +#if 0 //def CLP_FACTORIZATION_INSTRUMENT + inline bool collectStatistics() const + { return collectStatistics_;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { collectStatistics_ = onOff;} +#else + inline bool collectStatistics() const + { return true;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { } +#endif + /// The real work of constructors etc 0 just scalars, 1 bit normal + void gutsOfDestructor(int type=1); + /// 1 bit - tolerances etc, 2 more, 4 dummy arrays + void gutsOfInitialize(int type); + void gutsOfCopy(const CoinFactorization &other); + + /// Reset all sparsity etc statistics + void resetStatistics(); + + + //@} + + /**@name used by factorization */ + /// Gets space for a factorization, called by constructors + void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /** PreProcesses raw triplet data. + state is 0 - triplets, 1 - some counts etc , 2 - .. */ + void preProcess ( int state, + int possibleDuplicates = -1 ); + /// Does most of factorization + int factor ( ); +protected: + /** Does sparse phase of factorization + return code is <0 error, 0= finished */ + int factorSparse ( ); + /** Does sparse phase of factorization (for smaller problems) + return code is <0 error, 0= finished */ + int factorSparseSmall ( ); + /** Does sparse phase of factorization (for larger problems) + return code is <0 error, 0= finished */ + int factorSparseLarge ( ); + /** Does dense phase of factorization + return code is <0 error, 0= finished */ + int factorDense ( ); + + /// Pivots when just one other row so faster? + bool pivotOneOtherRow ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Row Singleton in factorization + bool pivotRowSingleton ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Column Singleton in factorization + bool pivotColumnSingleton ( int pivotRow, + int pivotColumn ); + + /** Gets space for one Column with given length, + may have to do compression (returns True if successful), + also moves existing vector, + extraNeeded is over and above present */ + bool getColumnSpace ( int iColumn, + int extraNeeded ); + + /** Reorders U so contiguous and in order (if there is space) + Returns true if it could */ + bool reorderU(); + /** getColumnSpaceIterateR. Gets space for one extra R element in Column + may have to do compression (returns true) + also moves existing vector */ + bool getColumnSpaceIterateR ( int iColumn, double value, + int iRow); + /** getColumnSpaceIterate. Gets space for one extra U element in Column + may have to do compression (returns true) + also moves existing vector. + Returns -1 if no memory or where element was put + Used by replaceRow (turns off R version) */ + CoinBigIndex getColumnSpaceIterate ( int iColumn, double value, + int iRow); + /** Gets space for one Row with given length, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpace ( int iRow, int extraNeeded ); + + /** Gets space for one Row with given length while iterating, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpaceIterate ( int iRow, + int extraNeeded ); + /// Checks that row and column copies look OK + void checkConsistency ( ); + /// Adds a link in chain of equal counts + inline void addLink ( int index, int count ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = firstCount[count]; + lastCount[index] = -2 - count; + if ( next < 0 ) { + //first with that count + firstCount[count] = index; + nextCount[index] = -1; + } else { + firstCount[count] = index; + nextCount[index] = next; + lastCount[next] = index; + }} + /// Deletes a link in chain of equal counts + inline void deleteLink ( int index ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = nextCount[index]; + int last = lastCount[index]; + if ( last >= 0 ) { + nextCount[last] = next; + } else { + int count = -last - 2; + + firstCount[count] = next; + } + if ( next >= 0 ) { + lastCount[next] = last; + } + nextCount[index] = -2; + lastCount[index] = -2; + return; + } + /// Separate out links with same row/column count + void separateLinks(int count,bool rowsFirst); + /// Cleans up at end of factorization + void cleanup ( ); + + /// Updates part of column (FTRANL) + void updateColumnL ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when densish + void updateColumnLDensish ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparse + void updateColumnLSparse ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparsish + void updateColumnLSparsish ( CoinIndexedVector * region, int * indexIn ) const; + + /// Updates part of column (FTRANR) without FT update + void updateColumnR ( CoinIndexedVector * region ) const; + /** Updates part of column (FTRANR) with FT update. + Also stores update after L and R */ + void updateColumnRFT ( CoinIndexedVector * region, int * indexIn ); + + /// Updates part of column (FTRANU) + void updateColumnU ( CoinIndexedVector * region, int * indexIn) const; + + /// Updates part of column (FTRANU) when sparse + void updateColumnUSparse ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) when sparsish + void updateColumnUSparsish ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) + int updateColumnUDensish ( double * COIN_RESTRICT region, + int * COIN_RESTRICT regionIndex) const; + /// Updates part of 2 columns (FTRANU) real work + void updateTwoColumnsUDensish ( + int & numberNonZero1, + double * COIN_RESTRICT region1, + int * COIN_RESTRICT index1, + int & numberNonZero2, + double * COIN_RESTRICT region2, + int * COIN_RESTRICT index2) const; + /// Updates part of column PFI (FTRAN) (after rest) + void updateColumnPFI ( CoinIndexedVector * regionSparse) const; + /// Permutes back at end of updateColumn + void permuteBack ( CoinIndexedVector * regionSparse, + CoinIndexedVector * outVector) const; + + /// Updates part of column transpose PFI (BTRAN) (before rest) + void updateColumnTransposePFI ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU), + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeU ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparsish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparsish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when densish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUDensish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparse, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparse ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU) by column + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUByColumn ( CoinIndexedVector * region, + int smallestIndex) const; + + /// Updates part of column transpose (BTRANR) + void updateColumnTransposeR ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when dense + void updateColumnTransposeRDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when sparse + void updateColumnTransposeRSparse ( CoinIndexedVector * region ) const; + + /// Updates part of column transpose (BTRANL) + void updateColumnTransposeL ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by column + void updateColumnTransposeLDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by row + void updateColumnTransposeLByRow ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparsish by row + void updateColumnTransposeLSparsish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparse (by Row) + void updateColumnTransposeLSparse ( CoinIndexedVector * region ) const; +public: + /** Replaces one Column to basis for PFI + returns 0=OK, 1=Probably OK, 2=singular, 3=no room. + In this case region is not empty - it is incoming variable (updated) + */ + int replaceColumnPFI ( CoinIndexedVector * regionSparse, + int pivotRow, double alpha); +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; + /********************************* START LARGE TEMPLATE ********/ +#ifdef INT_IS_8 +#define COINFACTORIZATION_BITS_PER_INT 64 +#define COINFACTORIZATION_SHIFT_PER_INT 6 +#define COINFACTORIZATION_MASK_PER_INT 0x3f +#else +#define COINFACTORIZATION_BITS_PER_INT 32 +#define COINFACTORIZATION_SHIFT_PER_INT 5 +#define COINFACTORIZATION_MASK_PER_INT 0x1f +#endif + template <class T> inline bool + pivot ( int pivotRow, + int pivotColumn, + CoinBigIndex pivotRowPosition, + CoinBigIndex pivotColumnPosition, + CoinFactorizationDouble work[], + unsigned int workArea2[], + int increment2, + T markRow[] , + int largeInteger) +{ + int *indexColumnU = indexColumnU_.array(); + CoinBigIndex *startColumnU = startColumnU_.array(); + int *numberInColumn = numberInColumn_.array(); + CoinFactorizationDouble *elementU = elementU_.array(); + int *indexRowU = indexRowU_.array(); + CoinBigIndex *startRowU = startRowU_.array(); + int *numberInRow = numberInRow_.array(); + CoinFactorizationDouble *elementL = elementL_.array(); + int *indexRowL = indexRowL_.array(); + int *saveColumn = saveColumn_.array(); + int *nextRow = nextRow_.array(); + int *lastRow = lastRow_.array() ; + + //store pivot columns (so can easily compress) + int numberInPivotRow = numberInRow[pivotRow] - 1; + CoinBigIndex startColumn = startColumnU[pivotColumn]; + int numberInPivotColumn = numberInColumn[pivotColumn] - 1; + CoinBigIndex endColumn = startColumn + numberInPivotColumn + 1; + int put = 0; + CoinBigIndex startRow = startRowU[pivotRow]; + CoinBigIndex endRow = startRow + numberInPivotRow + 1; + + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRow; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumnU[pivotColumnPosition]; + if ( iColumn != pivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRow ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumnU[i]; + } + } + assert (pivotColumnPosition<endRow); + assert (indexColumnU[pivotColumnPosition]==pivotColumn); + pivotColumnPosition++; + for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + saveColumn[put++] = indexColumnU[pivotColumnPosition]; + } + //take out this bit of indexColumnU + int next = nextRow[pivotRow]; + int last = lastRow[pivotRow]; + + nextRow[last] = next; + lastRow[next] = last; + nextRow[pivotRow] = numberGoodU_; //use for permute + lastRow[pivotRow] = -2; + numberInRow[pivotRow] = 0; + //store column in L, compress in U and take column out + CoinBigIndex l = lengthL_; + + if ( l + numberInPivotColumn > lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + return false; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberInPivotColumn; + lengthL_ += numberInPivotColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumn; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRowU[pivotRowPosition]; + if ( iRow != pivotRow ) { + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + markRow[iRow] = static_cast<T>(l - lSave); + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumn; i < pivotRowPosition; i++ ) { + int iRow = indexRowU[i]; + + markRow[iRow] = static_cast<T>(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[i]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition<endColumn); + assert (indexRowU[pivotRowPosition]==pivotRow); + CoinFactorizationDouble pivotElement = elementU[pivotRowPosition]; + CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement; + + pivotRegion_.array()[numberGoodU_] = pivotMultiplier; + pivotRowPosition++; + for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRowU[pivotRowPosition]; + + markRow[iRow] = static_cast<T>(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[pivotRow] = static_cast<T>(largeInteger); + //compress pivot column (move pivot to front including saved) + numberInColumn[pivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberInPivotColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberInPivotRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberInPivotRow * numberInPivotColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumn = startColumnU[iColumn]; + CoinBigIndex endColumn = startColumn + numberInColumn[iColumn]; + int iRow = indexRowU[startColumn]; + CoinFactorizationDouble value = elementU[startColumn]; + double largest; + CoinBigIndex put = startColumn; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumn + 1; i < endColumn; i++ ) { + iRow = indexRowU[i]; + value = elementU[i]; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + //keep + indexRowU[put] = iRow; + elementU[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + elementU[put] = elementU[startColumn]; + indexRowU[put] = indexRowU[startColumn]; + if ( positionLargest == startColumn ) { + positionLargest = put; //follow if was largest + } + put++; + elementU[startColumn] = thisPivotValue; + indexRowU[startColumn] = pivotRow; + //clean up counts + startColumn++; + numberInColumn[iColumn] = put - startColumn; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumnU[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumnU[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberInPivotColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) { + return false; + } + //redo starts + if (positionLargest >= 0) + positionLargest = positionLargest + startColumnU[iColumn] - startColumn; + startColumn = startColumnU[iColumn]; + put = startColumn + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberInPivotColumn; j++ ) { + value = work[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + work[j] = 0.0; + assert (put<lengthAreaU_); + elementU[put] = value; + indexRowU[put] = indexL[j]; + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + work[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumn; + //move largest + if ( positionLargest >= 0 ) { + value = elementU[positionLargest]; + iRow = indexRowU[positionLargest]; + elementU[positionLargest] = elementU[startColumn]; + indexRowU[positionLargest] = indexRowU[startColumn]; + elementU[startColumn] = value; + indexRowU[startColumn] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast<T>(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex; + + saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast<T>(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[pivotRow] = static_cast<T>(largeInteger+1); + //modify linked list for pivots + deleteLink ( pivotRow ); + deleteLink ( pivotColumn + numberRows_ ); + totalElements_ += added; + return true; +} + + /********************************* END LARGE TEMPLATE ********/ + //@} +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// How much to multiply areas by + double areaFactor_; + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Rows after iterating + int numberRowsExtra_; + /// Maximum number of Rows after iterating + int maximumRowsExtra_; + /// Number of Columns in factorization + int numberColumns_; + /// Number of Columns after iterating + int numberColumnsExtra_; + /// Maximum number of Columns after iterating + int maximumColumnsExtra_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Number factorized in L + int numberGoodL_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Number of elements in U (to go) + /// or while iterating total overall + CoinBigIndex totalElements_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Pivot order for each Column + CoinIntArrayWithLength pivotColumn_; + /// Permutation vector for pivot row order + CoinIntArrayWithLength permute_; + /// DePermutation vector for pivot row order + CoinIntArrayWithLength permuteBack_; + /// Inverse Pivot order for each Column + CoinIntArrayWithLength pivotColumnBack_; + /// Status of factorization + int status_; + + /** 0 - no increasing rows - no permutations, + 1 - no increasing rows but permutations + 2 - increasing rows + - taken out as always 2 */ + //int increasingRows_; + + /// Number of trials before rejection + int numberTrials_; + /// Start of each Row as pointer + CoinBigIndexArrayWithLength startRowU_; + + /// Number in each Row + CoinIntArrayWithLength numberInRow_; + + /// Number in each Column + CoinIntArrayWithLength numberInColumn_; + + /// Number in each Column including pivoted + CoinIntArrayWithLength numberInColumnPlus_; + + /** First Row/Column with count of k, + can tell which by offset - Rows then Columns */ + CoinIntArrayWithLength firstCount_; + + /// Next Row/Column with count + CoinIntArrayWithLength nextCount_; + + /// Previous Row/Column with count + CoinIntArrayWithLength lastCount_; + + /// Next Column in memory order + CoinIntArrayWithLength nextColumn_; + + /// Previous Column in memory order + CoinIntArrayWithLength lastColumn_; + + /// Next Row in memory order + CoinIntArrayWithLength nextRow_; + + /// Previous Row in memory order + CoinIntArrayWithLength lastRow_; + + /// Columns left to do in a single pivot + CoinIntArrayWithLength saveColumn_; + + /// Marks rows to be updated + CoinIntArrayWithLength markRow_; + + /// Detail in messages + int messageLevel_; + + /// Larger of row and column size + int biggerDimension_; + + /// Base address for U (may change) + CoinIntArrayWithLength indexColumnU_; + + /// Pivots for L + CoinIntArrayWithLength pivotRowL_; + + /// Inverses of pivot values + CoinFactorizationDoubleArrayWithLength pivotRegion_; + + /// Number of slacks at beginning of U + int numberSlacks_; + + /// Number in U + int numberU_; + + /// Maximum space used in U + CoinBigIndex maximumU_; + + /// Base of U is always 0 + //int baseU_; + + /// Length of U + CoinBigIndex lengthU_; + + /// Length of area reserved for U + CoinBigIndex lengthAreaU_; + +/// Elements of U + CoinFactorizationDoubleArrayWithLength elementU_; + +/// Row indices of U + CoinIntArrayWithLength indexRowU_; + +/// Start of each column in U + CoinBigIndexArrayWithLength startColumnU_; + +/// Converts rows to columns in U + CoinBigIndexArrayWithLength convertRowToColumnU_; + + /// Number in L + CoinBigIndex numberL_; + +/// Base of L + CoinBigIndex baseL_; + + /// Length of L + CoinBigIndex lengthL_; + + /// Length of area reserved for L + CoinBigIndex lengthAreaL_; + + /// Elements of L + CoinFactorizationDoubleArrayWithLength elementL_; + + /// Row indices of L + CoinIntArrayWithLength indexRowL_; + + /// Start of each column in L + CoinBigIndexArrayWithLength startColumnL_; + + /// true if Forrest Tomlin update, false if PFI + bool doForrestTomlin_; + + /// Number in R + int numberR_; + + /// Length of R stuff + CoinBigIndex lengthR_; + + /// length of area reserved for R + CoinBigIndex lengthAreaR_; + + /// Elements of R + CoinFactorizationDouble *elementR_; + + /// Row indices for R + int *indexRowR_; + + /// Start of columns for R + CoinBigIndexArrayWithLength startColumnR_; + + /// Dense area + double * denseArea_; + + /// Dense area - actually used (for alignment etc) + double * denseAreaAddress_; + + /// Dense permutation + int * densePermute_; + + /// Number of dense rows + int numberDense_; + + /// Dense threshold + int denseThreshold_; + + /// First work area + CoinFactorizationDoubleArrayWithLength workArea_; + + /// Second work area + CoinUnsignedIntArrayWithLength workArea2_; + + /// Number of compressions done + CoinBigIndex numberCompressions_; + +public: + /// Below are all to collect + mutable double ftranCountInput_; + mutable double ftranCountAfterL_; + mutable double ftranCountAfterR_; + mutable double ftranCountAfterU_; + mutable double btranCountInput_; + mutable double btranCountAfterU_; + mutable double btranCountAfterR_; + mutable double btranCountAfterL_; + + /// We can roll over factorizations + mutable int numberFtranCounts_; + mutable int numberBtranCounts_; + + /// While these are average ratios collected over last period + double ftranAverageAfterL_; + double ftranAverageAfterR_; + double ftranAverageAfterU_; + double btranAverageAfterU_; + double btranAverageAfterR_; + double btranAverageAfterL_; +protected: + + /// For statistics +#if 0 + mutable bool collectStatistics_; +#else +#define collectStatistics_ 1 +#endif + + /// Below this use sparse technology - if 0 then no L row copy + int sparseThreshold_; + + /// And one for "sparsish" + int sparseThreshold2_; + + /// Start of each row in L + CoinBigIndexArrayWithLength startRowL_; + + /// Index of column in row for L + CoinIntArrayWithLength indexColumnL_; + + /// Elements in L (row copy) + CoinFactorizationDoubleArrayWithLength elementByRowL_; + + /// Sparse regions + mutable CoinIntArrayWithLength sparse_; + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + int biasLU_; + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + int persistenceFlag_; +#ifdef ABC_USE_COIN_FACTORIZATION + /// Says if parallel + int parallelMode_; +#endif + //@} +}; +// Dense coding +#ifdef COIN_HAS_LAPACK +#ifndef COIN_FACTORIZATION_DENSE_CODE +#define COIN_FACTORIZATION_DENSE_CODE 1 +#endif +#endif +#ifdef COIN_FACTORIZATION_DENSE_CODE +/* Type of Fortran integer translated into C */ +#ifndef ipfint +//typedef ipfint FORTRAN_INTEGER_TYPE ; +typedef int ipfint; +typedef const int cipfint; +#endif +#endif +#endif +// Extra for ugly include +#ifdef UGLY_COIN_FACTOR_CODING +#define FAC_UNSET (FAC_SET+1) +{ + goodPivot=false; + //store pivot columns (so can easily compress) + CoinBigIndex startColumnThis = startColumn[iPivotColumn]; + CoinBigIndex endColumn = startColumnThis + numberDoColumn + 1; + int put = 0; + CoinBigIndex startRowThis = startRow[iPivotRow]; + CoinBigIndex endRow = startRowThis + numberDoRow + 1; + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRowThis; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumn[pivotColumnPosition]; + if ( iColumn != iPivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRowThis ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumn[i]; + } + } + assert (pivotColumnPosition<endRow); + assert (indexColumn[pivotColumnPosition]==iPivotColumn); + pivotColumnPosition++; + for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + saveColumn[put++] = indexColumn[pivotColumnPosition]; + } + //take out this bit of indexColumn + int next = nextRow[iPivotRow]; + int last = lastRow[iPivotRow]; + + nextRow[last] = next; + lastRow[next] = last; + nextRow[iPivotRow] = numberGoodU_; //use for permute + lastRow[iPivotRow] = -2; + numberInRow[iPivotRow] = 0; + //store column in L, compress in U and take column out + CoinBigIndex l = lengthL_; + // **** HORRID coding coming up but a goto seems best! + { + if ( l + numberDoColumn > lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + goto BAD_PIVOT; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberDoColumn; + lengthL_ += numberDoColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumnThis; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRow[pivotRowPosition]; + if ( iRow != iPivotRow ) { + indexRowL[l] = iRow; + elementL[l] = element[pivotRowPosition]; + markRow[iRow] = l - lSave; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumnThis; i < pivotRowPosition; i++ ) { + int iRow = indexRow[i]; + + markRow[iRow] = l - lSave; + indexRowL[l] = iRow; + elementL[l] = element[i]; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition<endColumn); + assert (indexRow[pivotRowPosition]==iPivotRow); + CoinFactorizationDouble pivotElement = element[pivotRowPosition]; + CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement; + + pivotRegion_.array()[numberGoodU_] = pivotMultiplier; + pivotRowPosition++; + for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRow[pivotRowPosition]; + + markRow[iRow] = l - lSave; + indexRowL[l] = iRow; + elementL[l] = element[pivotRowPosition]; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[iPivotRow] = FAC_SET; + //compress pivot column (move pivot to front including saved) + numberInColumn[iPivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberDoColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberDoRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberDoRow * numberDoColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumnThis = startColumn[iColumn]; + CoinBigIndex endColumn = startColumnThis + numberInColumn[iColumn]; + int iRow = indexRow[startColumnThis]; + CoinFactorizationDouble value = element[startColumnThis]; + double largest; + CoinBigIndex put = startColumnThis; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumnThis + 1; i < endColumn; i++ ) { + iRow = indexRow[i]; + value = element[i]; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + //keep + indexRow[put] = iRow; + element[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + element[put] = element[startColumnThis]; + indexRow[put] = indexRow[startColumnThis]; + if ( positionLargest == startColumnThis ) { + positionLargest = put; //follow if was largest + } + put++; + element[startColumnThis] = thisPivotValue; + indexRow[startColumnThis] = iPivotRow; + //clean up counts + startColumnThis++; + numberInColumn[iColumn] = put - startColumnThis; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumn[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumn[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberDoColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberDoColumn ) ) { + goto BAD_PIVOT; + } + //redo starts + positionLargest = positionLargest + startColumn[iColumn] - startColumnThis; + startColumnThis = startColumn[iColumn]; + put = startColumnThis + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberDoColumn; j++ ) { + value = workArea[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + workArea[j] = 0.0; + element[put] = value; + indexRow[put] = indexL[j]; + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + workArea[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumnThis; + //move largest + if ( positionLargest >= 0 ) { + value = element[positionLargest]; + iRow = indexRow[positionLargest]; + element[positionLargest] = element[startColumnThis]; + indexRow[positionLargest] = indexRow[startColumnThis]; + element[startColumnThis] = value; + indexRow[startColumnThis] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberDoColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberDoColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex; + + saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[iPivotRow] = FAC_UNSET; + //modify linked list for pivots + deleteLink ( iPivotRow ); + deleteLink ( iPivotColumn + numberRows_ ); + totalElements_ += added; + goodPivot= true; + // **** UGLY UGLY UGLY + } + BAD_PIVOT: + + ; +} +#undef FAC_UNSET +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinFileIO.hpp b/thirdparty/linux/include/coin/coin/CoinFileIO.hpp new file mode 100644 index 0000000..20be1a9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinFileIO.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinFileIO.hpp 1439 2011-06-13 16:31:21Z stefan $ */ +// Copyright (C) 2005, COIN-OR. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFileIO_H +#define CoinFileIO_H + +#include <string> + +/// Base class for FileIO classes. +class CoinFileIOBase +{ +public: + /// Constructor. + /// @param fileName The name of the file used by this object. + CoinFileIOBase (const std::string &fileName); + + /// Destructor. + ~CoinFileIOBase (); + + /// Return the name of the file used by this object. + const char *getFileName () const; + + /// Return the method of reading being used + inline std::string getReadType () const + { return readType_.c_str();} +protected: + std::string readType_; +private: + CoinFileIOBase (); + CoinFileIOBase (const CoinFileIOBase &); + + std::string fileName_; +}; + +/// Abstract base class for file input classes. +class CoinFileInput: public CoinFileIOBase +{ +public: + /// indicates whether CoinFileInput supports gzip'ed files + static bool haveGzipSupport(); + /// indicates whether CoinFileInput supports bzip2'ed files + static bool haveBzip2Support(); + + /// Factory method, that creates a CoinFileInput (more precisely + /// a subclass of it) for the file specified. This method reads the + /// first few bytes of the file and determines if this is a compressed + /// or a plain file and returns the correct subclass to handle it. + /// If the file does not exist or uses a compression not compiled in + /// an exception is thrown. + /// @param fileName The file that should be read. + static CoinFileInput *create (const std::string &fileName); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileInput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileInput (); + + /// Read a block of data from the file, similar to fread. + /// @param buffer Address of a buffer to store the data into. + /// @param size Number of bytes to read (buffer should be large enough). + /// @return Number of bytes read. + virtual int read (void *buffer, int size) = 0; + + /// Reads up to (size-1) characters an stores them into the buffer, + /// similar to fgets. + /// Reading ends, when EOF or a newline occurs or (size-1) characters have + /// been read. The resulting string is terminated with '\0'. If reading + /// ends due to an encoutered newline, the '\n' is put into the buffer, + /// before the '\0' is appended. + /// @param buffer The buffer to put the string into. + /// @param size The size of the buffer in characters. + /// @return buffer on success, or 0 if no characters have been read. + virtual char *gets (char *buffer, int size) = 0; +}; + +/// Abstract base class for file output classes. +class CoinFileOutput: public CoinFileIOBase +{ +public: + + /// The compression method. + enum Compression { + COMPRESS_NONE = 0, ///< No compression. + COMPRESS_GZIP = 1, ///< gzip compression. + COMPRESS_BZIP2 = 2 ///< bzip2 compression. + }; + + /// Returns whether the specified compression method is supported + /// (i.e. was compiled into COIN). + static bool compressionSupported (Compression compression); + + /// Factory method, that creates a CoinFileOutput (more precisely + /// a subclass of it) for the file specified. If the compression method + /// is not supported an exception is thrown (so use compressionSupported + /// first, if this is a problem). The reason for not providing direct + /// access to the subclasses (and using such a method instead) is that + /// depending on the build configuration some of the classes are not + /// available (or functional). This way we can handle all required ifdefs + /// here instead of polluting other files. + /// @param fileName The file that should be read. + /// @param compression Compression method used. + static CoinFileOutput *create (const std::string &fileName, + Compression compression); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileOutput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileOutput (); + + /// Write a block of data to the file, similar to fwrite. + /// @param buffer Address of a buffer containing the data to be written. + /// @param size Number of bytes to write. + /// @return Number of bytes written. + virtual int write (const void * buffer, int size) = 0; + + /// Write a string to the file (like fputs). + /// Just as with fputs no trailing newline is inserted! + /// The terminating '\0' is not written to the file. + /// The default implementation determines the length of the string + /// and calls write on it. + /// @param s The zero terminated string to be written. + /// @return true on success, false on error. + virtual bool puts (const char *s); + + /// Convenience method: just a 'puts(s.c_str())'. + inline bool puts (const std::string &s) + { + return puts (s.c_str ()); + } +}; + +/*! \relates CoinFileInput + \brief Test if the given string looks like an absolute file path + + The criteria are: + - unix: string begins with `/' + - windows: string begins with `\' or with `drv:' (drive specifier) +*/ +bool fileAbsPath (const std::string &path) ; + +/*! \relates CoinFileInput + \brief Test if the file is readable, using likely versions of the file + name, and return the name that worked. + + The file name is constructed from \p name using the following rules: + <ul> + <li> An absolute path is not modified. + <li> If the name begins with `~', an attempt is made to replace `~' + with the value of the environment variable HOME. + <li> If a default prefix (\p dfltPrefix) is provided, it is + prepended to the name. + </ul> + If the constructed file name cannot be opened, and CoinUtils was built + with support for compressed files, fileCoinReadable will try any + standard extensions for supported compressed files. + + The value returned in \p name is the file name that actually worked. +*/ +bool fileCoinReadable(std::string &name, + const std::string &dfltPrefix = std::string("")); +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinFinite.hpp b/thirdparty/linux/include/coin/coin/CoinFinite.hpp new file mode 100644 index 0000000..71b5b65 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinFinite.hpp @@ -0,0 +1,34 @@ +/* $Id: CoinFinite.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* Defines COIN_DBL_MAX and relatives and provides CoinFinite and CoinIsnan. */ + +#ifndef CoinFinite_H +#define CoinFinite_H + +#include <limits> + +//============================================================================= +// Smallest positive double value and Plus infinity (double and int) + +#if 1 +const double COIN_DBL_MIN = (std::numeric_limits<double>::min)(); +const double COIN_DBL_MAX = (std::numeric_limits<double>::max)(); +const int COIN_INT_MAX = (std::numeric_limits<int>::max)(); +const double COIN_INT_MAX_AS_DOUBLE = (std::numeric_limits<int>::max)(); +#else +#define COIN_DBL_MIN (std::numeric_limits<double>::min()) +#define COIN_DBL_MAX (std::numeric_limits<double>::max()) +#define COIN_INT_MAX (std::numeric_limits<int>::max()) +#define COIN_INT_MAX_AS_DOUBLE (std::numeric_limits<int>::max()) +#endif + +/** checks if a double value is finite (not infinity and not NaN) */ +extern bool CoinFinite(double val); + +/** checks if a double value is not a number */ +extern bool CoinIsnan(double val); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinFloatEqual.hpp b/thirdparty/linux/include/coin/coin/CoinFloatEqual.hpp new file mode 100644 index 0000000..d5edfff --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinFloatEqual.hpp @@ -0,0 +1,177 @@ +/* $Id: CoinFloatEqual.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFloatEqual_H +#define CoinFloatEqual_H + +#include <algorithm> +#include <cmath> + +#include "CoinFinite.hpp" + +/*! \file CoinFloatEqual.hpp + \brief Function objects for testing equality of real numbers. + + Two objects are provided; one tests for equality to an absolute tolerance, + one to a scaled tolerance. The tests will handle IEEE floating point, but + note that infinity == infinity. Mathematicians are rolling in their graves, + but this matches the behaviour for the common practice of using + <code>DBL_MAX</code> (<code>numeric_limits<double>::max()</code>, or similar + large finite number) as infinity. + + <p> + Example usage: + @verbatim + double d1 = 3.14159 ; + double d2 = d1 ; + double d3 = d1+.0001 ; + + CoinAbsFltEq eq1 ; + CoinAbsFltEq eq2(.001) ; + + assert( eq1(d1,d2) ) ; + assert( !eq1(d1,d3) ) ; + assert( eq2(d1,d3) ) ; + @endverbatim + CoinRelFltEq follows the same pattern. */ + +/*! \brief Equality to an absolute tolerance + + Operands are considered equal if their difference is within an epsilon ; + the test does not consider the relative magnitude of the operands. +*/ + +class CoinAbsFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + return (fabs(f1-f2) < epsilon_) ; } + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor + + Default tolerance is 1.0e-10. + */ + + CoinAbsFltEq () : epsilon_(1.e-10) {} + + //! Alternate constructor with epsilon as a parameter + + CoinAbsFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinAbsFltEq () {} + + //! Copy constructor + + CoinAbsFltEq (const CoinAbsFltEq& src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinAbsFltEq& operator= (const CoinAbsFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + + private: + + /*! \name Private member data */ + //@{ + + //! Equality tolerance. + + double epsilon_ ; + + //@} + +} ; + + + +/*! \brief Equality to a scaled tolerance + + Operands are considered equal if their difference is within a scaled + epsilon calculated as epsilon_*(1+CoinMax(|f1|,|f2|)). +*/ + +class CoinRelFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; + + double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; + + return (fabs(f1-f2) <= epsilon_*(1+tol)) ; } + + /*! \name Constructors and destructors */ + //@{ + +#ifndef COIN_FLOAT + /*! Default constructor + + Default tolerance is 1.0e-10. + */ + CoinRelFltEq () : epsilon_(1.e-10) {} +#else + /*! Default constructor + + Default tolerance is 1.0e-6. + */ + CoinRelFltEq () : epsilon_(1.e-6) {} ; // as float +#endif + + //! Alternate constructor with epsilon as a parameter + + CoinRelFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinRelFltEq () {} + + //! Copy constructor + + CoinRelFltEq (const CoinRelFltEq & src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinRelFltEq& operator= (const CoinRelFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + +private: + + /*! \name Private member data */ + //@{ + + //! Base equality tolerance + + double epsilon_ ; + + //@} + +} ; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinHelperFunctions.hpp b/thirdparty/linux/include/coin/coin/CoinHelperFunctions.hpp new file mode 100644 index 0000000..3409bbc --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinHelperFunctions.hpp @@ -0,0 +1,1111 @@ +/* $Id: CoinHelperFunctions.hpp 1679 2013-12-05 11:27:45Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinHelperFunctions_H +#define CoinHelperFunctions_H + +#include "CoinUtilsConfig.h" + +#if defined(_MSC_VER) +# include <direct.h> +# include <cctype> +# define getcwd _getcwd +# include <cctype> +#else +# include <unistd.h> +#endif +//#define USE_MEMCPY + +#include <cstdlib> +#include <cstdio> +#include <algorithm> +#include "CoinTypes.hpp" +#include "CoinError.hpp" + +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +//############################################################################# + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The arrays are given by pointers to their + first entries and by the size of the source array. Overlapping arrays are + handled correctly. */ + +template <class T> inline void +CoinCopyN(register const T* from, const int size, register T* to) +{ + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinCopyN", ""); +#endif + + register int n = (size + 7) / 8; + if (to > from) { + register const T* downfrom = from + size; + register T* downto = to + size; + // Use Duff's device to copy + switch (size % 8) { + case 0: do{ *--downto = *--downfrom; + case 7: *--downto = *--downfrom; + case 6: *--downto = *--downfrom; + case 5: *--downto = *--downfrom; + case 4: *--downto = *--downfrom; + case 3: *--downto = *--downfrom; + case 2: *--downto = *--downfrom; + case 1: *--downto = *--downfrom; + }while(--n>0); + } + } else { + // Use Duff's device to copy + --from; + --to; + switch (size % 8) { + case 0: do{ *++to = *++from; + case 7: *++to = *++from; + case 6: *++to = *++from; + case 5: *++to = *++from; + case 4: *++to = *++from; + case 3: *++to = *++from; + case 2: *++to = *++from; + case 1: *++to = *++from; + }while(--n>0); + } + } +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The source array is given by its first and + "after last" entry; the target array is given by its first entry. + Overlapping arrays are handled correctly. + + All of the various CoinCopyN variants use an int for size. On 64-bit + architectures, the address diff last-first will be a 64-bit quantity. + Given that everything else uses an int, I'm going to choose to kick + the difference down to int. -- lh, 100823 -- +*/ +template <class T> inline void +CoinCopy(register const T* first, register const T* last, register T* to) +{ + CoinCopyN(first, static_cast<int>(last-first), to); +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinMemcpyN which can be used for atomic data */ +template <class T> inline void +CoinDisjointCopyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinDisjointCopyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinDisjointCopyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#else + CoinCopyN(from, size, to); +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The source array is given by its first and "after + last" entry; the target array is given by its first entry. */ +template <class T> inline void +CoinDisjointCopy(register const T* first, register const T* last, + register T* to) +{ + CoinDisjointCopyN(first, static_cast<int>(last - first), to); +} + +//----------------------------------------------------------------------------- + +/*! \brief Return an array of length \p size filled with input from \p array, + or null if \p array is null. +*/ + +template <class T> inline T* +CoinCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + std::memcpy(arrayNew,array,size*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + + +/*! \brief Return an array of length \p size filled with first copySize from \p array, + or null if \p array is null. +*/ + +template <class T> inline T* +CoinCopyOfArrayPartial( const T * array, const int size,const int copySize) +{ + if (array||size) { + T * arrayNew = new T[size]; + assert (copySize<=size); + std::memcpy(arrayNew,array,copySize*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + +/*! \brief Return an array of length \p size filled with input from \p array, + or filled with (scalar) \p value if \p array is null +*/ + +template <class T> inline T* +CoinCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + int i; + for (i=0;i<size;i++) + arrayNew[i] = value; + } + return arrayNew; +} + + +/*! \brief Return an array of length \p size filled with input from \p array, + or filled with zero if \p array is null +*/ + +template <class T> inline T* +CoinCopyOfArrayOrZero( const T * array , const int size) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + std::memset(arrayNew,0,size*sizeof(T)); + } + return arrayNew; +} + + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + alternative coding if USE_MEMCPY defined*/ +#ifndef COIN_USE_RESTRICT +template <class T> inline void +CoinMemcpyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER +#ifdef USE_MEMCPY + // Use memcpy - seems a lot faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif +#endif + std::memcpy(to,from,size*sizeof(T)); +#else + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#endif +#else + CoinCopyN(from, size, to); +#endif +} +#else +template <class T> inline void +CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to) +{ +#ifdef USE_MEMCPY + std::memcpy(to,from,size*sizeof(T)); +#else + T * COIN_RESTRICT put = to; + const T * COIN_RESTRICT get = from; + for ( ; 0<size ; --size) + *put++ = *get++; +#endif +} +#endif + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The source array is given by its first and "after + last" entry; the target array is given by its first entry. */ +template <class T> inline void +CoinMemcpy(register const T* first, register const T* last, + register T* to) +{ + CoinMemcpyN(first, static_cast<int>(last - first), to); +} + +//############################################################################# + +/** This helper function fills an array with a given value. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinZero to allow for memset. */ +template <class T> inline void +CoinFillN(register T* to, const int size, register const T value) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinFillN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = value; + to[1] = value; + to[2] = value; + to[3] = value; + to[4] = value; + to[5] = value; + to[6] = value; + to[7] = value; + } + switch (size % 8) { + case 7: to[6] = value; + case 6: to[5] = value; + case 5: to[4] = value; + case 4: to[3] = value; + case 3: to[2] = value; + case 2: to[1] = value; + case 1: to[0] = value; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = value; + case 7: *++to = value; + case 6: *++to = value; + case 5: *++to = value; + case 4: *++to = value; + case 3: *++to = value; + case 2: *++to = value; + case 1: *++to = value; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with a given value. For speed 8 + entries are filled at a time. The array is given by its first and "after + last" entry. */ +template <class T> inline void +CoinFill(register T* first, register T* last, const T value) +{ + CoinFillN(first, last - first, value); +} + +//############################################################################# + +/** This helper function fills an array with zero. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have allowed + for memset as an alternative */ +template <class T> inline void +CoinZeroN(register T* to, const int size) +{ +#ifdef USE_MEMCPY + // Use memset - seems faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif + memset(to,0,size*sizeof(T)); +#else + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = 0; + to[1] = 0; + to[2] = 0; + to[3] = 0; + to[4] = 0; + to[5] = 0; + to[6] = 0; + to[7] = 0; + } + switch (size % 8) { + case 7: to[6] = 0; + case 6: to[5] = 0; + case 5: to[4] = 0; + case 4: to[3] = 0; + case 3: to[2] = 0; + case 2: to[1] = 0; + case 1: to[0] = 0; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = 0; + case 7: *++to = 0; + case 6: *++to = 0; + case 5: *++to = 0; + case 4: *++to = 0; + case 3: *++to = 0; + case 2: *++to = 0; + case 1: *++to = 0; + }while(--n>0); + } +#endif +#endif +} +/// This Debug helper function checks an array is all zero +inline void +CoinCheckDoubleZero(double * to, const int size) +{ + int n=0; + for (int j=0;j<size;j++) { + if (to[j]) + n++; + } + if (n) { + printf("array of length %d should be zero has %d nonzero\n",size,n); + } +} +/// This Debug helper function checks an array is all zero +inline void +CoinCheckIntZero(int * to, const int size) +{ + int n=0; + for (int j=0;j<size;j++) { + if (to[j]) + n++; + } + if (n) { + printf("array of length %d should be zero has %d nonzero\n",size,n); + } +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with a given value. For speed 8 + entries are filled at a time. The array is given by its first and "after + last" entry. */ +template <class T> inline void +CoinZero(register T* first, register T* last) +{ + CoinZeroN(first, last - first); +} + +//############################################################################# + +/** Returns strdup or NULL if original NULL */ +inline char * CoinStrdup(const char * name) +{ + char* dup = NULL; + if (name) { + const int len = static_cast<int>(strlen(name)); + dup = static_cast<char*>(malloc(len+1)); + CoinMemcpyN(name, len, dup); + dup[len] = 0; + } + return dup; +} + +//############################################################################# + +/** Return the larger (according to <code>operator<()</code> of the arguments. + This function was introduced because for some reason compiler tend to + handle the <code>max()</code> function differently. */ +template <class T> inline T +CoinMax(register const T x1, register const T x2) +{ + return (x1 > x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the smaller (according to <code>operator<()</code> of the arguments. + This function was introduced because for some reason compiler tend to + handle the min() function differently. */ +template <class T> inline T +CoinMin(register const T x1, register const T x2) +{ + return (x1 < x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the absolute value of the argument. This function was introduced + because for some reason compiler tend to handle the abs() function + differently. */ +template <class T> inline T +CoinAbs(const T value) +{ + return value<0 ? -value : value; +} + +//############################################################################# + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by a pointer to its first entry + and by its size. */ +template <class T> inline bool +CoinIsSorted(register const T* first, const int size) +{ + if (size == 0) + return true; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIsSorted", ""); +#endif +#if 1 + // size1 is the number of comparisons to be made + const int size1 = size - 1; + for (register int n = size1 / 8; n > 0; --n, first += 8) { + if (first[8] < first[7]) return false; + if (first[7] < first[6]) return false; + if (first[6] < first[5]) return false; + if (first[5] < first[4]) return false; + if (first[4] < first[3]) return false; + if (first[3] < first[2]) return false; + if (first[2] < first[1]) return false; + if (first[1] < first[0]) return false; + } + + switch (size1 % 8) { + case 7: if (first[7] < first[6]) return false; + case 6: if (first[6] < first[5]) return false; + case 5: if (first[5] < first[4]) return false; + case 4: if (first[4] < first[3]) return false; + case 3: if (first[3] < first[2]) return false; + case 2: if (first[2] < first[1]) return false; + case 1: if (first[1] < first[0]) return false; + case 0: break; + } +#else + register const T* next = first; + register const T* last = first + size; + for (++next; next != last; first = next, ++next) + if (*next < *first) + return false; +#endif + return true; +} + +//----------------------------------------------------------------------------- + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by its first and "after + last" entry. */ +template <class T> inline bool +CoinIsSorted(register const T* first, register const T* last) +{ + return CoinIsSorted(first, static_cast<int>(last - first)); +} + +//############################################################################# + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by a + pointer to its first entry and its size. */ +template <class T> inline void +CoinIotaN(register T* first, const int size, register T init) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIotaN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, first += 8, init += 8) { + first[0] = init; + first[1] = init + 1; + first[2] = init + 2; + first[3] = init + 3; + first[4] = init + 4; + first[5] = init + 5; + first[6] = init + 6; + first[7] = init + 7; + } + switch (size % 8) { + case 7: first[6] = init + 6; + case 6: first[5] = init + 5; + case 5: first[4] = init + 4; + case 4: first[3] = init + 3; + case 3: first[2] = init + 2; + case 2: first[1] = init + 1; + case 1: first[0] = init; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --first; + --init; + switch (size % 8) { + case 0: do{ *++first = ++init; + case 7: *++first = ++init; + case 6: *++first = ++init; + case 5: *++first = ++init; + case 4: *++first = ++init; + case 3: *++first = ++init; + case 2: *++first = ++init; + case 1: *++first = ++init; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by its + first and "after last" entry. */ +template <class T> inline void +CoinIota(T* first, const T* last, T init) +{ + CoinIotaN(first, last-first, init); +} + +//############################################################################# + +/** This helper function deletes certain entries from an array. The array is + given by pointers to its first and "after last" entry (first two + arguments). The positions of the entries to be deleted are given in the + integer array specified by the last two arguments (again, first and "after + last" entry). */ +template <class T> inline T * +CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast, + const int * firstDelPos, const int * lastDelPos) +{ + int delNum = static_cast<int>(lastDelPos - firstDelPos); + if (delNum == 0) + return arrayLast; + + if (delNum < 0) + throw CoinError("trying to delete negative number of entries", + "CoinDeleteEntriesFromArray", ""); + + int * delSortedPos = NULL; + if (! (CoinIsSorted(firstDelPos, lastDelPos) && + std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) { + // the positions of the to be deleted is either not sorted or not unique + delSortedPos = new int[delNum]; + CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos); + std::sort(delSortedPos, delSortedPos + delNum); + delNum = static_cast<int>(std::unique(delSortedPos, + delSortedPos+delNum) - delSortedPos); + } + const int * delSorted = delSortedPos ? delSortedPos : firstDelPos; + + const int last = delNum - 1; + int size = delSorted[0]; + for (int i = 0; i < last; ++i) { + const int copyFirst = delSorted[i] + 1; + const int copyLast = delSorted[i+1]; + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + } + const int copyFirst = delSorted[last] + 1; + const int copyLast = static_cast<int>(arrayLast - arrayFirst); + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + + if (delSortedPos) + delete[] delSortedPos; + + return arrayFirst + size; +} + +//############################################################################# + +#define COIN_OWN_RANDOM_32 + +#if defined COIN_OWN_RANDOM_32 +/* Thanks to Stefano Gliozzi for providing an operating system + independent random number generator. */ + +/*! \brief Return a random number between 0 and 1 + + A platform-independent linear congruential generator. For a given seed, the + generated sequence is always the same regardless of the (32-bit) + architecture. This allows to build & test in different environments, getting + in most cases the same optimization path. + + Set \p isSeed to true and supply an integer seed to set the seed + (vid. #CoinSeedRandom) + + \todo Anyone want to volunteer an upgrade for 64-bit architectures? +*/ +inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1) +{ + static unsigned int last = 123456; + if (isSeed) { + last = seed; + } else { + last = 1664525*last+1013904223; + return ((static_cast<double> (last))/4294967296.0); + } + return (0.0); +} + +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) +{ + CoinDrand48(true, iseed); +} + +#else // COIN_OWN_RANDOM_32 + +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__) + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return rand() / (double) RAND_MAX; } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); } + +#else + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return drand48(); } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); } + +#endif + +#endif // COIN_OWN_RANDOM_32 + +//############################################################################# + +/** This function figures out whether file names should contain slashes or + backslashes as directory separator */ +inline char CoinFindDirSeparator() +{ + int size = 1000; + char* buf = 0; + while (true) { + buf = new char[size]; + if (getcwd(buf, size)) + break; + delete[] buf; + buf = 0; + size = 2*size; + } + // if first char is '/' then it's unix and the dirsep is '/'. otherwise we + // assume it's dos and the dirsep is '\' + char dirsep = buf[0] == '/' ? '/' : '\\'; + delete[] buf; + return dirsep; +} +//############################################################################# + +inline int CoinStrNCaseCmp(const char* s0, const char* s1, + const size_t len) +{ + for (size_t i = 0; i < len; ++i) { + if (s0[i] == 0) { + return s1[i] == 0 ? 0 : -1; + } + if (s1[i] == 0) { + return 1; + } + const int c0 = std::tolower(s0[i]); + const int c1 = std::tolower(s1[i]); + if (c0 < c1) + return -1; + if (c0 > c1) + return 1; + } + return 0; +} + +//############################################################################# + +/// Swap the arguments. +template <class T> inline void CoinSwap (T &x, T &y) +{ + T t = x; + x = y; + y = t; +} + +//############################################################################# + +/** This helper function copies an array to file + Returns 0 if OK, 1 if bad write. +*/ + +template <class T> inline int +CoinToFile( const T* array, CoinBigIndex size, FILE * fp) +{ + CoinBigIndex numberWritten; + if (array&&size) { + numberWritten = + static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + numberWritten = + static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp)); + if (numberWritten!=size) + return 1; + } else { + size = 0; + numberWritten = + static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + } + return 0; +} + +//############################################################################# + +/** This helper function copies an array from file and creates with new. + Passed in array is ignored i.e. not deleted. + But if NULL and size does not match and newSize 0 then leaves as NULL and 0 + Returns 0 if OK, 1 if bad read, 2 if size did not match. +*/ + +template <class T> inline int +CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize) +{ + CoinBigIndex numberRead; + numberRead = + static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp)); + if (numberRead!=1) + return 1; + int returnCode=0; + if (size!=newSize&&(newSize||array)) + returnCode=2; + if (newSize) { + array = new T [newSize]; + numberRead = + static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp)); + if (numberRead!=newSize) + returnCode=1; + } else { + array = NULL; + } + return returnCode; +} + +//############################################################################# + +/// Cube Root +#if 0 +inline double CoinCbrt(double x) +{ +#if defined(_MSC_VER) + return pow(x,(1./3.)); +#else + return cbrt(x); +#endif +} +#endif + +//----------------------------------------------------------------------------- + +/// This helper returns "sizeof" as an int +#define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type))) +/// This helper returns "strlen" as an int +inline int +CoinStrlenAsInt(const char * string) +{ + return static_cast<int>(strlen(string)); +} + +/** Class for thread specific random numbers +*/ +#if defined COIN_OWN_RANDOM_32 +class CoinThreadRandom { +public: + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CoinThreadRandom() + { seed_=12345678;} + /** Constructor wih seed. */ + CoinThreadRandom(int seed) + { + seed_ = seed; + } + /** Destructor */ + ~CoinThreadRandom() {} + // Copy + CoinThreadRandom(const CoinThreadRandom & rhs) + { seed_ = rhs.seed_;} + // Assignment + CoinThreadRandom& operator=(const CoinThreadRandom & rhs) + { + if (this != &rhs) { + seed_ = rhs.seed_; + } + return *this; + } + + //@} + + /**@name Sets/gets */ + + //@{ + /** Set seed. */ + inline void setSeed(int seed) + { + seed_ = seed; + } + /** Get seed. */ + inline unsigned int getSeed() const + { + return seed_; + } + /// return a random number + inline double randomDouble() const + { + double retVal; + seed_ = 1664525*(seed_)+1013904223; + retVal = ((static_cast<double> (seed_))/4294967296.0); + return retVal; + } + /// make more random (i.e. for startup) + inline void randomize(int n=0) + { + if (!n) + n=seed_ & 255; + for (int i=0;i<n;i++) + randomDouble(); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Current seed + mutable unsigned int seed_; + //@} +}; +#else +class CoinThreadRandom { +public: + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CoinThreadRandom() + { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;} + /** Constructor wih seed. */ + CoinThreadRandom(const unsigned short seed[3]) + { memcpy(seed_,seed,3*sizeof(unsigned short));} + /** Constructor wih seed. */ + CoinThreadRandom(int seed) + { + union { int i[2]; unsigned short int s[4];} put; + put.i[0]=seed; + put.i[1]=seed; + memcpy(seed_,put.s,3*sizeof(unsigned short)); + } + /** Destructor */ + ~CoinThreadRandom() {} + // Copy + CoinThreadRandom(const CoinThreadRandom & rhs) + { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));} + // Assignment + CoinThreadRandom& operator=(const CoinThreadRandom & rhs) + { + if (this != &rhs) { + memcpy(seed_,rhs.seed_,3*sizeof(unsigned short)); + } + return *this; + } + + //@} + + /**@name Sets/gets */ + + //@{ + /** Set seed. */ + inline void setSeed(const unsigned short seed[3]) + { memcpy(seed_,seed,3*sizeof(unsigned short));} + /** Set seed. */ + inline void setSeed(int seed) + { + union { int i[2]; unsigned short int s[4];} put; + put.i[0]=seed; + put.i[1]=seed; + memcpy(seed_,put.s,3*sizeof(unsigned short)); + } + /// return a random number + inline double randomDouble() const + { + double retVal; +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__) + retVal=rand(); + retVal=retVal/(double) RAND_MAX; +#else + retVal = erand48(seed_); +#endif + return retVal; + } + /// make more random (i.e. for startup) + inline void randomize(int n=0) + { + if (!n) { + n=seed_[0]+seed_[1]+seed_[2]; + n &= 255; + } + for (int i=0;i<n;i++) + randomDouble(); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Current seed + mutable unsigned short seed_[3]; + //@} +}; +#endif +#ifndef COIN_DETAIL +#define COIN_DETAIL_PRINT(s) {} +#else +#define COIN_DETAIL_PRINT(s) s +#endif +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinIndexedVector.hpp b/thirdparty/linux/include/coin/coin/CoinIndexedVector.hpp new file mode 100644 index 0000000..9c386c5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinIndexedVector.hpp @@ -0,0 +1,1164 @@ +/* $Id: CoinIndexedVector.hpp 1767 2015-01-05 12:36:13Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinIndexedVector_H +#define CoinIndexedVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <map> +#include "CoinFinite.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#endif +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include <cassert> + +#ifndef COIN_FLOAT +#define COIN_INDEXED_TINY_ELEMENT 1.0e-50 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-100 +#else +#define COIN_INDEXED_TINY_ELEMENT 1.0e-35 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-39 +#endif + +/** Indexed Vector + +This stores values unpacked but apart from that is a bit like CoinPackedVector. +It is designed to be lightweight in normal use. + +It now has a "packed" mode when it is even more like CoinPackedVector + +Indices array has capacity_ extra chars which are zeroed and can +be used for any purpose - but must be re-zeroed + +Stores vector of indices and associated element values. +Supports sorting of indices. + +Does not support negative indices. + +Does NOT support testing for duplicates + +*** getElements is no longer supported + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its valuex1 + CoinIndexedVector r(ne,inx,el); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.getIndices ()[0]== 0 ); + assert( r.getIndices ()[1]== 1 ); + assert( r.getIndices ()[2]== 4 ); + assert( r.getIndices ()[3]== 2 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinIndexedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add indexed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinIndexedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinIndexedVector { + friend void CoinIndexedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getIndices() const { return indices_; } + /// Get element values + // ** No longer supported virtual const double * getElements() const ; + /// Get indices of elements + inline int * getIndices() { return indices_; } + /** Get the vector as a dense vector. This is normal storage method. + The user should not not delete [] this. + */ + inline double * denseVector() const { return elements_; } + /// For very temporary use when user needs to borrow a dense vector + inline void setDenseVector(double * array) + { elements_ = array;} + /// For very temporary use when user needs to borrow an index vector + inline void setIndexVector(int * array) + { indices_ = array;} + /** Access the i'th element of the full storage vector. + */ + double & operator[](int i) const; + + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Set the size + inline void setNumElements(int value) { nElements_ = value; + if (!nElements_) packedMode_=false;} + /// Reset the vector (as if were just created an empty vector). This leaves arrays! + void clear(); + /// Reset the vector (as if were just created an empty vector) + void empty(); + /** Assignment operator. */ + CoinIndexedVector & operator=(const CoinIndexedVector &); +#ifndef CLP_NO_VECTOR + /** Assignment operator from a CoinPackedVectorBase. <br> + <strong>NOTE</strong>: This assumes no duplicates */ + CoinIndexedVector & operator=(const CoinPackedVectorBase & rhs); +#endif + /** Copy the contents of one vector into another. If multiplier is 1 + It is the equivalent of = but if vectors are same size does + not re-allocate memory just clears and copies */ + void copy(const CoinIndexedVector & rhs, double multiplier=1.0); + + /** Borrow ownership of the arguments to this vector. + Size is the length of the unpacked elements vector. */ + void borrowVector(int size, int numberIndices, int* inds, double* elems); + + /** Return ownership of the arguments to this vector. + State after is empty . + */ + void returnVector(); + + /** Set vector numberIndices, indices, and elements. + NumberIndices is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. Assumed to have no duplicates */ + void setVector(int numberIndices, const int * inds, const double * elems); + + /** Set vector size, indices, and elements. + Size is the length of the unpacked elements vector. + The indices and elements vectors are copied into this class instance's + member data. We do not check for duplicate indices */ + void setVector(int size, int numberIndices, const int * inds, const double * elems); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems); + + /** Set an existing element in the indexed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Insert a nonzero element into the vector + inline void quickInsert(int index, double element) + { + assert (!elements_[index]); + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny */ + void add(int index, double element); + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This version does no checking */ + inline void quickAdd(int index, double element) + { + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = 1.0e-100; + } + } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This knows element is nonzero + This version does no checking */ + inline void quickAddNonZero(int index, double element) + { + assert (element); + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = COIN_DBL_MIN; + } + } else { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Makes nonzero tiny. + This version does no checking */ + inline void zero(int index) + { + if (elements_[index]) + elements_[index] = COIN_DBL_MIN; + } + /** set all small values to zero and return number remaining + - < tolerance => 0.0 */ + int clean(double tolerance); + /// Same but packs down + int cleanAndPack(double tolerance); + /// Same but packs down and is safe (i.e. if order is odd) + int cleanAndPackSafe(double tolerance); + /// Mark as packed + inline void setPacked() + { packedMode_ = true;} +#ifndef NDEBUG + /// For debug check vector is clear i.e. no elements + void checkClear(); + /// For debug check vector is clean i.e. elements match indices + void checkClean(); +#else + inline void checkClear() {}; + inline void checkClean() {}; +#endif + /// Scan dense region and set up indices (returns number found) + int scan(); + /** Scan dense region from start to < end and set up indices + returns number found + */ + int scan(int start, int end); + /** Scan dense region and set up indices (returns number found). + Only ones >= tolerance */ + int scan(double tolerance); + /** Scan dense region from start to < end and set up indices + returns number found. Only >= tolerance + */ + int scan(int start, int end, double tolerance); + /// These are same but pack down + int scanAndPack(); + int scanAndPack(int start, int end); + int scanAndPack(double tolerance); + int scanAndPack(int start, int end, double tolerance); + /// Create packed array + void createPacked(int number, const int * indices, + const double * elements); + /// Create unpacked array + void createUnpacked(int number, const int * indices, + const double * elements); + /// Create unpacked singleton + void createOneUnpackedElement(int index, double element); + /// This is mainly for testing - goes from packed to indexed + void expand(); +#ifndef CLP_NO_VECTOR + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); +#endif + /// Append a CoinIndexedVector to the end (with extra space) + void append(const CoinIndexedVector & caboose); + /// Append a CoinIndexedVector to the end and modify indices + void append(CoinIndexedVector & other,int adjustIndex,bool zapElements=false); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /// Throw away all entries in rows >= newSize + void truncate(int newSize); + /// Print out + void print() const; + //@} + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(double value); + /// subtract <code>value</code> from every entry + void operator-=(double value); + /// multiply every entry by <code>value</code> + void operator*=(double value); + /// divide every entry by <code>value</code> (** 0 vanishes) + void operator/=(double value); + //@} + + /**@name Comparison operators on two indexed vectors */ + //@{ +#ifndef CLP_NO_VECTOR + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; +#endif + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinIndexedVector & rhs) const; + /// Not equal + bool operator!=(const CoinIndexedVector & rhs) const; + /// Equal with a tolerance (returns -1 or position of inequality). + int isApproximatelyEqual(const CoinIndexedVector & rhs, double tolerance=1.0e-8) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + //@} + + + /**@name Sorting */ + //@{ + /** Sort the indexed storage vector (increasing indices). */ + void sort() + { std::sort(indices_,indices_+nElements_); } + + void sortIncrIndex() + { std::sort(indices_,indices_+nElements_); } + + void sortDecrIndex(); + + void sortIncrElement(); + + void sortDecrElement(); + void sortPacked(); + + //@} + + //############################################################################# + + /**@name Arithmetic operators on packed vectors. + + <strong>NOTE</strong>: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.<br> + <strong>NOTE 2</strong>: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + <em>very</em> inefficient... + */ +//@{ +/// Return the sum of two indexed vectors +CoinIndexedVector operator+( + const CoinIndexedVector& op2); + +/// Return the difference of two indexed vectors +CoinIndexedVector operator-( + const CoinIndexedVector& op2); + +/// Return the element-wise product of two indexed vectors +CoinIndexedVector operator*( + const CoinIndexedVector& op2); + +/// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +CoinIndexedVector operator/( + const CoinIndexedVector& op2); +/// The sum of two indexed vectors +void operator+=(const CoinIndexedVector& op2); + +/// The difference of two indexed vectors +void operator-=( const CoinIndexedVector& op2); + +/// The element-wise product of two indexed vectors +void operator*=(const CoinIndexedVector& op2); + +/// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +void operator/=(const CoinIndexedVector& op2); +//@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the indexed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + inline int capacity() const { return capacity_; } + inline void setCapacity(int value) + { capacity_ = value; } + /// Sets packed mode + inline void setPackedMode(bool yesNo) + { packedMode_=yesNo;} + /// Gets packed mode + inline bool packedMode() const + { return packedMode_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinIndexedVector(); + /** Alternate Constructors - set elements to vector of doubles */ + CoinIndexedVector(int size, const int * inds, const double * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinIndexedVector(int size, const int * inds, double element); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinIndexedVector(int size, const double * elements); + /** Alternate Constructors - just size */ + CoinIndexedVector(int size); + /** Copy constructor. */ + CoinIndexedVector(const CoinIndexedVector &); + /** Copy constructor.2 */ + CoinIndexedVector(const CoinIndexedVector *); +#ifndef CLP_NO_VECTOR + /** Copy constructor <em>from a PackedVectorBase</em>. */ + CoinIndexedVector(const CoinPackedVectorBase & rhs); +#endif + /** Destructor */ + ~CoinIndexedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, + const int * inds, const double * elems); + void gutsOfSetVector(int size, int numberIndices, + const int * inds, const double * elems); + void gutsOfSetPackedVector(int size, int numberIndices, + const int * inds, const double * elems); + /// + void gutsOfSetConstant(int size, + const int * inds, double value); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and packed elements vectors + int nElements_; + /// Amount of memory allocated for indices_, and elements_. + int capacity_; + /// Offset to get where new allocated array + int offset_; + /// If true then is operating in packed mode + bool packedMode_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinIndexedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinIndexedVectorUnitTest(); +/** Pointer with length in bytes + + This has a pointer to an array and the number of bytes in array. + If number of bytes==-1 then + CoinConditionalNew deletes existing pointer and returns new pointer + of correct size (and number bytes still -1). + CoinConditionalDelete deletes existing pointer and NULLs it. + So behavior is as normal (apart from New deleting pointer which will have + no effect with good coding practices. + If number of bytes >=0 then + CoinConditionalNew just returns existing pointer if array big enough + otherwise deletes existing pointer, allocates array with spare 1%+64 bytes + and updates number of bytes + CoinConditionalDelete sets number of bytes = -size-2 and then array + returns NULL +*/ +class CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_; } + /// Get the size + inline int rawSize() const + { return size_; } + /// See if persistence already on + inline bool switchedOn() const + { return size_!=-1; } + /// Get the capacity (just read it) + inline int capacity() const + { return (size_>-2) ? size_ : (-size_)-2; } + /// Set the capacity to >=0 if <=-2 + inline void setCapacity() + { if (size_<=-2) size_ = (-size_)-2; } + /// Get Array + inline const char * array() const + { return (size_>-2) ? array_ : NULL; } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value; } + /// Set the size to -1 + inline void switchOff() + { size_ = -1; } + /// Set the size to -2 and alignment + inline void switchOn(int alignment=3) + { size_ = -2; alignment_=alignment;} + /// Does what is needed to set persistence + void setPersistence(int flag,int currentLength); + /// Zero out array + void clear(); + /// Swaps memory between two members + void swap(CoinArrayWithLength & other); + /// Extend a persistent array keeping data (size in bytes) + void extend(int newSize); + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + char * conditionalNew(long sizeWanted); + /// Conditionally deletes + void conditionalDelete(); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArrayWithLength() + : array_(NULL),size_(-1),offset_(0),alignment_(0) + { } + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArrayWithLength(int size) + : size_(-1),offset_(0),alignment_(0) + { array_=new char [size];} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + mode>0 size_ set to size and zeroed + if size<=0 just does alignment + If abs(mode) >2 then align on that as power of 2 + */ + CoinArrayWithLength(int size, int mode); + /** Copy constructor. */ + CoinArrayWithLength(const CoinArrayWithLength & rhs); + /** Copy constructor.2 */ + CoinArrayWithLength(const CoinArrayWithLength * rhs); + /** Assignment operator. */ + CoinArrayWithLength& operator=(const CoinArrayWithLength & rhs); + /** Assignment with length (if -1 use internal length) */ + void copy(const CoinArrayWithLength & rhs, int numberBytes=-1); + /** Assignment with length - does not copy */ + void allocate(const CoinArrayWithLength & rhs, int numberBytes); + /** Destructor */ + ~CoinArrayWithLength (); + /// Get array with alignment + void getArray(int size); + /// Really get rid of array with alignment + void reallyFreeArray(); + /// Get enough space (if more needed then do at least needed) + void getCapacity(int numberBytes,int numberIfNeeded=-1); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Array + char * array_; + /// Size of array in bytes + CoinBigIndex size_; + /// Offset of array + int offset_; + /// Alignment wanted (power of 2) + int alignment_; + //@} +}; +/// double * version + +class CoinDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(double); } + /// Get Array + inline double * array() const + { return reinterpret_cast<double *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline double * conditionalNew(int sizeWanted) + { return reinterpret_cast<double *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(double),mode) {} + /** Copy constructor. */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinDoubleArrayWithLength& operator=(const CoinDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationDouble * version + +class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinFactorizationDouble); } + /// Get Array + inline CoinFactorizationDouble * array() const + { return reinterpret_cast<CoinFactorizationDouble *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinFactorizationDouble); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinFactorizationDouble * conditionalNew(int sizeWanted) + { return reinterpret_cast<CoinFactorizationDouble *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinFactorizationDouble)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinFactorizationDouble),mode) {} + /** Copy constructor. */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationDoubleArrayWithLength& operator=(const CoinFactorizationDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationLongDouble * version + +class CoinFactorizationLongDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(long double); } + /// Get Array + inline long double * array() const + { return reinterpret_cast<long double *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(long double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline long double * conditionalNew(int sizeWanted) + { return reinterpret_cast<long double *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(long double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationLongDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationLongDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(long double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationLongDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(long double),mode) {} + /** Copy constructor. */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationLongDoubleArrayWithLength& operator=(const CoinFactorizationLongDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// int * version + +class CoinIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(int); } + /// Get Array + inline int * array() const + { return reinterpret_cast<int *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline int * conditionalNew(int sizeWanted) + { return reinterpret_cast<int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(int),mode) {} + /** Copy constructor. */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinIntArrayWithLength& operator=(const CoinIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinBigIndex * version + +class CoinBigIndexArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinBigIndex); } + /// Get Array + inline CoinBigIndex * array() const + { return reinterpret_cast<CoinBigIndex *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinBigIndex); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinBigIndex * conditionalNew(int sizeWanted) + { return reinterpret_cast<CoinBigIndex *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinBigIndexArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinBigIndexArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinBigIndex)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinBigIndexArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinBigIndex),mode) {} + /** Copy constructor. */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinBigIndexArrayWithLength& operator=(const CoinBigIndexArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// unsigned int * version + +class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(unsigned int); } + /// Get Array + inline unsigned int * array() const + { return reinterpret_cast<unsigned int *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(unsigned int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline unsigned int * conditionalNew(int sizeWanted) + { return reinterpret_cast<unsigned int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinUnsignedIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinUnsignedIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(unsigned int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinUnsignedIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(unsigned int),mode) {} + /** Copy constructor. */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinUnsignedIntArrayWithLength& operator=(const CoinUnsignedIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// void * version + +class CoinVoidStarArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(void *); } + /// Get Array + inline void ** array() const + { return reinterpret_cast<void **> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(void *); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline void ** conditionalNew(int sizeWanted) + { return reinterpret_cast<void **> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(void *)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinVoidStarArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinVoidStarArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(void *)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinVoidStarArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(void *),mode) {} + /** Copy constructor. */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinVoidStarArrayWithLength& operator=(const CoinVoidStarArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// arbitrary version + +class CoinArbitraryArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/lengthInBytes_; } + /// Get Array + inline void ** array() const + { return reinterpret_cast<void **> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*lengthInBytes_; } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline char * conditionalNew(int length, int sizeWanted) + { lengthInBytes_=length;return reinterpret_cast<char *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> + ((sizeWanted)*lengthInBytes_) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArbitraryArrayWithLength(int length=1) + { array_=NULL; size_=-1;lengthInBytes_=length;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArbitraryArrayWithLength(int length, int size) + { array_=new char [size*length]; size_=-1; lengthInBytes_=length;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinArbitraryArrayWithLength(int length, int size, int mode) + : CoinArrayWithLength(size*length,mode) {lengthInBytes_=length;} + /** Copy constructor. */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinArbitraryArrayWithLength& operator=(const CoinArbitraryArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} + +protected: + /**@name Private member data */ + //@{ + /// Length in bytes + int lengthInBytes_; + //@} +}; +class CoinPartitionedVector : public CoinIndexedVector { + +public: +#ifndef COIN_PARTITIONS +#define COIN_PARTITIONS 8 +#endif + /**@name Get methods. */ + //@{ + /// Get the size of a partition + inline int getNumElements(int partition) const { assert (partition<COIN_PARTITIONS); + return numberElementsPartition_[partition]; } + /// Get number of partitions + inline int getNumPartitions() const + { return numberPartitions_; } + /// Get the size + inline int getNumElements() const { return nElements_; } + /// Get starts + inline int startPartition(int partition) const { assert (partition<=COIN_PARTITIONS); + return startPartition_[partition]; } + /// Get starts + inline const int * startPartitions() const + { return startPartition_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Set the size of a partition + inline void setNumElementsPartition(int partition, int value) { assert (partition<COIN_PARTITIONS); + if (numberPartitions_) numberElementsPartition_[partition]=value; } + /// Set the size of a partition (just for a tiny while) + inline void setTempNumElementsPartition(int partition, int value) { assert (partition<COIN_PARTITIONS); + numberElementsPartition_[partition]=value; } + /// Add up number of elements in partitions + void computeNumberElements(); + /// Add up number of elements in partitions and pack and get rid of partitions + void compact(); + /** Reserve space. + */ + void reserve(int n); + /// Setup partitions (needs end as well) + void setPartitions(int number,const int * starts); + /// Reset the vector (as if were just created an empty vector). Gets rid of partitions + void clearAndReset(); + /// Reset the vector (as if were just created an empty vector). Keeps partitions + void clearAndKeep(); + /// Clear a partition. + void clearPartition(int partition); +#ifndef NDEBUG + /// For debug check vector is clear i.e. no elements + void checkClear(); + /// For debug check vector is clean i.e. elements match indices + void checkClean(); +#else + inline void checkClear() {}; + inline void checkClean() {}; +#endif + /// Scan dense region and set up indices (returns number found) + int scan(int partition, double tolerance=0.0); + /** Scan dense region from start to < end and set up indices + returns number found + */ + /// Print out + void print() const; + //@} + + /**@name Sorting */ + //@{ + /** Sort the indexed storage vector (increasing indices). */ + void sort(); + //@} + + /**@name Constructors and destructors (not all wriiten) */ + //@{ + /** Default constructor */ + CoinPartitionedVector(); + /** Alternate Constructors - set elements to vector of doubles */ + CoinPartitionedVector(int size, const int * inds, const double * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinPartitionedVector(int size, const int * inds, double element); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinPartitionedVector(int size, const double * elements); + /** Alternate Constructors - just size */ + CoinPartitionedVector(int size); + /** Copy constructor. */ + CoinPartitionedVector(const CoinPartitionedVector &); + /** Copy constructor.2 */ + CoinPartitionedVector(const CoinPartitionedVector *); + /** Assignment operator. */ + CoinPartitionedVector & operator=(const CoinPartitionedVector &); + /** Destructor */ + ~CoinPartitionedVector (); + //@} +protected: + /**@name Private member data */ + //@{ + /// Starts + int startPartition_[COIN_PARTITIONS+1]; + /// Size of indices in a partition + int numberElementsPartition_[COIN_PARTITIONS]; + /// Number of partitions (0 means off) + int numberPartitions_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinLpIO.hpp b/thirdparty/linux/include/coin/coin/CoinLpIO.hpp new file mode 100644 index 0000000..43c0e20 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinLpIO.hpp @@ -0,0 +1,805 @@ +/* $Id: CoinLpIO.hpp 1749 2014-10-24 20:00:14Z tkr $ */ +// Last edit: 11/5/08 +// +// Name: CoinLpIO.hpp; Support for Lp files +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 12/28/03 +//----------------------------------------------------------------------------- +// Copyright (C) 2003, Francois Margot, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinLpIO_H +#define CoinLpIO_H + +#include <cstdio> + +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +class CoinSet; + +const int MAX_OBJECTIVES = 2; + +typedef int COINColumnIndex; + + /** Class to read and write Lp files + + Lp file format: + +/ this is a comment <BR> +\ this too <BR> + Min<BR> + obj: x0 + x1 + 3 x2 - 4.5 xyr + 1 <BR> + s.t. <BR> + cons1: x0 - x2 - 2.3 x4 <= 4.2 / this is another comment <BR> + c2: x1 + x2 >= 1 <BR> + cc: x1 + x2 + xyr = 2 <BR> + Bounds <BR> + 0 <= x1 <= 3 <BR> + 1 >= x2 <BR> + x3 = 1 <BR> + -2 <= x4 <= Inf <BR> + xyr free <BR> + Integers <BR> + x0 <BR> + Generals <BR> + x1 xyr <BR> + Binaries <BR> + x2 <BR> + End + +Notes: <UL> + <LI> Keywords are: Min, Max, Minimize, Maximize, s.t., Subject To, + Bounds, Integers, Generals, Binaries, End, Free, Inf. + <LI> Keywords are not case sensitive and may be in plural or singular form. + They should not be used as objective, row or column names. + <LI> Bounds, Integers, Generals, Binaries sections are optional. + <LI> Generals and Integers are synonymous. + <LI> Bounds section (if any) must come before Integers, Generals, and + Binaries sections. + <LI> Row names must be followed by ':' without blank space. + Row names are optional. If row names are present, + they must be distinct (if the k-th constraint has no given name, its name + is set automatically to "consk" for k=0,...,). + For valid row names, see the method is_invalid_name(). + <LI> Column names must be followed by a blank space. They must be distinct. + For valid column names, see the method is_invalid_name(). + <LI> Multiple objectives may be specified, but when there are multiple + objectives, they must have names (to indicate where each one starts). + <LI> The objective function names must be followed by ':' without blank space. + If there is a single objective, the objective function name is optional. + If no name is given, the name is set to "obj" by default. + For valid objective function names, see the method is_invalid_name(). + <LI> Ranged constraints are written as two constraints. + If a name is given for a ranged constraint, the upper bound constraint + has that name and the lower bound constraint has that name with "_low" + as suffix. This should be kept in mind when assigning names to ranged + constraint, as the resulting name must be distinct from all the other + names and be considered valid by the method is_invalid_name(). + <LI> At most one term related to any single variable may appear in the + objective function; if more than one term are present, only the last + one is taken into account. + At most one constant term may appear in the objective function; + if present, it must appear last. + <LI> Default bounds are 0 for lower bound and +infinity for upper bound. + <LI> Free variables get default lower bound -infinity and + default upper bound +infinity. Writing "x0 Free" in an + LP file means "set lower bound on x0 to -infinity". + <LI> If more than one upper (resp. lower) bound on a variable appears in + the Bounds section, the last one is the one taken into + account. The bounds for a binary variable are set to 0/1 only if this + bound is stronger than the bound obtained from the Bounds section. + <LI> Numbers larger than DBL_MAX (or larger than 1e+400) in the input file + might crash the code. + <LI> A comment must start with '\' or '/'. That symbol must either be + the first character of a line or be preceded by a blank space. The + comment ends at the end of the + line. Comments are skipped while reading an Lp file and they may be + inserted anywhere. +</UL> +*/ +class CoinLpIO { + friend void CoinLpIOUnitTest(const std::string & lpDir); +public: + + /**@name Constructor and Destructor */ + //@{ + /// Default Constructor + CoinLpIO(); + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment + void gutsOfCopy(const CoinLpIO &); + + /// assignment operator + CoinLpIO & operator = (const CoinLpIO& rhs) ; + + /// Copy constructor + CoinLpIO (const CoinLpIO &); + + /// Destructor + ~CoinLpIO(); + + /** Free the vector previous_names_[section] and set + card_previous_names_[section] to 0. + section = 0 for row names, + section = 1 for column names. + */ + void freePreviousNames(const int section); + + /// Free all memory (except memory related to hash tables and objName_). + void freeAll(); + //@} + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + + /**@name Queries */ + //@{ + + /// Get the problem name + const char * getProblemName() const; + + /// Set problem name + void setProblemName(const char *name); + + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + /** Get pointer to array[getNumRows()] of constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + Put another way, only ranged constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const int getNumObjectives() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients for objective j + const double * getObjCoefficients(int j) const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Get objective function name + const char * getObjName() const; + + /// Get objective function name for objective j + const char * getObjName(int j) const; + + /// Get pointer to array[*card_prev] of previous row names. + /// The value of *card_prev might be different than getNumRows()+1 if + /// non distinct + /// row names were present or if no previous names were saved or if + /// the object was holding a different problem before. + void getPreviousRowNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[*card_prev] of previous column names. + /// The value of *card_prev might be different than getNumCols() if non + /// distinct column names were present of if no previous names were saved, + /// or if the object was holding a different problem before. + void getPreviousColNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[getNumRows()+1] of row names, including + /// objective function name as last entry. + char const * const * getRowNames() const; + + /// Get pointer to array[getNumCols()] of column names + char const * const *getColNames() const; + + /// Return the row name for the specified index. + /// Return the objective function name if index = getNumRows(). + /// Return 0 if the index is out of range or if row names are not defined. + const char * rowName(int index) const; + + /// Return the column name for the specified index. + /// Return 0 if the index is out of range or if column names are not + /// defined. + const char * columnName(int index) const; + + /// Return the index for the specified row name. + /// Return getNumRows() for the objective function name. + /// Return -1 if the name is not found. + int rowIndex(const char * name) const; + + /// Return the index for the specified column name. + /// Return -1 if the name is not found. + int columnIndex(const char * name) const; + + ///Returns the (constant) objective offset + double objectiveOffset() const; + + ///Returns the (constant) objective offset for objective j + double objectiveOffset(int j) const; + + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_[0] = value;} + + /// Set objective offset + inline void setObjectiveOffset(double value, int j) + { objectiveOffset_[j] = value;} + + /// Return true if a column is an integer (binary or general + /// integer) variable + bool isInteger(int columnNumber) const; + + /// Get characteristic vector of integer variables + const char * integerColumns() const; + //@} + + /**@name Parameters */ + //@{ + /// Get infinity + double getInfinity() const; + + /// Set infinity. Any number larger is considered infinity. + /// Default: DBL_MAX + void setInfinity(const double); + + /// Get epsilon + double getEpsilon() const; + + /// Set epsilon. + /// Default: 1e-5. + void setEpsilon(const double); + + /// Get numberAcross, the number of monomials to be printed per line + int getNumberAcross() const; + + /// Set numberAcross. + /// Default: 10. + void setNumberAcross(const int); + + /// Get decimals, the number of digits to write after the decimal point + int getDecimals() const; + + /// Set decimals. + /// Default: 5 + void setDecimals(const int); + //@} + + /**@name Public methods */ + //@{ + /** Set the data of the object. + Set it from the coefficient matrix m, the lower bounds + collb, the upper bounds colub, objective function obj_coeff, + integrality vector integrality, lower/upper bounds on the constraints. + The sense of optimization of the objective function is assumed to be + a minimization. + Numbers larger than DBL_MAX (or larger than 1e+400) + might crash the code. There are two version. The second one is for + setting multiple objectives. + */ + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff, + const char* integrality, + const double* rowlb, const double* rowub); + + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff[MAX_OBJECTIVES], + int num_objectives, + const char* integrality, + const double* rowlb, const double* rowub); + + /** Return 0 if buff is a valid name for a row, a column or objective + function, return a positive number otherwise. + If parameter ranged = true, the name is intended for a ranged + constraint. <BR> + Return 1 if the name has more than 100 characters (96 characters + for a ranged constraint name, as "_low" will be added to the name).<BR> + Return 2 if the name starts with a number.<BR> + Return 3 if the name is not built with + the letters a to z, A to Z, the numbers 0 to 9 or the characters + " ! # $ % & ( ) . ; ? @ _ ' ` { } ~ <BR> + Return 4 if the name is a keyword.<BR> + Return 5 if the name is empty or NULL. */ + int is_invalid_name(const char *buff, const bool ranged) const; + + /** Return 0 if each of the card_vnames entries of vnames is a valid name, + return a positive number otherwise. The return value, if not 0, is the + return value of is_invalid_name() for the last invalid name + in vnames. If check_ranged = true, the names are row names and + names for ranged constaints must be checked for additional restrictions + since "_low" will be added to the name if an Lp file is written. + When check_ranged = true, card_vnames must have getNumRows()+1 entries, + with entry vnames[getNumRows()] being the + name of the objective function. + For a description of valid names and return values, see the method + is_invalid_name(). + + This method must not be called with check_ranged = true before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + */ + int are_invalid_names(char const * const *vnames, + const int card_vnames, + const bool check_ranged) const; + + /// Set objective function name to the default "obj" and row + /// names to the default "cons0", "cons1", ... + void setDefaultRowNames(); + + /// Set column names to the default "x0", "x1", ... + void setDefaultColNames(); + + /** Set the row and column names. + The array rownames must either be NULL or have exactly getNumRows()+1 + distinct entries, + each of them being a valid name (see is_invalid_name()) and the + last entry being the intended name for the objective function. + If rownames is NULL, existing row names and objective function + name are not changed. + If rownames is deemed invalid, default row names and objective function + name are used (see setDefaultRowNames()). The memory location of + array rownames (or its entries) should not be related + to the memory location of the array (or entries) obtained from + getRowNames() or getPreviousRowNames(), as the call to + setLpDataRowAndColNames() modifies the corresponding arrays. + Unpredictable results + are obtained if this requirement is ignored. + + Similar remarks apply to the array colnames, which must either be + NULL or have exactly getNumCols() entries. + */ + void setLpDataRowAndColNames(char const * const * const rownames, + char const * const * const colnames); + + /** Write the data in Lp format in the file with name filename. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(const char *filename, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /** Write the data in Lp format in the file pointed to by the paramater fp. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(FILE *fp, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /// Write the data in Lp format in the file with name filename. + /// Write objective function name and row names if useRowNames = true. + int writeLp(const char *filename, const bool useRowNames = true); + + /// Write the data in Lp format in the file pointed to by the parameter fp. + /// Write objective function name and row names if useRowNames = true. + int writeLp(FILE *fp, const bool useRowNames = true); + + /// Read the data in Lp format from the file with name filename, using + /// the given value for epsilon. If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename, const double epsilon); + + /// Read the data in Lp format from the file with name filename. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename); + + /// Read the data in Lp format from the file stream, using + /// the given value for epsilon. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp, const double epsilon); + + /// Read the data in Lp format from the file stream. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp); + + /// Dump the data. Low level method for debugging. + void print() const; + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet * sets); + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet ** sets); + + /// Number of SOS sets + inline int numberSets() const + { return numberSets_;} + + /// Set information + inline CoinSet ** setInformation() const + { return set_;} + //@} +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + +protected: + /// Problem name + char * problemName_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of elements + int numberElements_; + + /// Pointer to column-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByColumn_; + + /// Pointer to row-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByRow_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of row rhs + mutable double * rhs_; + + /** Pointer to dense vector of slack variable upper bounds for ranged + constraints (undefined for non-ranged constraints) + */ + mutable double *rowrange_; + + /// Pointer to dense vector of row senses + mutable char * rowsense_; + + /// Pointer to dense vector of objective coefficients + double * objective_[MAX_OBJECTIVES]; + + /// Number of objectives + int num_objectives_; + + /// Constant offset for objective value + double objectiveOffset_[MAX_OBJECTIVES]; + + /// Pointer to dense vector specifying if a variable is continuous + /// (0) or integer (1). + char * integerType_; + + /// Pointer to sets + CoinSet ** set_; + + /// Number of sets + int numberSets_; + + /// Current file name + char * fileName_; + + /// Value to use for infinity + double infinity_; + + /// Value to use for epsilon + double epsilon_; + + /// Number of monomials printed in a row + int numberAcross_; + + /// Number of decimals printed for coefficients + int decimals_; + + /// Objective function name + char *objName_[MAX_OBJECTIVES]; + + /** Row names (including objective function name) + and column names when stopHash() for the corresponding + section was last called or for initial names (deemed invalid) + read from a file.<BR> + section = 0 for row names, + section = 1 for column names. */ + char **previous_names_[2]; + + /// card_previous_names_[section] holds the number of entries in the vector + /// previous_names_[section]. + /// section = 0 for row names, + /// section = 1 for column names. + int card_previous_names_[2]; + + /// Row names (including objective function name) + /// and column names (linked to Hash tables). + /// section = 0 for row names, + /// section = 1 for column names. + char **names_[2]; + + typedef struct { + int index, next; + } CoinHashLink; + + /// Maximum number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int maxHash_[2]; + + /// Number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int numberHash_[2]; + + /// Hash tables with two sections. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + mutable CoinHashLink *hash_[2]; + + /// Build the hash table for the given names. The parameter number is + /// the cardinality of parameter names. Remove duplicate names. + /// + /// section = 0 for row names, + /// section = 1 for column names. + void startHash(char const * const * const names, + const COINColumnIndex number, + int section); + + /// Delete hash storage. If section = 0, it also frees objName_. + /// section = 0 for row names, + /// section = 1 for column names. + void stopHash(int section); + + /// Return the index of the given name, return -1 if the name is not found. + /// Return getNumRows() for the objective function name. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + COINColumnIndex findHash(const char *name, int section) const; + + /// Insert thisName in the hash table if not present yet; does nothing + /// if the name is already in. + /// section = 0 for row names, + /// section = 1 for column names. + void insertHash(const char *thisName, int section); + + /// Write a coefficient. + /// print_1 = 0 : do not print the value 1. + void out_coeff(FILE *fp, double v, int print_1) const; + + /// Locate the objective function. + /// Return 1 if found the keyword "Minimize" or one of its variants, + /// -1 if found keyword "Maximize" or one of its variants. + int find_obj(FILE *fp) const; + + /// Return an integer indicating if the keyword "subject to" or one + /// of its variants has been read. + /// Return 1 if buff is the keyword "s.t" or one of its variants. + /// Return 2 if buff is the keyword "subject" or one of its variants. + /// Return 0 otherwise. + int is_subject_to(const char *buff) const; + + /// Return 1 if the first character of buff is a number. + /// Return 0 otherwise. + int first_is_number(const char *buff) const; + + /// Return 1 if the first character of buff is '/' or '\'. + /// Return 0 otherwise. + int is_comment(const char *buff) const; + + /// Read the file fp until buff contains an end of line + void skip_comment(char *buff, FILE *fp) const; + + /// Put in buff the next string that is not part of a comment + void scan_next(char *buff, FILE *fp) const; + + /// Return 1 if buff is the keyword "free" or one of its variants. + /// Return 0 otherwise. + int is_free(const char *buff) const; + + /// Return 1 if buff is the keyword "inf" or one of its variants. + /// Return 0 otherwise. + int is_inf(const char *buff) const; + + /// Return an integer indicating the inequality sense read. + /// Return 0 if buff is '<='. + /// Return 1 if buff is '='. + /// Return 2 if buff is '>='. + /// Return -1 otherwise. + int is_sense(const char *buff) const; + + /// Return an integer indicating if one of the keywords "Bounds", "Integers", + /// "Generals", "Binaries", "Semi-continuous", "Sos", "End", or one + /// of their variants has been read. (note Semi-continuous not coded) + /// Return 1 if buff is the keyword "Bounds" or one of its variants. + /// Return 2 if buff is the keyword "Integers" or "Generals" or one of their + /// variants. + /// Return 3 if buff is the keyword "Binaries" or one of its variants. + /// Return 4 if buff is the keyword "Semi-continuous" or one of its variants. + /// Return 5 if buff is the keyword "Sos" or one of its variants. + /// Return 6 if buff is the keyword "End" or one of its variants. + /// Return 0 otherwise. + int is_keyword(const char *buff) const; + + /// Read a monomial of the objective function. + /// Return 1 if "subject to" or one of its variants has been read. + int read_monom_obj(FILE *fp, double *coeff, char **name, int *cnt, + char **obj_name, int *num_objectives, int *obj_starts); + + /// Read a monomial of a constraint. + /// Return a positive number if the sense of the inequality has been + /// read (see method is_sense() for the return code). + /// Return -1 otherwise. + int read_monom_row(FILE *fp, char *start_str, double *coeff, char **name, + int cnt_coeff) const; + + /// Reallocate vectors related to number of coefficients. + void realloc_coeff(double **coeff, char ***colNames, int *maxcoeff) const; + + /// Reallocate vectors related to rows. + void realloc_row(char ***rowNames, int **start, double **rhs, + double **rowlow, double **rowup, int *maxrow) const; + + /// Reallocate vectors related to columns. + void realloc_col(double **collow, double **colup, char **is_int, + int *maxcol) const; + + /// Read a constraint. + void read_row(FILE *fp, char *buff, double **pcoeff, char ***pcolNames, + int *cnt_coeff, int *maxcoeff, + double *rhs, double *rowlow, double *rowup, + int *cnt_row, double inf) const; + + /** Check that current objective name and all row names are distinct + including row names obtained by adding "_low" for ranged constraints. + If there is a conflict in the names, they are replaced by default + row names (see setDefaultRowNames()). + + This method must not be called before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the row names is required. + */ + void checkRowNames(); + + /** Check that current column names are distinct. + If not, they are replaced by default + column names (see setDefaultColNames()). + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the column names is required. + */ + void checkColNames(); + +}; + +void +CoinLpIOUnitTest(const std::string& lpDir); + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinMessage.hpp b/thirdparty/linux/include/coin/coin/CoinMessage.hpp new file mode 100644 index 0000000..cfdcd49 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinMessage.hpp @@ -0,0 +1,96 @@ +/* $Id: CoinMessage.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessage_H +#define CoinMessage_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +/*! \file + + This file contains the enum for the standard set of Coin messages and a + class definition whose sole purpose is to supply a constructor. The text + ot the messages is defined in CoinMessage.cpp, + + CoinMessageHandler.hpp contains the generic facilities for message + handling. +*/ + +#include "CoinMessageHandler.hpp" + +/*! \brief Symbolic names for the standard set of COIN messages */ + +enum COIN_Message +{ + COIN_MPS_LINE=0, + COIN_MPS_STATS, + COIN_MPS_ILLEGAL, + COIN_MPS_BADIMAGE, + COIN_MPS_DUPOBJ, + COIN_MPS_DUPROW, + COIN_MPS_NOMATCHROW, + COIN_MPS_NOMATCHCOL, + COIN_MPS_FILE, + COIN_MPS_BADFILE1, + COIN_MPS_BADFILE2, + COIN_MPS_EOF, + COIN_MPS_RETURNING, + COIN_MPS_CHANGED, + COIN_SOLVER_MPS, + COIN_PRESOLVE_COLINFEAS, + COIN_PRESOLVE_ROWINFEAS, + COIN_PRESOLVE_COLUMNBOUNDA, + COIN_PRESOLVE_COLUMNBOUNDB, + COIN_PRESOLVE_NONOPTIMAL, + COIN_PRESOLVE_STATS, + COIN_PRESOLVE_INFEAS, + COIN_PRESOLVE_UNBOUND, + COIN_PRESOLVE_INFEASUNBOUND, + COIN_PRESOLVE_INTEGERMODS, + COIN_PRESOLVE_POSTSOLVE, + COIN_PRESOLVE_NEEDS_CLEANING, + COIN_PRESOLVE_PASS, +# if PRESOLVE_DEBUG + COIN_PRESOLDBG_FIRSTCHECK, + COIN_PRESOLDBG_RCOSTACC, + COIN_PRESOLDBG_RCOSTSTAT, + COIN_PRESOLDBG_STATSB, + COIN_PRESOLDBG_DUALSTAT, +# endif + COIN_GENERAL_INFO, + COIN_GENERAL_INFO2, + COIN_GENERAL_WARNING, + COIN_DUMMY_END +}; + + +/*! \class CoinMessage + \brief The standard set of Coin messages + + This class provides convenient access to the standard set of Coin messages. + In a nutshell, it's a CoinMessages object with a constructor that + preloads the standard Coin messages. +*/ + +class CoinMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /*! \brief Constructor + + Build a CoinMessages object and load it with the standard set of + Coin messages. + */ + CoinMessage(Language language=us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinMessageHandler.hpp b/thirdparty/linux/include/coin/coin/CoinMessageHandler.hpp new file mode 100644 index 0000000..7922630 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinMessageHandler.hpp @@ -0,0 +1,666 @@ +/* $Id: CoinMessageHandler.hpp 1514 2011-12-10 23:35:23Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessageHandler_H +#define CoinMessageHandler_H + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +#include <iostream> +#include <cstdio> +#include <string> +#include <vector> + +/** \file CoinMessageHandler.hpp + \brief This is a first attempt at a message handler. + + The COIN Project is in favo(u)r of multi-language support. This implementation + of a message handler tries to make it as lightweight as possible in the sense + that only a subset of messages need to be defined --- the rest default to US + English. + + The default handler at present just prints to stdout or to a FILE pointer + + \todo + This needs to be worked over for correct operation with ISO character codes. +*/ + +/* + I (jjf) am strongly in favo(u)r of language support for an open + source project, but I have tried to make it as lightweight as + possible in the sense that only a subset of messages need to be + defined - the rest default to US English. There will be different + sets of messages for each component - so at present there is a + Clp component and a Coin component. + + Because messages are only used in a controlled environment and have no + impact on code and are tested by other tests I have included tests such + as language and derivation in other unit tests. +*/ +/* + Where there are derived classes I (jjf) have started message numbers at 1001. +*/ + + +/** \brief Class for one massaged message. + + A message consists of a text string with formatting codes (#message_), + an integer identifier (#externalNumber_) which also determines the severity + level (#severity_) of the message, and a detail (logging) level (#detail_). + + CoinOneMessage is just a container to hold this information. The + interpretation is set by CoinMessageHandler, which see. + */ + +class CoinOneMessage { + +public: + /**@name Constructors etc */ + //@{ + /** Default constructor. */ + CoinOneMessage(); + /** Normal constructor */ + CoinOneMessage(int externalNumber, char detail, + const char * message); + /** Destructor */ + ~CoinOneMessage(); + /** The copy constructor */ + CoinOneMessage(const CoinOneMessage&); + /** assignment operator. */ + CoinOneMessage& operator=(const CoinOneMessage&); + //@} + + /**@name Useful stuff */ + //@{ + /// Replace message text (<i>e.g.</i>, text in a different language) + void replaceMessage(const char * message); + //@} + + /**@name Get and set methods */ + //@{ + /** Get message ID number */ + inline int externalNumber() const + {return externalNumber_;} + /** \brief Set message ID number + + In the default CoinMessageHandler, this number is printed in the message + prefix and is used to determine the message severity level. + */ + inline void setExternalNumber(int number) + {externalNumber_=number;} + /// Severity + inline char severity() const + {return severity_;} + /// Set detail level + inline void setDetail(int level) + {detail_=static_cast<char> (level);} + /// Get detail level + inline int detail() const + {return detail_;} + /// Return the message text + inline char * message() const + {return message_;} + //@} + + /**@name member data */ + //@{ + /// number to print out (also determines severity) + int externalNumber_; + /// Will only print if detail matches + char detail_; + /// Severity + char severity_; + /// Messages (in correct language) (not all 400 may exist) + mutable char message_[400]; + //@} +}; + +/** \brief Class to hold and manipulate an array of massaged messages. + + Note that the message index used to reference a message in the array of + messages is completely distinct from the external ID number stored with the + message. +*/ + +class CoinMessages { + +public: + /** \brief Supported languages + + These are the languages that are supported. At present only + us_en is serious and the rest are for testing. + */ + enum Language { + us_en = 0, + uk_en, + it + }; + + /**@name Constructors etc */ + //@{ + /** Constructor with number of messages. */ + CoinMessages(int numberMessages=0); + /** Destructor */ + ~CoinMessages(); + /** The copy constructor */ + CoinMessages(const CoinMessages&); + /** assignment operator. */ + CoinMessages& operator=(const CoinMessages&); + //@} + + /**@name Useful stuff */ + //@{ + /*! \brief Installs a new message in the specified index position + + Any existing message is replaced, and a copy of the specified message is + installed. + */ + void addMessage(int messageNumber, const CoinOneMessage & message); + /*! \brief Replaces the text of the specified message + + Any existing text is deleted and the specified text is copied into the + specified message. + */ + void replaceMessage(int messageNumber, const char * message); + /** Language. Need to think about iso codes */ + inline Language language() const + {return language_;} + /** Set language */ + void setLanguage(Language newlanguage) + {language_ = newlanguage;} + /// Change detail level for one message + void setDetailMessage(int newLevel, int messageNumber); + /** \brief Change detail level for several messages + + messageNumbers is expected to contain the indices of the messages to be + changed. + If numberMessages >= 10000 or messageNumbers is NULL, the detail level + is changed on all messages. + */ + void setDetailMessages(int newLevel, int numberMessages, + int * messageNumbers); + /** Change detail level for all messages with low <= ID number < high */ + void setDetailMessages(int newLevel, int low, int high); + + /// Returns class + inline int getClass() const + { return class_;} + /// Moves to compact format + void toCompact(); + /// Moves from compact format + void fromCompact(); + //@} + + /**@name member data */ + //@{ + /// Number of messages + int numberMessages_; + /// Language + Language language_; + /// Source (null-terminated string, maximum 4 characters). + char source_[5]; + /// Class - see later on before CoinMessageHandler + int class_; + /** Length of fake CoinOneMessage array. + First you get numberMessages_ pointers which point to stuff + */ + int lengthMessages_; + /// Messages + CoinOneMessage ** message_; + //@} +}; + +// for convenience eol +enum CoinMessageMarker { + CoinMessageEol = 0, + CoinMessageNewline = 1 +}; + +/** Base class for message handling + + The default behavior is described here: messages are printed, and (if the + severity is sufficiently high) execution will be aborted. Inherit and + redefine the methods #print and #checkSeverity to augment the behaviour. + + Messages can be printed with or without a prefix; the prefix will consist + of a source string, the external ID number, and a letter code, + <i>e.g.</i>, Clp6024W. + A prefix makes the messages look less nimble but is very useful + for "grep" <i>etc</i>. + + <h3> Usage </h3> + + The general approach to using the COIN messaging facility is as follows: + <ul> + <li> Define your messages. For each message, you must supply an external + ID number, a log (detail) level, and a format string. Typically, you + define a convenience structure for this, something that's easy to + use to create an array of initialised message definitions at compile + time. + <li> Create a CoinMessages object, sized to accommodate the number of + messages you've defined. (Incremental growth will happen if + necessary as messages are loaded, but it's inefficient.) + <li> Load the messages into the CoinMessages object. Typically this + entails creating a CoinOneMessage object for each message and + passing it as a parameter to CoinMessages::addMessage(). You specify + the message's internal ID as the other parameter to addMessage. + <li> Create and use a CoinMessageHandler object to print messages. + </ul> + See, for example, CoinMessage.hpp and CoinMessage.cpp for an example of + the first three steps. `Format codes' below has a simple example of + printing a message. + + <h3> External ID numbers and severity </h3> + + CoinMessageHandler assumes the following relationship between the + external ID number of a message and the severity of the message: + \li <3000 are informational ('I') + \li <6000 warnings ('W') + \li <9000 non-fatal errors ('E') + \li >=9000 aborts the program (after printing the message) ('S') + + <h3> Log (detail) levels </h3> + + The default behaviour is that a message will print if its detail level + is less than or equal to the handler's log level. If all you want to + do is set a single log level for the handler, use #setLogLevel(int). + + If you want to get fancy, here's how it really works: There's an array, + #logLevels_, which you can manipulate with #setLogLevel(int,int). Each + entry logLevels_[i] specifies the log level for messages of class i (see + CoinMessages::class_). If logLevels_[0] is set to the magic number -1000 + you get the simple behaviour described above, whatever the class of the + messages. If logLevels_[0] is set to a valid log level (>= 0), then + logLevels_[i] really is the log level for messages of class i. + + <h3> Format codes </h3> + + CoinMessageHandler can print integers (normal, long, and long long), + doubles, characters, and strings. See the descriptions of the + various << operators. + + When processing a standard message with a format string, the formatting + codes specified in the format string will be passed to the sprintf + function, along with the argument. When generating a message with no + format string, each << operator uses a simple format code appropriate for + its argument. Consult the documentation for the standard printf facility + for further information on format codes. + + The special format code `%?' provides a hook to enable or disable + printing. For each `%?' code, there must be a corresponding call to + printing(bool). This provides a way to define optional parts in + messages, delineated by the code `%?' in the format string. Printing can + be suppressed for these optional parts, but any operands must still be + supplied. For example, given the message string + \verbatim + "A message with%? an optional integer %d and%? a double %g." + \endverbatim + installed in CoinMessages \c exampleMsgs with index 5, and + \c CoinMessageHandler \c hdl, the code + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(true) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with an optional integer 42 and a double 53.5. + \endverbatim + while + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(false) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with a double 53.5. + \endverbatim + + For additional examples of usage, see CoinMessageHandlerUnitTest in + CoinMessageHandlerTest.cpp. +*/ + +class CoinMessageHandler { + +friend bool CoinMessageHandlerUnitTest () ; + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Print message, return 0 normally. + */ + virtual int print() ; + /** Check message severity - if too bad then abort + */ + virtual void checkSeverity() ; + //@} + + /**@name Constructors etc */ + //@{ + /// Constructor + CoinMessageHandler(); + /// Constructor to put to file pointer (won't be closed) + CoinMessageHandler(FILE *fp); + /** Destructor */ + virtual ~CoinMessageHandler(); + /** The copy constructor */ + CoinMessageHandler(const CoinMessageHandler&); + /** Assignment operator. */ + CoinMessageHandler& operator=(const CoinMessageHandler&); + /// Clone + virtual CoinMessageHandler * clone() const; + //@} + /**@name Get and set methods */ + //@{ + /// Get detail level of a message. + inline int detail(int messageNumber, const CoinMessages &normalMessage) const + { return normalMessage.message_[messageNumber]->detail();} + /** Get current log (detail) level. */ + inline int logLevel() const + { return logLevel_;} + /** \brief Set current log (detail) level. + + If the log level is equal or greater than the detail level of a message, + the message will be printed. A rough convention for the amount of output + expected is + - 0 - none + - 1 - minimal + - 2 - normal low + - 3 - normal high + - 4 - verbose + + Please assign log levels to messages accordingly. Log levels of 8 and + above (8,16,32, <i>etc</i>.) are intended for selective debugging. + The logical AND of the log level specified in the message and the current + log level is used to determine if the message is printed. (In other words, + you're using individual bits to determine which messages are printed.) + */ + void setLogLevel(int value); + /** Get alternative log level. */ + inline int logLevel(int which) const + { return logLevels_[which];} + /*! \brief Set alternative log level value. + + Can be used to store alternative log level information within the handler. + */ + void setLogLevel(int which, int value); + + /// Set the number of significant digits for printing floating point numbers + void setPrecision(unsigned int new_precision); + /// Current number of significant digits for printing floating point numbers + inline int precision() { return (g_precision_) ; } + + /// Switch message prefix on or off. + void setPrefix(bool yesNo); + /// Current setting for printing message prefix. + bool prefix() const; + /*! \brief Values of double fields already processed. + + As the parameter for a double field is processed, the value is saved + and can be retrieved using this function. + */ + inline double doubleValue(int position) const + { return doubleValue_[position];} + /*! \brief Number of double fields already processed. + + Incremented each time a field of type double is processed. + */ + inline int numberDoubleFields() const + {return static_cast<int>(doubleValue_.size());} + /*! \brief Values of integer fields already processed. + + As the parameter for a integer field is processed, the value is saved + and can be retrieved using this function. + */ + inline int intValue(int position) const + { return longValue_[position];} + /*! \brief Number of integer fields already processed. + + Incremented each time a field of type integer is processed. + */ + inline int numberIntFields() const + {return static_cast<int>(longValue_.size());} + /*! \brief Values of char fields already processed. + + As the parameter for a char field is processed, the value is saved + and can be retrieved using this function. + */ + inline char charValue(int position) const + { return charValue_[position];} + /*! \brief Number of char fields already processed. + + Incremented each time a field of type char is processed. + */ + inline int numberCharFields() const + {return static_cast<int>(charValue_.size());} + /*! \brief Values of string fields already processed. + + As the parameter for a string field is processed, the value is saved + and can be retrieved using this function. + */ + inline std::string stringValue(int position) const + { return stringValue_[position];} + /*! \brief Number of string fields already processed. + + Incremented each time a field of type string is processed. + */ + inline int numberStringFields() const + {return static_cast<int>(stringValue_.size());} + + /// Current message + inline CoinOneMessage currentMessage() const + {return currentMessage_;} + /// Source of current message + inline std::string currentSource() const + {return source_;} + /// Output buffer + inline const char * messageBuffer() const + {return messageBuffer_;} + /// Highest message number (indicates any errors) + inline int highestNumber() const + {return highestNumber_;} + /// Get current file pointer + inline FILE * filePointer() const + { return fp_;} + /// Set new file pointer + inline void setFilePointer(FILE * fp) + { fp_ = fp;} + //@} + + /**@name Actions to create a message */ + //@{ + /*! \brief Start a message + + Look up the specified message. A prefix will be generated if enabled. + The message will be printed if the current log level is equal or greater + than the log level of the message. + */ + CoinMessageHandler &message(int messageNumber, + const CoinMessages &messages) ; + + /*! \brief Start or continue a message + + With detail = -1 (default), does nothing except return a reference to the + handler. (I.e., msghandler.message() << "foo" is precisely equivalent + to msghandler << "foo".) If \p msgDetail is >= 0, is will be used + as the detail level to determine whether the message should print + (assuming class 0). + + This can be used with any of the << operators. One use is to start + a message which will be constructed entirely from scratch. Another + use is continuation of a message after code that interrupts the usual + sequence of << operators. + */ + CoinMessageHandler & message(int detail = -1) ; + + /*! \brief Print a complete message + + Generate a standard prefix and append \c msg `as is'. This is intended as + a transition mechanism. The standard prefix is generated (if enabled), + and \c msg is appended. The message must be ended with a CoinMessageEol + marker. Attempts to add content with << will have no effect. + + The default value of \p detail will not change printing status. If + \p detail is >= 0, it will be used as the detail level to determine + whether the message should print (assuming class 0). + + */ + CoinMessageHandler &message(int externalNumber, const char *source, + const char *msg, + char severity, int detail = -1) ; + + /*! \brief Process an integer parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (int intvalue); +#if COIN_BIG_INDEX==1 + /*! \brief Process a long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long longvalue); +#endif +#if COIN_BIG_INDEX==2 + /*! \brief Process a long long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long long longvalue); +#endif + /*! \brief Process a double parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (double doublevalue); + /*! \brief Process a STL string parameter value. + + The default format code is `%g'. + */ + CoinMessageHandler & operator<< (const std::string& stringvalue); + /*! \brief Process a char parameter value. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (char charvalue); + /*! \brief Process a C-style string parameter value. + + The default format code is `%c'. + */ + CoinMessageHandler & operator<< (const char *stringvalue); + /*! \brief Process a marker. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (CoinMessageMarker); + /** Finish (and print) the message. + + Equivalent to using the CoinMessageEol marker. + */ + int finish(); + /*! \brief Enable or disable printing of an optional portion of a message. + + Optional portions of a message are delimited by `%?' markers, and + printing processes one %? marker. If \c onOff is true, the subsequent + portion of the message (to the next %? marker or the end of the format + string) will be printed. If \c onOff is false, printing is suppressed. + Parameters must still be supplied, whether printing is suppressed or not. + See the class documentation for an example. + */ + CoinMessageHandler & printing(bool onOff); + + //@} + + /** Log levels will be by type and will then use type + given in CoinMessage::class_ + + - 0 - Branch and bound code or similar + - 1 - Solver + - 2 - Stuff in Coin directory + - 3 - Cut generators + */ +#define COIN_NUM_LOG 4 +/// Maximum length of constructed message (characters) +#define COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE 1000 +protected: + /**@name Protected member data */ + //@{ + /// values in message + std::vector<double> doubleValue_; + std::vector<int> longValue_; + std::vector<char> charValue_; + std::vector<std::string> stringValue_; + /// Log level + int logLevel_; + /// Log levels + int logLevels_[COIN_NUM_LOG]; + /// Whether we want prefix (may get more subtle so is int) + int prefix_; + /// Current message + CoinOneMessage currentMessage_; + /// Internal number for use with enums + int internalNumber_; + /// Format string for message (remainder) + char * format_; + /// Output buffer + char messageBuffer_[COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE]; + /// Position in output buffer + char * messageOut_; + /// Current source of message + std::string source_; + /** 0 - Normal. + 1 - Put in values, move along format, but don't print. + 2 - A complete message was provided; nothing more to do but print + when CoinMessageEol is processed. Any << operators are treated + as noops. + 3 - do nothing except look for CoinMessageEol (i.e., the message + detail level was not sufficient to cause it to print). + */ + int printStatus_; + /// Highest message number (indicates any errors) + int highestNumber_; + /// File pointer + FILE * fp_; + /// Current format for floating point numbers + char g_format_[8]; + /// Current number of significant digits for floating point numbers + int g_precision_ ; + //@} + +private: + + /** The body of the copy constructor and the assignment operator */ + void gutsOfCopy(const CoinMessageHandler &rhs) ; + + /*! \brief Internal function to locate next format code. + + Intended for internal use. Side effects modify the format string. + */ + char *nextPerCent(char *start, const bool initial = false) ; + + /*! \brief Internal printing function. + + Makes it easier to split up print into clean, print and check severity + */ + int internalPrint() ; + + /// Decide if this message should print. + void calcPrintStatus(int msglvl, int msgclass) ; + + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMessageHandler class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +bool +CoinMessageHandlerUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinModel.hpp b/thirdparty/linux/include/coin/coin/CoinModel.hpp new file mode 100644 index 0000000..6d1ff5b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinModel.hpp @@ -0,0 +1,1054 @@ +/* $Id: CoinModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModel_H +#define CoinModel_H + +#include "CoinModelUseful.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinFinite.hpp" +class CoinBaseModel { + +public: + + + /**@name Constructors, destructor */ + //@{ + /// Default Constructor + CoinBaseModel (); + + /// Copy constructor + CoinBaseModel ( const CoinBaseModel &rhs); + + /// Assignment operator + CoinBaseModel & operator=( const CoinBaseModel& rhs); + + /// Clone + virtual CoinBaseModel * clone() const=0; + + /// Destructor + virtual ~CoinBaseModel () ; + //@} + + /**@name For getting information */ + //@{ + /// Return number of rows + inline int numberRows() const + { return numberRows_;} + /// Return number of columns + inline int numberColumns() const + { return numberColumns_;} + /// Return number of elements + virtual CoinBigIndex numberElements() const = 0; + /** Returns the (constant) objective offset + This is the RHS entry for the objective row + */ + inline double objectiveOffset() const + { return objectiveOffset_;} + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Get print level 0 - off, 1 - errors, 2 - more + inline int logLevel() const + { return logLevel_;} + /// Set print level 0 - off, 1 - errors, 2 - more + void setLogLevel(int value); + /// Return the problem name + inline const char * getProblemName() const + { return problemName_.c_str();} + /// Set problem name + void setProblemName(const char *name) ; + /// Set problem name + void setProblemName(const std::string &name) ; + /// Return the row block name + inline const std::string & getRowBlock() const + { return rowBlockName_;} + /// Set row block name + inline void setRowBlock(const std::string &name) + { rowBlockName_ = name;} + /// Return the column block name + inline const std::string & getColumnBlock() const + { return columnBlockName_;} + /// Set column block name + inline void setColumnBlock(const std::string &name) + { columnBlockName_ = name;} + /// Pass in message handler + void setMessageHandler(CoinMessageHandler * handler); + //@} + +protected: + /**@name Data members */ + //@{ + /// Current number of rows + int numberRows_; + /// Current number of columns + int numberColumns_; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Objective offset to be passed on + double objectiveOffset_; + /// Problem name + std::string problemName_; + /// Rowblock name + std::string rowBlockName_; + /// Columnblock name + std::string columnBlockName_; + /// Message handler (Passed in) + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + + /** Print level. + I could have gone for full message handling but this should normally + be silent and lightweight. + -1 - use passed in message handler + 0 - no output + 1 - on errors + 2 - more detailed + */ + int logLevel_; + //@} + /// data + +}; + +/** + This is a simple minded model which is stored in a format which makes + it easier to construct and modify but not efficient for algorithms. It has + to be passed across to ClpModel or OsiSolverInterface by addRows, addCol(umn)s + or loadProblem. + + It may have up to four parts - + 1) A matrix of doubles (or strings - see note A) + 2) Column information including integer information and names + 3) Row information including names + 4) Quadratic objective (not implemented - but see A) + + This class is meant to make it more efficient to build a model. It is at + its most efficient when all additions are done as addRow or as addCol but + not mixed. If only 1 and 2 exist then solver.addColumns may be used to pass to solver, + if only 1 and 3 exist then solver.addRows may be used. Otherwise solver.loadProblem + must be used. + + If addRows and addColumns are mixed or if individual elements are set then the + speed will drop to some extent and more memory will be used. + + It is also possible to iterate over existing elements and to access columns and rows + by name. Again each of these use memory and cpu time. However memory is unlikely + to be critical as most algorithms will use much more. + + Notes: + A) Although this could be used to pass nonlinear information around the + only use at present is to have named values e.g. value1 which can then be + set to a value after model is created. I have no idea whether that could + be useful but I thought it might be fun. + Quadratic terms are allowed in strings! A solver could try and use this + if so - the convention is that 0.5* quadratic is stored + + B) This class could be useful for modeling. +*/ + +class CoinModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a row - numberInRow may be zero */ + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX, const char * name=NULL); + /// add a column - numberInColumn may be zero */ + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false); + /// add a column - numberInColumn may be zero */ + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue, + name,isInteger);} + /// Sets value for row i and column j + inline void operator() (int i,int j,double value) + { setElement(i,j,value);} + /// Sets value for row i and column j + void setElement(int i,int j,double value) ; + /** Gets sorted row - user must provide enough space + (easiest is allocate number of columns). + If column or element NULL then just returns number + Returns number of elements + */ + int getRow(int whichRow, int * column, double * element); + /** Gets sorted column - user must provide enough space + (easiest is allocate number of rows). + If row or element NULL then just returns number + Returns number of elements + */ + int getColumn(int whichColumn, int * column, double * element); + /// Sets quadratic value for column i and j + void setQuadraticElement(int i,int j,double value) ; + /// Sets value for row i and column j as string + inline void operator() (int i,int j,const char * value) + { setElement(i,j,value);} + /// Sets value for row i and column j as string + void setElement(int i,int j,const char * value) ; + /// Associates a string with a value. Returns string id (or -1 if does not exist) + int associateElement(const char * stringValue, double value); + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,double rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,double rowUpper); + /** Sets rowLower and rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowBounds(int whichRow,double rowLower,double rowUpper); + /** Sets name (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowName(int whichRow,const char * rowName); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,double columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,double columnUpper); + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnBounds(int whichColumn,double columnLower,double columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,double columnObjective); + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnName(int whichColumn,const char * columnName); + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,bool columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setInteger(int whichColumn) + { setColumnIsInteger( whichColumn, true);} + /** Sets continuous (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setContinuous(int whichColumn) + { setColumnIsInteger( whichColumn, false);} + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColLower(int whichColumn,double columnLower) + { setColumnLower( whichColumn, columnLower);} + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColUpper(int whichColumn,double columnUpper) + { setColumnUpper( whichColumn, columnUpper);} + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColBounds(int whichColumn,double columnLower,double columnUpper) + { setColumnBounds( whichColumn, columnLower, columnUpper);} + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColName(int whichColumn,const char * columnName) + { setColumnName( whichColumn, columnName);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,const char * rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,const char * rowUpper); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,const char * columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,const char * columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,const char * columnObjective); + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,const char * columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,const char * columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,const char * columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Deletes all entries in row and bounds. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteRow(int whichRow); + /** Deletes all entries in column and bounds and objective. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteColumn(int whichColumn); + /** Deletes all entries in column and bounds. If last column the number of columns + will be decremented and true returned. */ + inline void deleteCol(int whichColumn) + { deleteColumn(whichColumn);} + /// Takes element out of matrix - returning position (<0 if not there); + int deleteElement(int row, int column); + /// Takes element out of matrix when position known + void deleteThisElement(int row, int column,int position); + /** Packs down all rows i.e. removes empty rows permanently. Empty rows + have no elements and feasible bounds. returns number of rows deleted. */ + int packRows(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + int packColumns(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + inline int packCols() + { return packColumns();} + /** Packs down all rows and columns. i.e. removes empty rows and columns permanently. + Empty rows have no elements and feasible bounds. + Empty columns have no elements and no objective. + returns number of rows+columns deleted. */ + int pack(); + + /** Sets columnObjective array + */ + void setObjective(int numberColumns,const double * objective) ; + /** Sets columnLower array + */ + void setColumnLower(int numberColumns,const double * columnLower); + /** Sets columnLower array + */ + inline void setColLower(int numberColumns,const double * columnLower) + { setColumnLower( numberColumns, columnLower);} + /** Sets columnUpper array + */ + void setColumnUpper(int numberColumns,const double * columnUpper); + /** Sets columnUpper array + */ + inline void setColUpper(int numberColumns,const double * columnUpper) + { setColumnUpper( numberColumns, columnUpper);} + /** Sets rowLower array + */ + void setRowLower(int numberRows,const double * rowLower); + /** Sets rowUpper array + */ + void setRowUpper(int numberRows,const double * rowUpper); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + May modify both models by cleaning up + */ + int differentModel(CoinModel & other, bool ignoreNames); + //@} + + + /**@name For structured models */ + //@{ + /// Pass in CoinPackedMatrix (and switch off element updates) + void passInMatrix(const CoinPackedMatrix & matrix); + /** Convert elements to CoinPackedMatrix (and switch off element updates). + Returns number of errors */ + int convertMatrix(); + /// Return a pointer to CoinPackedMatrix (or NULL) + inline const CoinPackedMatrix * packedMatrix() const + { return packedMatrix_;} + /// Return pointers to original rows (for decomposition) + inline const int * originalRows() const + { return rowType_;} + /// Return pointers to original columns (for decomposition) + inline const int * originalColumns() const + { return columnType_;} + //@} + + + /**@name For getting information */ + //@{ + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /// Return elements as triples + inline const CoinModelTriple * elements() const + { return elements_;} + /// Returns value for row i and column j + inline double operator() (int i,int j) const + { return getElement(i,j);} + /// Returns value for row i and column j + double getElement(int i,int j) const; + /// Returns value for row rowName and column columnName + inline double operator() (const char * rowName,const char * columnName) const + { return getElement(rowName,columnName);} + /// Returns value for row rowName and column columnName + double getElement(const char * rowName,const char * columnName) const; + /// Returns quadratic value for columns i and j + double getQuadraticElement(int i,int j) const; + /** Returns value for row i and column j as string. + Returns NULL if does not exist. + Returns "Numeric" if not a string + */ + const char * getElementAsString(int i,int j) const; + /** Returns pointer to element for row i column j. + Only valid until next modification. + NULL if element does not exist */ + double * pointer (int i,int j) const; + /** Returns position in elements for row i column j. + Only valid until next modification. + -1 if element does not exist */ + int position (int i,int j) const; + + + /** Returns first element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInRow(int whichRow) const ; + /** Returns last element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInRow(int whichRow) const ; + /** Returns first element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInColumn(int whichColumn) const ; + /** Returns last element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInColumn(int whichColumn) const ; + /** Returns next element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.next would be NULL + */ + CoinModelLink next(CoinModelLink & current) const ; + /** Returns previous element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.previous would be NULL + May not be correct if matrix updated. + */ + CoinModelLink previous(CoinModelLink & current) const ; + /** Returns first element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + May not be correct if matrix updated. + */ + CoinModelLink firstInQuadraticColumn(int whichColumn) const ; + /** Returns last element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInQuadraticColumn(int whichColumn) const ; + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + double getRowLower(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + double getRowUpper(int whichRow) const ; + /** Gets name (if row does not exist then NULL) + */ + const char * getRowName(int whichRow) const ; + inline double rowLower(int whichRow) const + { return getRowLower(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline double rowUpper(int whichRow) const + { return getRowUpper(whichRow) ;} + /** Gets name (if row does not exist then NULL) + */ + inline const char * rowName(int whichRow) const + { return getRowName(whichRow);} + /** Gets columnLower (if column does not exist then 0.0) + */ + double getColumnLower(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + double getColumnUpper(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + double getColumnObjective(int whichColumn) const ; + /** Gets name (if column does not exist then NULL) + */ + const char * getColumnName(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + bool getColumnIsInteger(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double columnLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double columnUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double columnObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double objective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * columnName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool columnIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool isInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double getColLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double getColUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double getColObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * getColName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool getColIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + const char * getRowLowerAsString(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + const char * getRowUpperAsString(int whichRow) const ; + inline const char * rowLowerAsString(int whichRow) const + { return getRowLowerAsString(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline const char * rowUpperAsString(int whichRow) const + { return getRowUpperAsString(whichRow) ;} + /** Gets columnLower (if column does not exist then 0.0) + */ + const char * getColumnLowerAsString(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + const char * getColumnUpperAsString(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + const char * getColumnObjectiveAsString(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + const char * getColumnIsIntegerAsString(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline const char * columnLowerAsString(int whichColumn) const + { return getColumnLowerAsString(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline const char * columnUpperAsString(int whichColumn) const + { return getColumnUpperAsString(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * columnObjectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * objectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * columnIsIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * isIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /// Row index from row name (-1 if no names or no match) + int row(const char * rowName) const; + /// Column index from column name (-1 if no names or no match) + int column(const char * columnName) const; + /// Returns type + inline int type() const + { return type_;} + /// returns unset value + inline double unsetValue() const + { return -1.23456787654321e-97;} + /// Creates a packed matrix - return number of errors + int createPackedMatrix(CoinPackedMatrix & matrix, + const double * associated); + /** Fills in startPositive and startNegative with counts for +-1 matrix. + If not +-1 then startPositive[0]==-1 otherwise counts and + startPositive[numberColumns]== size + - return number of errors + */ + int countPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + const double * associated); + /** Creates +-1 matrix given startPositive and startNegative counts for +-1 matrix. + */ + void createPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + int * indices, + const double * associated); + /// Creates copies of various arrays - return number of errors + int createArrays(double * & rowLower, double * & rowUpper, + double * & columnLower, double * & columnUpper, + double * & objective, int * & integerType, + double * & associated); + /// Says if strings exist + inline bool stringsExist() const + { return string_.numberItems()!=0;} + /// Return string array + inline const CoinModelHash * stringArray() const + { return &string_;} + /// Returns associated array + inline double * associatedArray() const + { return associated_;} + /// Return rowLower array + inline double * rowLowerArray() const + { return rowLower_;} + /// Return rowUpper array + inline double * rowUpperArray() const + { return rowUpper_;} + /// Return columnLower array + inline double * columnLowerArray() const + { return columnLower_;} + /// Return columnUpper array + inline double * columnUpperArray() const + { return columnUpper_;} + /// Return objective array + inline double * objectiveArray() const + { return objective_;} + /// Return integerType array + inline int * integerTypeArray() const + { return integerType_;} + /// Return row names array + inline const CoinModelHash * rowNames() const + { return &rowName_;} + /// Return column names array + inline const CoinModelHash * columnNames() const + { return &columnName_;} + /// Reset row names + inline void zapRowNames() + { rowName_=CoinModelHash();} + /// Reset column names + inline void zapColumnNames() + { columnName_=CoinModelHash();} + /// Returns array of 0 or nonzero if can be a cut (or returns NULL) + inline const int * cutMarker() const + { return cut_;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Return pointer to more information + inline void * moreInfo() const + { return moreInfo_;} + /// Set pointer to more information + inline void setMoreInfo(void * info) + { moreInfo_ = info;} + /** Returns which parts of model are set + 1 - matrix + 2 - rhs + 4 - row names + 8 - column bounds and/or objective + 16 - column names + 32 - integer types + */ + int whatIsSet() const; + //@} + + /**@name for block models - matrix will be CoinPackedMatrix */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadBlock method using rowlb and rowub for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadBlock method using sense/rhs/range for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModel(); + /** Constructor with sizes. */ + CoinModel(int firstRows, int firstColumns, int firstElements,bool noNames=false); + /** Read a problem in MPS or GAMS format from the given filename. + */ + CoinModel(const char *fileName, int allowStrings=0); + /** Read a problem from AMPL nl file + NOTE - as I can't work out configure etc the source code is in Cbc_ampl.cpp! + */ + CoinModel( int nonLinear, const char * fileName,const void * info); + /// From arrays + CoinModel(int numberRows, int numberColumns, + const CoinPackedMatrix * matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + /// Clone + virtual CoinBaseModel * clone() const; + + /** Destructor */ + virtual ~CoinModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModel(const CoinModel&); + /// = + CoinModel& operator=(const CoinModel&); + //@} + + /**@name For debug */ + //@{ + /// Checks that links are consistent + void validateLinks() const; + //@} +private: + /// Resize + void resize(int maximumRows, int maximumColumns, int maximumElements); + /// Fill in default row information + void fillRows(int which,bool forceCreation,bool fromAddRow=false); + /// Fill in default column information + void fillColumns(int which,bool forceCreation,bool fromAddColumn=false); + /** Fill in default linked list information (1= row, 2 = column) + Marked as const as list is mutable */ + void fillList(int which, CoinModelLinkedList & list,int type) const ; + /** Create a linked list and synchronize free + type 1 for row 2 for column + Marked as const as list is mutable */ + void createList(int type) const; + /// Adds one string, returns index + int addString(const char * string); + /** Gets a double from a string possibly containing named strings, + returns unset if not found + */ + double getDoubleFromString(CoinYacc & info, const char * string); + /// Frees value memory + void freeStringMemory(CoinYacc & info); +public: + /// Fills in all associated - returning number of errors + int computeAssociated(double * associated); + /** Gets correct form for a quadratic row - user to delete + If row is not quadratic then returns which other variables are involved + with tiny (1.0e-100) elements and count of total number of variables which could not + be put in quadratic form + */ + CoinPackedMatrix * quadraticRow(int rowNumber,double * linear, + int & numberBad) const; + /// Replaces a quadratic row + void replaceQuadraticRow(int rowNumber,const double * linear, const CoinPackedMatrix * quadraticPart); + /** If possible return a model where if all variables marked nonzero are fixed + the problem will be linear. At present may only work if quadratic. + Returns NULL if not possible + */ + CoinModel * reorder(const char * mark) const; + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput,double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement,int reConstruct=-1) const; + /// Sets cut marker array + void setCutMarker(int size,const int * marker); + /// Sets priority array + void setPriorities(int size,const int * priorities); + /// priorities (given for all columns (-1 if not integer) + inline const int * priorities() const + { return priority_;} + /// For decomposition set original row and column indices + void setOriginalIndices(const int * row, const int * column); + +private: + /** Read a problem from AMPL nl file + so not constructor so gdb will work + */ + void gdb( int nonLinear, const char * fileName, const void * info); + /// returns jColumn (-2 if linear term, -1 if unknown) and coefficient + int decodeBit(char * phrase, char * & nextPhrase, double & coefficient, bool ifFirst) const; + /// Aborts with message about packedMatrix + void badType() const; + /**@name Data members */ + //@{ + /// Maximum number of rows + int maximumRows_; + /// Maximum number of columns + int maximumColumns_; + /// Current number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// Current number of quadratic elements + int numberQuadraticElements_; + /// Maximum number of quadratic elements + int maximumQuadraticElements_; + /// Row lower + double * rowLower_; + /// Row upper + double * rowUpper_; + /// Row names + CoinModelHash rowName_; + /** Row types. + Has information - at present + bit 0 - rowLower is a string + bit 1 - rowUpper is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original rows (i.e. when decomposed) + */ + int * rowType_; + /// Objective + double * objective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Column names + CoinModelHash columnName_; + /// Integer information + int * integerType_; + /// Strings + CoinModelHash string_; + /** Column types. + Has information - at present + bit 0 - columnLower is a string + bit 1 - columnUpper is a string + bit 2 - objective is a string + bit 3 - integer setting is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original columns (i.e. when decomposed) + */ + int * columnType_; + /// If simple then start of each row/column + int * start_; + /// Actual elements + CoinModelTriple * elements_; + /// Actual elements as CoinPackedMatrix + CoinPackedMatrix * packedMatrix_; + /// Hash for elements + mutable CoinModelHash2 hashElements_; + /// Linked list for rows + mutable CoinModelLinkedList rowList_; + /// Linked list for columns + mutable CoinModelLinkedList columnList_; + /// Actual quadratic elements (always linked lists) + CoinModelTriple * quadraticElements_; + /// Hash for quadratic elements + mutable CoinModelHash2 hashQuadraticElements_; + /// Array for sorting indices + int * sortIndices_; + /// Array for sorting elements + double * sortElements_; + /// Size of sort arrays + int sortSize_; + /// Linked list for quadratic rows + mutable CoinModelLinkedList quadraticRowList_; + /// Linked list for quadratic columns + mutable CoinModelLinkedList quadraticColumnList_; + /// Size of associated values + int sizeAssociated_; + /// Associated values + double * associated_; + /// Number of SOS - all these are done in one go e.g. from ampl + int numberSOS_; + /// SOS starts + int * startSOS_; + /// SOS members + int * memberSOS_; + /// SOS type + int * typeSOS_; + /// SOS priority + int * prioritySOS_; + /// SOS reference + double * referenceSOS_; + /// priorities (given for all columns (-1 if not integer) + int * priority_; + /// Nonzero if row is cut - done in one go e.g. from ampl + int * cut_; + /// Pointer to more information + void * moreInfo_; + /** Type of build - + -1 unset, + 0 for row, + 1 for column, + 2 linked. + 3 matrix is CoinPackedMatrix (and at present can't be modified); + */ + mutable int type_; + /// True if no names EVER being used (for users who know what they are doing) + bool noNames_; + /** Links present (could be tested by sizes of objects) + 0 - none, + 1 - row links, + 2 - column links, + 3 - both + */ + mutable int links_; + //@} +}; +/// Just function of single variable x +double getFunctionValueFromString(const char * string, const char * x, double xValue); +/// faster version +double getDoubleFromString(CoinYacc & info, const char * string, const char * x, double xValue); +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinModelUseful.hpp b/thirdparty/linux/include/coin/coin/CoinModelUseful.hpp new file mode 100644 index 0000000..f9eeea3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinModelUseful.hpp @@ -0,0 +1,441 @@ +/* $Id: CoinModelUseful.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModelUseful_H +#define CoinModelUseful_H + + +#include <cstdlib> +#include <cmath> +#include <cassert> +#include <cfloat> +#include <cstring> +#include <cstdio> +#include <iostream> + + +#include "CoinPragma.hpp" + +/** + This is for various structures/classes needed by CoinModel. + + CoinModelLink + CoinModelLinkedList + CoinModelHash +*/ +/// for going through row or column + +class CoinModelLink { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLink(); + /** Destructor */ + ~CoinModelLink(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLink(const CoinModelLink&); + /// = + CoinModelLink& operator=(const CoinModelLink&); + //@} + + /**@name Sets and gets method */ + //@{ + /// Get row + inline int row() const + { return row_;} + /// Get column + inline int column() const + { return column_;} + /// Get value + inline double value() const + { return value_;} + /// Get value + inline double element() const + { return value_;} + /// Get position + inline int position() const + { return position_;} + /// Get onRow + inline bool onRow() const + { return onRow_;} + /// Set row + inline void setRow(int row) + { row_=row;} + /// Set column + inline void setColumn(int column) + { column_=column;} + /// Set value + inline void setValue(double value) + { value_=value;} + /// Set value + inline void setElement(double value) + { value_=value;} + /// Set position + inline void setPosition(int position) + { position_=position;} + /// Set onRow + inline void setOnRow(bool onRow) + { onRow_=onRow;} + //@} + +private: + /**@name Data members */ + //@{ + /// Row + int row_; + /// Column + int column_; + /// Value as double + double value_; + /// Position in data + int position_; + /// If on row chain + bool onRow_; + //@} +}; + +/// for linked lists +// for specifying triple +typedef struct { + // top bit is nonzero if string + // rest is row + unsigned int row; + //CoinModelRowIndex row; + int column; + double value; // If string then index into strings +} CoinModelTriple; +inline int rowInTriple(const CoinModelTriple & triple) +{ return triple.row&0x7fffffff;} +inline void setRowInTriple(CoinModelTriple & triple,int iRow) +{ triple.row = iRow|(triple.row&0x80000000);} +inline bool stringInTriple(const CoinModelTriple & triple) +{ return (triple.row&0x80000000)!=0;} +inline void setStringInTriple(CoinModelTriple & triple,bool string) +{ triple.row = (string ? 0x80000000 : 0)|(triple.row&0x7fffffff);} +inline void setRowAndStringInTriple(CoinModelTriple & triple, + int iRow,bool string) +{ triple.row = (string ? 0x80000000 : 0)|iRow;} +/// for names and hashing +// for hashing +typedef struct { + int index, next; +} CoinModelHashLink; + +/* Function type. */ +typedef double (*func_t) (double); + +/// For string evaluation +/* Data type for links in the chain of symbols. */ +struct symrec +{ + char *name; /* name of symbol */ + int type; /* type of symbol: either VAR or FNCT */ + union + { + double var; /* value of a VAR */ + func_t fnctptr; /* value of a FNCT */ + } value; + struct symrec *next; /* link field */ +}; + +typedef struct symrec symrec; + +class CoinYacc { +private: + CoinYacc(const CoinYacc& rhs); + CoinYacc& operator=(const CoinYacc& rhs); + +public: + CoinYacc() : symtable(NULL), symbuf(NULL), length(0), unsetValue(0) {} + ~CoinYacc() + { + if (length) { + free(symbuf); + symbuf = NULL; + } + symrec* s = symtable; + while (s) { + free(s->name); + symtable = s; + s = s->next; + free(symtable); + } + } + +public: + symrec * symtable; + char * symbuf; + int length; + double unsetValue; +}; + +class CoinModelHash { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash(); + /** Destructor */ + ~CoinModelHash(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash(const CoinModelHash&); + /// = + CoinModelHash& operator=(const CoinModelHash&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems,bool forceReHash=false); + /// Number of items i.e. rows if just row names + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + /// Names + inline const char *const * names() const + { return names_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(const char * name) const; + /// Adds to hash + void addHash(int index, const char * name); + /// Deletes from hash + void deleteHash(int index); + /// Returns name at position (or NULL) + const char * name(int which) const; + /// Returns non const name at position (or NULL) + char * getName(int which) const; + /// Sets name at position (does not create) + void setName(int which,char * name ) ; + /// Validates + void validateHash() const; +private: + /// Returns a hash value + int hashValue(const char * name) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// Names + char ** names_; + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +/// For int,int hashing +class CoinModelHash2 { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash2(); + /** Destructor */ + ~CoinModelHash2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash2(const CoinModelHash2&); + /// = + CoinModelHash2& operator=(const CoinModelHash2&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems, const CoinModelTriple * triples,bool forceReHash=false); + /// Number of items + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(int row, int column, const CoinModelTriple * triples) const; + /// Adds to hash + void addHash(int index, int row, int column, const CoinModelTriple * triples); + /// Deletes from hash + void deleteHash(int index, int row, int column); +private: + /// Returns a hash value + int hashValue(int row, int column) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +class CoinModelLinkedList { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLinkedList(); + /** Destructor */ + ~CoinModelLinkedList(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLinkedList(const CoinModelLinkedList&); + /// = + CoinModelLinkedList& operator=(const CoinModelLinkedList&); + //@} + + /**@name sizing (just increases) */ + //@{ + /** Resize list - for row list maxMajor is maximum rows. + */ + void resize(int maxMajor,int maxElements); + /** Create list - for row list maxMajor is maximum rows. + type 0 row list, 1 column list + */ + void create(int maxMajor,int maxElements, + int numberMajor, int numberMinor, + int type, + int numberElements, const CoinModelTriple * triples); + /// Number of major items i.e. rows if just row links + inline int numberMajor() const + { return numberMajor_;} + /// Maximum number of major items i.e. rows if just row links + inline int maximumMajor() const + { return maximumMajor_;} + /// Number of elements + inline int numberElements() const + { return numberElements_;} + /// Maximum number of elements + inline int maximumElements() const + { return maximumElements_;} + /// First on free chain + inline int firstFree() const + { return first_[maximumMajor_];} + /// Last on free chain + inline int lastFree() const + { return last_[maximumMajor_];} + /// First on chain + inline int first(int which) const + { return first_[which];} + /// Last on chain + inline int last(int which) const + { return last_[which];} + /// Next array + inline const int * next() const + { return next_;} + /// Previous array + inline const int * previous() const + { return previous_;} + //@} + + /**@name does work */ + //@{ + /** Adds to list - easy case i.e. add row to row list + Returns where chain starts + */ + int addEasy(int majorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + */ + void addHard(int minorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + This is when elements have been added to other copy + */ + void addHard(int first, const CoinModelTriple * triples, + int firstFree, int lastFree,const int * nextOther); + /** Deletes from list - same case i.e. delete row from row list + */ + void deleteSame(int which, CoinModelTriple * triples, + CoinModelHash2 & hash, bool zapTriples); + /** Deletes from list - other case i.e. delete row from column list + This is when elements have been deleted from other copy + */ + void updateDeleted(int which, CoinModelTriple * triples, + CoinModelLinkedList & otherList); + /** Deletes one element from Row list + */ + void deleteRowOne(int position, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Update column list for one element when + one element deleted from row copy + */ + void updateDeletedOne(int position, const CoinModelTriple * triples); + /// Fills first,last with -1 + void fill(int first,int last); + /** Puts in free list from other list */ + void synchronize(CoinModelLinkedList & other); + /// Checks that links are consistent + void validateLinks(const CoinModelTriple * triples) const; + //@} +private: + /**@name Data members */ + //@{ + /// Previous - maximumElements long + int * previous_; + /// Next - maximumElements long + int * next_; + /// First - maximumMajor+1 long (last free element chain) + int * first_; + /// Last - maximumMajor+1 long (last free element chain) + int * last_; + /// Number of major items i.e. rows if just row links + int numberMajor_; + /// Maximum number of major items i.e. rows if just row links + int maximumMajor_; + /// Number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// 0 row list, 1 column list + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinMpsIO.hpp b/thirdparty/linux/include/coin/coin/CoinMpsIO.hpp new file mode 100644 index 0000000..8f0226a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinMpsIO.hpp @@ -0,0 +1,1056 @@ +/* $Id: CoinMpsIO.hpp 1642 2013-10-16 00:43:14Z tkr $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMpsIO_H +#define CoinMpsIO_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <vector> +#include <string> + +#include "CoinUtilsConfig.h" +#include "CoinPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinFileIO.hpp" +class CoinModel; + +/// The following lengths are in decreasing order (for 64 bit etc) +/// Large enough to contain element index +/// This is already defined as CoinBigIndex +/// Large enough to contain column index +typedef int COINColumnIndex; + +/// Large enough to contain row index (or basis) +typedef int COINRowIndex; + +// We are allowing free format - but there is a limit! +// User can override by using CXXFLAGS += -DCOIN_MAX_FIELD_LENGTH=nnn +#ifndef COIN_MAX_FIELD_LENGTH +#define COIN_MAX_FIELD_LENGTH 160 +#endif +#define MAX_CARD_LENGTH 5*COIN_MAX_FIELD_LENGTH+80 + +enum COINSectionType { COIN_NO_SECTION, COIN_NAME_SECTION, COIN_ROW_SECTION, + COIN_COLUMN_SECTION, + COIN_RHS_SECTION, COIN_RANGES_SECTION, COIN_BOUNDS_SECTION, + COIN_ENDATA_SECTION, COIN_EOF_SECTION, COIN_QUADRATIC_SECTION, + COIN_CONIC_SECTION,COIN_QUAD_SECTION,COIN_SOS_SECTION, + COIN_BASIS_SECTION,COIN_UNKNOWN_SECTION +}; + +enum COINMpsType { COIN_N_ROW, COIN_E_ROW, COIN_L_ROW, COIN_G_ROW, + COIN_BLANK_COLUMN, COIN_S1_COLUMN, COIN_S2_COLUMN, COIN_S3_COLUMN, + COIN_INTORG, COIN_INTEND, COIN_SOSEND, COIN_UNSET_BOUND, + COIN_UP_BOUND, COIN_FX_BOUND, COIN_LO_BOUND, COIN_FR_BOUND, + COIN_MI_BOUND, COIN_PL_BOUND, COIN_BV_BOUND, + COIN_UI_BOUND, COIN_LI_BOUND, COIN_BOTH_BOUNDS_SET, + COIN_SC_BOUND, COIN_S1_BOUND, COIN_S2_BOUND, + COIN_BS_BASIS, COIN_XL_BASIS, COIN_XU_BASIS, + COIN_LL_BASIS, COIN_UL_BASIS, COIN_UNKNOWN_MPS_TYPE +}; +class CoinMpsIO; +/// Very simple code for reading MPS data +class CoinMpsCardReader { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor expects file to be open + /// This one takes gzFile if fp null + CoinMpsCardReader ( CoinFileInput *input, CoinMpsIO * reader ); + + /// Destructor + ~CoinMpsCardReader ( ); + //@} + + + /**@name card stuff */ + //@{ + /// Read to next section + COINSectionType readToNextSection ( ); + /// Gets next field and returns section type e.g. COIN_COLUMN_SECTION + COINSectionType nextField ( ); + /** Gets next field for .gms file and returns type. + -1 - EOF + 0 - what we expected (and processed so pointer moves past) + 1 - not what we expected + leading blanks always ignored + input types + 0 - anything - stops on non blank card + 1 - name (in columnname) + 2 - value + 3 - value name pair + 4 - equation type + 5 - ; + */ + int nextGmsField ( int expectedType ); + /// Returns current section type + inline COINSectionType whichSection ( ) const { + return section_; + } + /// Sets current section type + inline void setWhichSection(COINSectionType section ) { + section_=section; + } + /// Sees if free format. + inline bool freeFormat() const + { return freeFormat_;} + /// Sets whether free format. Mainly for blank RHS etc + inline void setFreeFormat(bool yesNo) + { freeFormat_=yesNo;} + /// Only for first field on card otherwise BLANK_COLUMN + /// e.g. COIN_E_ROW + inline COINMpsType mpsType ( ) const { + return mpsType_; + } + /// Reads and cleans card - taking out trailing blanks - return 1 if EOF + int cleanCard(); + /// Returns row name of current field + inline const char *rowName ( ) const { + return rowName_; + } + /// Returns column name of current field + inline const char *columnName ( ) const { + return columnName_; + } + /// Returns value in current field + inline double value ( ) const { + return value_; + } + /// Returns value as string in current field + inline const char *valueString ( ) const { + return valueString_; + } + /// Whole card (for printing) + inline const char *card ( ) const { + return card_; + } + /// Whole card - so we look at it (not const so nextBlankOr will work for gms reader) + inline char *mutableCard ( ) { + return card_; + } + /// set position (again so gms reader will work) + inline void setPosition(char * position) + { position_=position;} + /// get position (again so gms reader will work) + inline char * getPosition() const + { return position_;} + /// Returns card number + inline CoinBigIndex cardNumber ( ) const { + return cardNumber_; + } + /// Returns file input + inline CoinFileInput * fileInput ( ) const { + return input_; + } + /// Sets whether strings allowed + inline void setStringsAllowed() + { stringsAllowed_=true;} + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Current value + double value_; + /// Current card image + char card_[MAX_CARD_LENGTH]; + /// Current position within card image + char *position_; + /// End of card + char *eol_; + /// Current COINMpsType + COINMpsType mpsType_; + /// Current row name + char rowName_[COIN_MAX_FIELD_LENGTH]; + /// Current column name + char columnName_[COIN_MAX_FIELD_LENGTH]; + /// File input + CoinFileInput *input_; + /// Which section we think we are in + COINSectionType section_; + /// Card number + CoinBigIndex cardNumber_; + /// Whether free format. Just for blank RHS etc + bool freeFormat_; + /// Whether IEEE - 0 no, 1 INTEL, 2 not INTEL + int ieeeFormat_; + /// If all names <= 8 characters then allow embedded blanks + bool eightChar_; + /// MpsIO + CoinMpsIO * reader_; + /// Message handler + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + /// Current element as characters (only if strings allowed) + char valueString_[COIN_MAX_FIELD_LENGTH]; + /// Whether strings allowed + bool stringsAllowed_; + //@} +public: + /**@name methods */ + //@{ + /// type - 0 normal, 1 INTEL IEEE, 2 other IEEE + double osi_strtod(char * ptr, char ** output, int type); + /// remove blanks + static void strcpyAndCompress ( char *to, const char *from ); + /// + static char * nextBlankOr ( char *image ); + /// For strings + double osi_strtod(char * ptr, char ** output); + //@} + +}; + +//############################################################################# +#ifdef USE_SBB +class SbbObject; +class SbbModel; +#endif +/// Very simple class for containing data on set +class CoinSet { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Default constructor + CoinSet ( ); + /// Constructor + CoinSet ( int numberEntries, const int * which); + + /// Copy constructor + CoinSet (const CoinSet &); + + /// Assignment operator + CoinSet & operator=(const CoinSet& rhs); + + /// Destructor + virtual ~CoinSet ( ); + //@} + + + /**@name gets */ + //@{ + /// Returns number of entries + inline int numberEntries ( ) const + { return numberEntries_; } + /// Returns type of set - 1 =SOS1, 2 =SOS2 + inline int setType ( ) const + { return setType_; } + /// Returns list of variables + inline const int * which ( ) const + { return which_; } + /// Returns weights + inline const double * weights ( ) const + { return weights_; } + //@} + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const + { return NULL;} + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Number of entries + int numberEntries_; + /// type of set + int setType_; + /// Which variables are in set + int * which_; + /// Weights + double * weights_; + //@} +}; + +//############################################################################# +/// Very simple class for containing SOS set +class CoinSosSet : public CoinSet{ + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor + CoinSosSet ( int numberEntries, const int * which, const double * weights, int type); + + /// Destructor + virtual ~CoinSosSet ( ); + //@} + + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const ; + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; + +//############################################################################# + +/** MPS IO Interface + + This class can be used to read in mps files without a solver. After + reading the file, the CoinMpsIO object contains all relevant data, which + may be more than a particular OsiSolverInterface allows for. Items may + be deleted to allow for flexibility of data storage. + + The implementation makes the CoinMpsIO object look very like a dummy solver, + as the same conventions are used. +*/ + +class CoinMpsIO { + friend void CoinMpsIOUnitTest(const std::string & mpsDir); + +public: + +/** @name Methods to retrieve problem information + + These methods return information about the problem held by the CoinMpsIO + object. + + Querying an object that has no data associated with it result in zeros for + the number of rows and columns, and NULL pointers from the methods that + return vectors. Const pointers returned from any data-query method are + always valid +*/ +//@{ + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + Put another way, only range constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Return true if column is a continuous variable + bool isContinuous(int colNumber) const; + + /** Return true if a column is an integer variable + + Note: This function returns true if the the column + is a binary or general integer variable. + */ + bool isInteger(int columnNumber) const; + + /** Returns array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + const char * integerColumns() const; + + /** Returns the row name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * rowName(int index) const; + + /** Returns the column name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * columnName(int index) const; + + /** Returns the index for the specified row name + + Returns -1 if the name is not found. + Returns numberRows for the objective row and > numberRows for + dropped free rows. + */ + int rowIndex(const char * name) const; + + /** Returns the index for the specified column name + + Returns -1 if the name is not found. + */ + int columnIndex(const char * name) const; + + /** Returns the (constant) objective offset + + This is the RHS entry for the objective row + */ + double objectiveOffset() const; + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + + /// Return the problem name + const char * getProblemName() const; + + /// Return the objective name + const char * getObjectiveName() const; + + /// Return the RHS vector name + const char * getRhsName() const; + + /// Return the range vector name + const char * getRangeName() const; + + /// Return the bound vector name + const char * getBoundName() const; + /// Number of string elements + inline int numberStringElements() const + { return numberStringElements_;} + /// String element + inline const char * stringElement(int i) const + { return stringElements_[i];} +//@} + + +/** @name Methods to set problem information + + Methods to load a problem into the CoinMpsIO object. +*/ +//@{ + + /// Set the problem data + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + + /** Pass in an array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + void copyInIntegerInformation(const char * integerInformation); + + /// Set problem name + void setProblemName(const char *name) ; + + /// Set objective name + void setObjectiveName(const char *name) ; + +//@} + +/** @name Parameter set/get methods + + Methods to set and retrieve MPS IO parameters. +*/ + +//@{ + /// Set infinity + void setInfinity(double value); + + /// Get infinity + double getInfinity() const; + + /// Set default upper bound for integer variables + void setDefaultBound(int value); + + /// Get default upper bound for integer variables + int getDefaultBound() const; + /// Whether to allow string elements + inline int allowStringElements() const + { return allowStringElements_;} + /// Whether to allow string elements (0 no, 1 yes, 2 yes and try flip) + inline void setAllowStringElements(int yesNo) + { allowStringElements_ = yesNo;} + /** Small element value - elements less than this set to zero on input + default is 1.0e-14 */ + inline double getSmallElementValue() const + { return smallElement_;} + inline void setSmallElementValue(double value) + { smallElement_=value;} +//@} + + +/** @name Methods for problem input and output + + Methods to read and write MPS format problem files. + + The read and write methods return the number of errors that occurred during + the IO operation, or -1 if no file is opened. + + \note + If the CoinMpsIO class was compiled with support for libz then + readMps will automatically try to append .gz to the file name and open it as + a compressed file if the specified file name cannot be opened. + (Automatic append of the .bz2 suffix when libbz is used is on the TODO list.) + + \todo + Allow for file pointers and positioning +*/ + +//@{ + /// Set the current file name for the CoinMpsIO object + void setFileName(const char * name); + + /// Get the current file name for the CoinMpsIO object + const char * getFileName() const; + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + */ + int readMps(const char *filename, const char *extension = "mps"); + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readMps(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in MPS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + \todo + Provide an interface that will allow a client to associate a + CoinMpsCardReader object with a CoinMpsIO object by setting the + cardReader_ field. + */ + int readMps(); + /// and + int readMps(int & numberSets, CoinSet **& sets); + /** Read a basis in MPS format from the given filename. + If VALUES on NAME card and solution not NULL fills in solution + status values as for CoinWarmStartBasis (but one per char) + -1 file error, 0 normal, 1 has solution values + + Use "stdin" or "-" to read from stdin. + + If sizes of names incorrect - read without names + */ + int readBasis(const char *filename, const char *extension , + double * solution, unsigned char *rowStatus, unsigned char *columnStatus, + const std::vector<std::string> & colnames,int numberColumns, + const std::vector<std::string> & rownames, int numberRows); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + if convertObjective then massages objective column + */ + int readGms(const char *filename, const char *extension = "gms",bool convertObjective=false); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readGms(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in GAMS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + */ + // Not for now int readGms(); + /// and + int readGms(int & numberSets, CoinSet **& sets); + /** Read a problem in GMPL (subset of AMPL) format from the given filenames. + */ + int readGMPL(const char *modelName, const char * dataName=NULL, bool keepNames=false); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + \param quadratic specifies quadratic objective to be output + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, + CoinPackedMatrix * quadratic = NULL, + int numberSOS=0,const CoinSet * setInfo=NULL) const; + + /// Return card reader object so can see what last card was e.g. QUADOBJ + inline const CoinMpsCardReader * reader() const + { return cardReader_;} + + /** Read in a quadratic objective from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if QSECTION + Data is assumed to be Q and objective is c + 1/2 xT Q x + No assumption is made for symmetry, positive definite, etc. + No check is made for duplicates or non-triangular if checkSymmetry==0. + If 1 checks lower triangular (so off diagonal should be 2*Q) + if 2 makes lower triangular and assumes full Q (but adds off diagonals) + + Arrays should be deleted by delete [] + + Returns number of errors: + <ul> + <li> -1: bad file + <li> -2: no Quadratic section + <li> -3: an empty section + <li> +n: then matching errors etc (symmetry forced) + <li> -4: no matching errors but fails triangular test + (triangularity forced) + </ul> + columnStart is numberColumns+1 long, others numberNonZeros + */ + int readQuadraticMps(const char * filename, + int * &columnStart, int * &column, double * &elements, + int checkSymmetry); + + /** Read in a list of cones from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if CSECTION + No checking is done that in unique cone + + Arrays should be deleted by delete [] + + Returns number of errors, -1 bad file, -2 no conic section, + -3 empty section + + columnStart is numberCones+1 long, other number of columns in matrix + + coneType is 1 for QUAD, 2 for RQUAD (numberCones long) +*/ + int readConicMps(const char * filename, + int * &columnStart, int * &column, int * &coneType, int & numberCones); + /// Set whether to move objective from matrix + inline void setConvertObjective(bool trueFalse) + { convertObjective_=trueFalse;} + /// copies in strings from a CoinModel - returns number + int copyStringElements(const CoinModel * model); + //@} + +/** @name Constructors and destructors */ +//@{ + /// Default Constructor + CoinMpsIO(); + + /// Copy constructor + CoinMpsIO (const CoinMpsIO &); + + /// Assignment operator + CoinMpsIO & operator=(const CoinMpsIO& rhs); + + /// Destructor + ~CoinMpsIO (); +//@} + + +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + + +/**@name Methods to release storage + + These methods allow the client to reduce the storage used by the CoinMpsIO + object be selectively releasing unneeded problem information. +*/ +//@{ + /** Release all information which can be re-calculated. + + E.g., row sense, copies of rows, hash tables for names. + */ + void releaseRedundantInformation(); + + /// Release all row information (lower, upper) + void releaseRowInformation(); + + /// Release all column information (lower, upper, objective) + void releaseColumnInformation(); + + /// Release integer information + void releaseIntegerInformation(); + + /// Release row names + void releaseRowNames(); + + /// Release column names + void releaseColumnNames(); + + /// Release matrix information + void releaseMatrixInformation(); + //@} + +protected: + +/**@name Miscellaneous helper functions */ + //@{ + + /// Utility method used several times to implement public methods + void + setMpsDataWithoutRowAndColNames( + const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub); + void + setMpsDataColAndRowNames( + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + void + setMpsDataColAndRowNames( + char const * const * const colnames, + char const * const * const rownames); + + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment. + void gutsOfCopy(const CoinMpsIO &); + + /// Clears problem data from the CoinMpsIO object. + void freeAll(); + + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from sense/rhs/range stryle + constraint definition to lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + + /** Deal with a filename + + As the name says. + Returns +1 if the file name is new, 0 if it's the same as before + (i.e., matches fileName_), and -1 if there's an error and the file + can't be opened. + Handles automatic append of .gz suffix when compiled with libz. + + \todo + Add automatic append of .bz2 suffix when compiled with libbz. + */ + + int dealWithFileName(const char * filename, const char * extension, + CoinFileInput * &input); + /** Add string to list + iRow==numberRows is objective, nr+1 is lo, nr+2 is up + iColumn==nc is rhs (can't cope with ranges at present) + */ + void addString(int iRow,int iColumn, const char * value); + /// Decode string + void decodeString(int iString, int & iRow, int & iColumn, const char * & value) const; + //@} + + + // for hashing + typedef struct { + int index, next; + } CoinHashLink; + + /**@name Hash table methods */ + //@{ + /// Creates hash list for names (section = 0 for rows, 1 columns) + void startHash ( char **names, const int number , int section ); + /// This one does it when names are already in + void startHash ( int section ) const; + /// Deletes hash storage + void stopHash ( int section ); + /// Finds match using hash, -1 not found + int findHash ( const char *name , int section ) const; + //@} + + /**@name Cached problem information */ + //@{ + /// Problem name + char * problemName_; + + /// Objective row name + char * objectiveName_; + + /// Right-hand side vector name + char * rhsName_; + + /// Range vector name + char * rangeName_; + + /// Bounds vector name + char * boundName_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of coefficients + CoinBigIndex numberElements_; + + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack variable upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to column-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByColumn_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of objective coefficients + double * objective_; + + /// Constant offset for objective value (i.e., RHS value for OBJ row) + double objectiveOffset_; + + + /** Pointer to dense vector specifying if a variable is continuous + (0) or integer (1). + */ + char * integerType_; + + /** Row and column names + Linked to hash table sections (0 - row names, 1 column names) + */ + char **names_[2]; + //@} + + /** @name Hash tables */ + //@{ + /// Current file name + char * fileName_; + + /// Number of entries in a hash table section + int numberHash_[2]; + + /// Hash tables (two sections, 0 - row names, 1 - column names) + mutable CoinHashLink *hash_[2]; + //@} + + /** @name CoinMpsIO object parameters */ + //@{ + /// Upper bound when no bounds for integers + int defaultBound_; + + /// Value to use for infinity + double infinity_; + /// Small element value + double smallElement_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Card reader + CoinMpsCardReader * cardReader_; + /// If .gms file should it be massaged to move objective + bool convertObjective_; + /// Whether to allow string elements + int allowStringElements_; + /// Maximum number of string elements + int maximumStringElements_; + /// Number of string elements + int numberStringElements_; + /// String elements + char ** stringElements_; + //@} + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMpsIO class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. Also, if this method is compiled with + optimization, the compilation takes 10-15 minutes and the machine pages + (has 256M core memory!)... */ +void +CoinMpsIOUnitTest(const std::string & mpsDir); +// Function to return number in most efficient way +// section is 0 for columns, 1 for rhs,ranges and 2 for bounds +/* formatType is + 0 - normal and 8 character names + 1 - extra accuracy + 2 - IEEE hex - INTEL + 3 - IEEE hex - not INTEL +*/ +void +CoinConvertDouble(int section, int formatType, double value, char outputValue[24]); + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CoinOslFactorization.hpp b/thirdparty/linux/include/coin/coin/CoinOslFactorization.hpp new file mode 100644 index 0000000..0b51b01 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinOslFactorization.hpp @@ -0,0 +1,280 @@ +/* $Id: CoinOslFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 1987, 2009, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + Authors + + John Forrest + + */ +#ifndef CoinOslFactorization_H +#define CoinOslFactorization_H +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; +/** This deals with Factorization and Updates + This is ripped off from OSL!!!!!!!!! + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + +typedef struct {int suc, pre;} EKKHlink; +typedef struct _EKKfactinfo { + double drtpiv; + double demark; + double zpivlu; + double zeroTolerance; + double areaFactor; + int *xrsadr; + int *xcsadr; + int *xrnadr; + int *xcnadr; + int *krpadr; + int *kcpadr; + int *mpermu; + int *bitArray; + int * back; + char * nonzero; + double * trueStart; + mutable double *kadrpm; + int *R_etas_index; + int *R_etas_start; + double *R_etas_element; + + int *xecadr; + int *xeradr; + double *xeeadr; + double *xe2adr; + EKKHlink * kp1adr; + EKKHlink * kp2adr; + double * kw1adr; + double * kw2adr; + double * kw3adr; + int * hpivcoR; + int nrow; + int nrowmx; + int firstDoRow; + int firstLRow; + int maxinv; + int nnetas; + int iterin; + int iter0; + int invok; + int nbfinv; + int num_resets; + int nnentl; + int nnentu; +#ifdef CLP_REUSE_ETAS + int save_nnentu; +#endif + int ndenuc; + int npivots; /* use as xpivsq in factorization */ + int kmxeta; + int xnetal; + int first_dense; + int last_dense; + int iterno; + int numberSlacks; + int lastSlack; + int firstNonSlack; + int xnetalval; + int lstart; + int if_sparse_update; + mutable int packedMode; + int switch_off_sparse_update; + int nuspike; + bool rows_ok; /* replaces test using mrstrt[1] */ +#ifdef CLP_REUSE_ETAS + mutable int reintro; +#endif + int nR_etas; + int sortedEta; /* if vector for F-T is sorted */ + int lastEtaCount; + int ifvsol; + int eta_size; + int last_eta_size; + int maxNNetas; +} EKKfactinfo; + +class CoinOslFactorization : public CoinOtherFactorization { + friend void CoinOslFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOslFactorization ( ); + /// Copy constructor + CoinOslFactorization ( const CoinOslFactorization &other); + + /// Destructor + virtual ~CoinOslFactorization ( ); + /// = copy + CoinOslFactorization & operator = ( const CoinOslFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// Condition number - product of pivots after factorization + double conditionNumber() const; + /// Get rid of all memory + virtual void clearArrays(); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + //inline void clearArrays() + //{ gutsOfDestructor();} + /// Returns array to put basis indices in + virtual int * indices() const; + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(bool clearFact=true); + /// The real work of constructor + void gutsOfInitialize(bool zapFact=true); + /// The real work of copy + void gutsOfCopy(const CoinOslFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Osl factorization data + EKKfactinfo factInfo_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPackedMatrix.hpp b/thirdparty/linux/include/coin/coin/CoinPackedMatrix.hpp new file mode 100644 index 0000000..c6837ac --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPackedMatrix.hpp @@ -0,0 +1,947 @@ +/* $Id: CoinPackedMatrix.hpp 1560 2012-11-24 00:29:01Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedMatrix_H +#define CoinPackedMatrix_H + +#include "CoinError.hpp" +#include "CoinTypes.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#include "CoinShallowPackedVector.hpp" +#else +class CoinRelFltEq; +#endif + +/** Sparse Matrix Base Class + + This class is intended to represent sparse matrices using row-major + or column-major ordering. The representation is very efficient for + adding, deleting, or retrieving major-dimension vectors. Adding + a minor-dimension vector is less efficient, but can be helped by + providing "extra" space as described in the next paragraph. Deleting + a minor-dimension vector requires inspecting all coefficients in the + matrix. Retrieving a minor-dimension vector would incur the same cost + and is not supported (except in the sense that you can write a loop to + retrieve all coefficients one at a time). Consider physically transposing + the matrix, or keeping a second copy with the other major-vector ordering. + + The sparse represention can be completely compact or it can have "extra" + space available at the end of each major vector. Incorporating extra + space into the sparse matrix representation can improve performance in + cases where new data needs to be inserted into the packed matrix against + the major-vector orientation (e.g, inserting a row into a matrix stored + in column-major order). + + For example if the matrix: + @verbatim + 3 1 0 -2 -1 0 0 -1 + 0 2 1.1 0 0 0 0 0 + 0 0 1 0 0 1 0 0 + 0 0 0 2.8 0 0 -1.2 0 + 5.6 0 0 0 1 0 0 1.9 + + was stored by rows (with no extra space) in + CoinPackedMatrix r then: + r.getElements() returns a vector containing: + 3 1 -2 -1 -1 2 1.1 1 1 2.8 -1.2 5.6 1 1.9 + r.getIndices() returns a vector containing: + 0 1 3 4 7 1 2 2 5 3 6 0 4 7 + r.getVectorStarts() returns a vector containing: + 0 5 7 9 11 14 + r.getNumElements() returns 14. + r.getMajorDim() returns 5. + r.getVectorSize(0) returns 5. + r.getVectorSize(1) returns 2. + r.getVectorSize(2) returns 2. + r.getVectorSize(3) returns 2. + r.getVectorSize(4) returns 3. + + If stored by columns (with no extra space) then: + c.getElements() returns a vector containing: + 3 5.6 1 2 1.1 1 -2 2.8 -1 1 1 -1.2 -1 1.9 + c.getIndices() returns a vector containing: + 0 4 0 1 1 2 0 3 0 4 2 3 0 4 + c.getVectorStarts() returns a vector containing: + 0 2 4 6 8 10 11 12 14 + c.getNumElements() returns 14. + c.getMajorDim() returns 8. + @endverbatim + + Compiling this class with CLP_NO_VECTOR defined will excise all methods + which use CoinPackedVectorBase, CoinPackedVector, or CoinShallowPackedVector + as parameters or return types. + + Compiling this class with COIN_FAST_CODE defined removes index range checks. +*/ +class CoinPackedMatrix { + friend void CoinPackedMatrixUnitTest(); + +public: + + + //--------------------------------------------------------------------------- + /**@name Query members */ + //@{ + /** Return the current setting of the extra gap. */ + inline double getExtraGap() const { return extraGap_; } + /** Return the current setting of the extra major. */ + inline double getExtraMajor() const { return extraMajor_; } + + /** Reserve sufficient space for appending major-ordered vectors. + If create is true, empty columns are created (for column generation) */ + void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize, + bool create=false); + /** Clear the data, but do not free any arrays */ + void clear(); + + /** Whether the packed matrix is column major ordered or not. */ + inline bool isColOrdered() const { return colOrdered_; } + + /** Whether the packed matrix has gaps or not. */ + inline bool hasGaps() const { return (size_<start_[majorDim_]) ; } + + /** Number of entries in the packed matrix. */ + inline CoinBigIndex getNumElements() const { return size_; } + + /** Number of columns. */ + inline int getNumCols() const + { return colOrdered_ ? majorDim_ : minorDim_; } + + /** Number of rows. */ + inline int getNumRows() const + { return colOrdered_ ? minorDim_ : majorDim_; } + + /*! \brief A vector containing the elements in the packed matrix. + + Returns #elements_. Note that there might be gaps in this vector, + entries that do not belong to any major-dimension vector. To get + the actual elements one should look at this vector together with + vectorStarts (#start_) and vectorLengths (#length_). + */ + inline const double * getElements() const { return element_; } + + /*! \brief A vector containing the minor indices of the elements in + the packed matrix. + + Returns #index_. Note that there might be gaps in this list, + entries that do not belong to any major-dimension vector. To get + the actual elements one should look at this vector together with + vectorStarts (#start_) and vectorLengths (#length_). + */ + inline const int * getIndices() const { return index_; } + + /*! \brief The size of the <code>vectorStarts</code> array + + See #start_. + */ + inline int getSizeVectorStarts() const + { return ((majorDim_ > 0)?(majorDim_+1):(0)) ; } + + /*! \brief The size of the <code>vectorLengths</code> array + + See #length_. + */ + inline int getSizeVectorLengths() const { return majorDim_; } + + /*! \brief The positions where the major-dimension vectors start in + elements and indices. + + See #start_. + */ + inline const CoinBigIndex * getVectorStarts() const { return start_; } + + /*! \brief The lengths of the major-dimension vectors. + + See #length_. + */ + inline const int * getVectorLengths() const { return length_; } + + /** The position of the first element in the i'th major-dimension vector. + */ + CoinBigIndex getVectorFirst(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix"); +#endif + return start_[i]; + } + /** The position of the last element (well, one entry <em>past</em> the + last) in the i'th major-dimension vector. */ + CoinBigIndex getVectorLast(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorLast", "CoinPackedMatrix"); +#endif + return start_[i] + length_[i]; + } + /** The length of i'th vector. */ + inline int getVectorSize(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorSize", "CoinPackedMatrix"); +#endif + return length_[i]; + } +#ifndef CLP_NO_VECTOR + /** Return the i'th vector in matrix. */ + const CoinShallowPackedVector getVector(int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vector", "CoinPackedMatrix"); +#endif + return CoinShallowPackedVector(length_[i], + index_ + start_[i], + element_ + start_[i], + false); + } +#endif + /** Returns an array containing major indices. The array is + getNumElements long and if getVectorStarts() is 0,2,5 then + the array would start 0,0,1,1,1,2... + This method is provided to go back from a packed format + to a triple format. It returns NULL if there are gaps in + matrix so user should use removeGaps() if there are any gaps. + It does this as this array has to match getElements() and + getIndices() and because it makes no sense otherwise. + The returned array is allocated with <code>new int[]</code>, + free it with <code>delete[]</code>. */ + int * getMajorIndices() const; + //@} + + //--------------------------------------------------------------------------- + /**@name Modifying members */ + //@{ + /*! \brief Set the dimensions of the matrix. + + The method name is deceptive; the effect is to append empty columns + and/or rows to the matrix to reach the specified dimensions. + A negative number for either dimension means that that dimension + doesn't change. An exception will be thrown if the specified dimensions + are smaller than the current dimensions. + */ + void setDimensions(int numrows, int numcols); + + /** Set the extra gap to be allocated to the specified value. */ + void setExtraGap(const double newGap); + /** Set the extra major to be allocated to the specified value. */ + void setExtraMajor(const double newMajor); +#ifndef CLP_NO_VECTOR + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const CoinPackedVectorBase& vec); +#endif + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of columns to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the column vectors specify a nonexistent row index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendCols(const int numcols, + const CoinPackedVectorBase * const * cols); +#endif + /*! Append a set of columns to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate row index). + No error checking is performed if \p numberRows < 0. + */ + int appendCols(const int numcols, + const CoinBigIndex * columnStarts, const int * row, + const double * element, int numberRows=-1); +#ifndef CLP_NO_VECTOR + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const CoinPackedVectorBase& vec); +#endif + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of rows to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the row vectors specify a nonexistent column index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendRows(const int numrows, + const CoinPackedVectorBase * const * rows); +#endif + /*! Append a set of rows to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate column index). + No error checking is performed if \p numberColumns < 0. + */ + int appendRows(const int numrows, + const CoinBigIndex * rowStarts, const int * column, + const double * element, int numberColumns=-1); + + /** Append the argument to the "right" of the current matrix. Imagine this + as adding new columns (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of rows + is different in the matrices. */ + void rightAppendPackedMatrix(const CoinPackedMatrix& matrix); + /** Append the argument to the "bottom" of the current matrix. Imagine this + as adding new rows (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of columns + is different in the matrices. */ + void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix); + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + void deleteRows(const int numDel, const int * indDel); + + /** Replace the elements of a vector. The indices remain the same. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + void replaceVector(const int index, + const int numReplace, const double * newElements); + /** Modify one element of packed matrix. An element may be added. + This works for either ordering + If the new element is zero it will be deleted unless + keepZero true */ + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false); + /** Return one element of packed matrix. + This works for either ordering + If it is not present will return 0.0 */ + double getCoefficient(int row, int column) const; + + /** Eliminate all elements in matrix whose + absolute value is less than threshold. + The column starts are not affected. Returns number of elements + eliminated. Elements eliminated are at end of each vector + */ + int compress(double threshold); + /** Eliminate all duplicate AND small elements in matrix + The column starts are not affected. Returns number of elements + eliminated. + */ + int eliminateDuplicates(double threshold); + /** Sort all columns so indices are increasing.in each column */ + void orderMatrix(); + /** Really clean up matrix. + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated + */ + int cleanMatrix(double threshold=1.0e-20); + //@} + + //--------------------------------------------------------------------------- + /**@name Methods that reorganize the whole matrix */ + //@{ + /** Remove the gaps from the matrix if there were any + Can also remove small elements fabs() <= removeValue*/ + void removeGaps(double removeValue=-1.0); + + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Does not allow duplicates. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Allows duplicates and keeps order. */ + void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); +#if 0 + /** Extract a submatrix from matrix. Those major/minor-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor, + const int numMinor, const int * indMinor); +#endif + + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. */ + void copyOf(const CoinPackedMatrix& rhs); + /** Copy the arguments to the matrix. If <code>len</code> is a NULL pointer + then the matrix is assumed to have no gaps in it and <code>len</code> + will be created accordingly. */ + void copyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. + If there is room it will re-use arrays */ + void copyReuseArrays(const CoinPackedMatrix& rhs); + + /*! \brief Make a reverse-ordered copy. + + This method makes an exact replica of the argument with the major + vector orientation changed from row (column) to column (row). + The extra space parameters are also copied and reversed. + (Cf. #reverseOrdering, which does the same thing in place.) + */ + void reverseOrderedCopyOf(const CoinPackedMatrix& rhs); + + /** Assign the arguments to the matrix. If <code>len</code> is a NULL + pointer then the matrix is assumed to have no gaps in it and + <code>len</code> will be created accordingly. <br> + <strong>NOTE 1</strong>: After this method returns the pointers + passed to the method will be NULL pointers! <br> + <strong>NOTE 2</strong>: When the matrix is eventually destructed the + arrays will be deleted by <code>delete[]</code>. Hence one should use + this method ONLY if all array swere allocated by <code>new[]</code>! */ + void assignMatrix(const bool colordered, + const int minor, const int major, + const CoinBigIndex numels, + double *& elem, int *& ind, + CoinBigIndex *& start, int *& len, + const int maxmajor = -1, const CoinBigIndex maxsize = -1); + + + + /** Assignment operator. This copies out the data, but uses the current + matrix's extra space parameters. */ + CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs); + + /*! \brief Reverse the ordering of the packed matrix. + + Change the major vector orientation of the matrix data structures from + row (column) to column (row). (Cf. #reverseOrderedCopyOf, which does + the same thing but produces a new matrix.) + */ + void reverseOrdering(); + + /*! \brief Transpose the matrix. + + \note + If you start with a column-ordered matrix and invoke transpose, you + will have a row-ordered transposed matrix. To change the major vector + orientation (e.g., to transform a column-ordered matrix to a + column-ordered transposed matrix), invoke transpose() followed by + #reverseOrdering(). + */ + void transpose(); + + /*! \brief Swap the content of two packed matrices. */ + void swap(CoinPackedMatrix& matrix); + + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods */ + //@{ + /** Return <code>A * x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + void times(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> in <code>y</code>. Same as the previous + method, just <code>x</code> is given in the form of a packed vector. */ + void times(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return <code>x * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + void transposeTimes(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>x * A</code> in <code>y</code>. Same as the previous + method, just <code>x</code> is given in the form of a packed vector. */ + void transposeTimes(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Helper functions used internally, but maybe useful externally. + + These methods do not worry about testing whether the packed matrix is + row or column major ordered; they operate under the assumption that the + correct version is invoked. In fact, a number of other methods simply + just call one of these after testing the ordering of the matrix. */ + //@{ + + //------------------------------------------------------------------------- + /**@name Queries */ + //@{ + /** Count the number of entries in every minor-dimension vector and + return an array containing these lengths. The returned array is + allocated with <code>new int[]</code>, free it with + <code>delete[]</code>. */ + int * countOrthoLength() const; + /** Count the number of entries in every minor-dimension vector and + fill in an array containing these lengths. */ + void countOrthoLength(int * counts) const; + /** Major dimension. For row ordered matrix this would be the number of + rows. */ + inline int getMajorDim() const { return majorDim_; } + /** Set major dimension. For row ordered matrix this would be the number of + rows. Use with great care.*/ + inline void setMajorDim(int value) { majorDim_ = value; } + /** Minor dimension. For row ordered matrix this would be the number of + columns. */ + inline int getMinorDim() const { return minorDim_; } + /** Set minor dimension. For row ordered matrix this would be the number of + columns. Use with great care.*/ + inline void setMinorDim(int value) { minorDim_ = value; } + /** Current maximum for major dimension. For row ordered matrix this many + rows can be added without reallocating the vector related to the + major dimension (<code>start_</code> and <code>length_</code>). */ + inline int getMaxMajorDim() const { return maxMajorDim_; } + + /** Dump the matrix on stdout. When in dire straits this method can + help. */ + void dumpMatrix(const char* fname = NULL) const; + + /// Print a single matrix element. + void printMatrixElement(const int row_val, const int col_val) const; + //@} + + //------------------------------------------------------------------------- + /*! @name Append vectors + + \details + When compiled with COIN_DEBUG defined these methods throw an exception + if the major (minor) vector contains an index that's invalid for the + minor (major) dimension. Otherwise the methods assume that every index + fits into the matrix. + */ + //@{ +#ifndef CLP_NO_VECTOR + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several major-dimensonvectors to the end of the matrix */ + void appendMajorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); + + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several minor-dimension vectors to the end of the matrix */ + void appendMinorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); +#endif + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + This case is when we know there are no gaps and majorDim_ will not + change. + + \todo + This method really belongs in the group of protected methods with + #appendMinor; there are no safeties here even with COIN_DEBUG. + Apparently this method was needed in ClpPackedMatrix and giving it + proper visibility was too much trouble. Should be moved. + */ + void appendMinorFast(const int number, + const CoinBigIndex * starts, const int * index, + const double * element); + //@} + + //------------------------------------------------------------------------- + /*! \name Append matrices + + \details + We'll document these methods assuming that the current matrix is + column major ordered (Hence in the <code>...SameOrdered()</code> + methods the argument is column ordered, in the + <code>OrthoOrdered()</code> methods the argument is row ordered.) + */ + //@{ + /** Append the columns of the argument to the right end of this matrix. + @pre <code>minorDim_ == matrix.minorDim_</code> <br> + This method throws an exception if the minor dimensions are not the + same. */ + void majorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the columns of the argument to the bottom end of this matrix. + @pre <code>majorDim_ == matrix.majorDim_</code> <br> + This method throws an exception if the major dimensions are not the + same. */ + void minorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the right end of this matrix. + @pre <code>minorDim_ == matrix.majorDim_</code> <br> + This method throws an exception if the minor dimension of the + current matrix is not the same as the major dimension of the + argument matrix. */ + void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the bottom end of this matrix. + @pre <code>majorDim_ == matrix.minorDim_</code> <br> + This method throws an exception if the major dimension of the + current matrix is not the same as the minor dimension of the + argument matrix. */ + void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + //@} + + //----------------------------------------------------------------------- + /**@name Delete vectors */ + //@{ + /** Delete the major-dimension vectors whose indices are listed in + <code>indDel</code>. */ + void deleteMajorVectors(const int numDel, const int * indDel); + /** Delete the minor-dimension vectors whose indices are listed in + <code>indDel</code>. */ + void deleteMinorVectors(const int numDel, const int * indDel); + //@} + + //----------------------------------------------------------------------- + /**@name Various dot products. */ + //@{ + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. + @pre <code>x</code> must be of size <code>majorDim()</code> + @pre <code>y</code> must be of size <code>minorDim()</code> */ + void timesMajor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. Same as the previous method, just <code>x</code> is + given in the form of a packed vector. */ + void timesMajor(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. + @pre <code>x</code> must be of size <code>minorDim()</code> + @pre <code>y</code> must be of size <code>majorDim()</code> */ + void timesMinor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. Same as the previous method, just <code>x</code> is + given in the form of a packed vector. */ + void timesMinor(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + //@} + + //-------------------------------------------------------------------------- + /**@name Logical Operations. */ + //@{ +#ifndef CLP_NO_VECTOR + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + The operator used to test for equality can be specified using the + \p FloatEqual template parameter. + */ + template <class FloatEqual> bool + isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const + { + // Both must be column order or both row ordered and must be of same size + if ((isColOrdered() ^ rhs.isColOrdered()) || + (getNumCols() != rhs.getNumCols()) || + (getNumRows() != rhs.getNumRows()) || + (getNumElements() != rhs.getNumElements())) + return false; + + for (int i=getMajorDim()-1; i >= 0; --i) { + CoinShallowPackedVector pv = getVector(i); + CoinShallowPackedVector rhsPv = rhs.getVector(i); + if ( !pv.isEquivalent(rhsPv,eq) ) + return false; + } + return true; + } + + /*! \brief Test for equivalence and report differences + + Equivalence is defined as for #isEquivalent. In addition, this method will + print differences to std::cerr. Intended for use in unit tests and + for debugging. + */ + bool isEquivalent2(const CoinPackedMatrix& rhs) const; +#else + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + This method is optimised for speed. CoinPackedVector#isEquivalent is + replaced with more efficient code for repeated comparison of + equal-length vectors. The CoinRelFltEq operator is used. + */ + bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const; +#endif + /*! \brief Test for equivalence. + + The test for element equality is the default CoinRelFltEq operator. + */ + bool isEquivalent(const CoinPackedMatrix& rhs) const; + //@} + + //-------------------------------------------------------------------------- + /*! \name Non-const methods + + These are to be used with great care when doing column generation, etc. + */ + //@{ + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with #start_ and #length_. */ + inline double * getMutableElements() const { return element_; } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with #start_ and + #length_. */ + inline int * getMutableIndices() const { return index_; } + + /** The positions where the major-dimension vectors start in #element_ and + #index_. */ + inline CoinBigIndex * getMutableVectorStarts() const { return start_; } + /** The lengths of the major-dimension vectors. */ + inline int * getMutableVectorLengths() const { return length_; } + /// Change the size of the bulk store after modifying - be careful + inline void setNumElements(CoinBigIndex value) + { size_ = value;} + /*! NULLify element array + + Used when space is very tight. Does not free the space! + */ + inline void nullElementArray() {element_=NULL;} + + /*! NULLify start array + + Used when space is very tight. Does not free the space! + */ + inline void nullStartArray() {start_=NULL;} + + /*! NULLify length array + + Used when space is very tight. Does not free the space! + */ + inline void nullLengthArray() {length_=NULL;} + + /*! NULLify index array + + Used when space is very tight. Does not free the space! + */ + inline void nullIndexArray() {index_=NULL;} + //@} + + //-------------------------------------------------------------------------- + /*! \name Constructors and destructors */ + //@{ + /// Default Constructor creates an empty column ordered packed matrix + CoinPackedMatrix(); + + /// A constructor where the ordering and the gaps are specified + CoinPackedMatrix(const bool colordered, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + + /** Create packed matrix from triples. + If colordered is true then the created matrix will be column ordered. + Duplicate matrix elements are allowed. The created matrix will have + the sum of the duplicates. <br> + For example if: <br> + rowIndices[0]=2; colIndices[0]=5; elements[0]=2.0 <br> + rowIndices[1]=2; colIndices[1]=5; elements[1]=0.5 <br> + then the created matrix will contain a value of 2.5 in row 2 and column 5.<br> + The matrix is created without gaps. + */ + CoinPackedMatrix(const bool colordered, + const int * rowIndices, + const int * colIndices, + const double * elements, + CoinBigIndex numels ); + + /// Copy constructor + CoinPackedMatrix(const CoinPackedMatrix& m); + + /*! \brief Copy constructor with fine tuning + + This constructor allows for the specification of an exact amount of extra + space and/or reverse ordering. + + \p extraForMajor is the exact number of spare major vector slots after + any possible reverse ordering. If \p extraForMajor < 0, all gaps and small + elements will be removed from the copy, otherwise gaps and small elements + are preserved. + + \p extraElements is the exact number of spare element entries. + + The usual multipliers, #extraMajor_ and #extraGap_, are set to zero. + */ + CoinPackedMatrix(const CoinPackedMatrix &m, + int extraForMajor, int extraElements, + bool reverseOrdering = false) ; + + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + CoinPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /// Destructor + virtual ~CoinPackedMatrix(); + //@} + + /*! \name Debug Utilities */ + //@{ + /*! \brief Scan the matrix for anomalies. + + Returns the number of anomalies. Scans the structure for gaps, + obviously bogus indices and coefficients, and inconsistencies. Gaps + are not an error unless #hasGaps() says the matrix should be + gap-free. Zeroes are not an error unless \p zeroesAreError is set to + true. + + Values for verbosity are: + - 0: No messages, just the return value + - 1: Messages about errors + - 2: If there are no errors, a message indicating the matrix was + checked is printed (positive confirmation). + - 3: Adds a bit more information about the matrix. + - 4: Prints warnings about zeroes even if they're not considered + errors. + + Obviously bogus coefficients are coefficients that are NaN or have + absolute value greater than 1e50. Zeros have absolute value less + than 1e-50. + */ + int verifyMtx(int verbosity = 1, bool zeroesAreError = false) const ; + //@} + + //-------------------------------------------------------------------------- +protected: + void gutsOfDestructor(); + void gutsOfCopyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /// When no gaps we can do faster + void gutsOfCopyOfNoGaps(const bool colordered, + const int minor, const int major, + const double * elem, const int * ind, + const CoinBigIndex * start); + void gutsOfOpEqual(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + void resizeForAddingMajorVectors(const int numVec, const int * lengthVec); + void resizeForAddingMinorVectors(const int * addedEntries); + + /*! \brief Append a set of rows (columns) to the end of a row (colum) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or invalid indices and return the + number of errors. A valid minor index must satisfy + \code 0 <= k < numberOther \endcode + If \p numberOther < 0 no checking is performed. + */ + int appendMajor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or indices outside the current + range for the major dimension and return the number of violations. + If \p numberOther <= 0 the major dimension will be expanded as + necessary and there are no checks for duplicate indices. + */ + int appendMinor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + +private: + inline CoinBigIndex getLastStart() const { + return majorDim_ == 0 ? 0 : start_[majorDim_]; + } + + //-------------------------------------------------------------------------- +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** A flag indicating whether the matrix is column or row major ordered. */ + bool colOrdered_; + /** This much times more space should be allocated for each major-dimension + vector (with respect to the number of entries in the vector) when the + matrix is resized. The purpose of these gaps is to allow fast insertion + of new minor-dimension vectors. */ + double extraGap_; + /** his much times more space should be allocated for major-dimension + vectors when the matrix is resized. The purpose of these gaps is to + allow fast addition of new major-dimension vectors. */ + double extraMajor_; + + /** List of nonzero element values. The entries in the gaps between + major-dimension vectors are undefined. */ + double *element_; + /** List of nonzero element minor-dimension indices. The entries in the gaps + between major-dimension vectors are undefined. */ + int *index_; + /** Starting positions of major-dimension vectors. */ + CoinBigIndex *start_; + /** Lengths of major-dimension vectors. */ + int *length_; + + /// number of vectors in matrix + int majorDim_; + /// size of other dimension + int minorDim_; + /// the number of nonzero entries + CoinBigIndex size_; + + /// max space allocated for major-dimension + int maxMajorDim_; + /// max space allocated for entries + CoinBigIndex maxSize_; + //@} +}; + +//############################################################################# +/*! \brief Test the methods in the CoinPackedMatrix class. + + The only reason for it not to be a member method is that this way + it doesn't have to be compiled into the library. And that's a gain, + because the library should be compiled with optimization on, but this + method should be compiled with debugging. +*/ +void +CoinPackedMatrixUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPackedVector.hpp b/thirdparty/linux/include/coin/coin/CoinPackedVector.hpp new file mode 100644 index 0000000..9ea1feb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPackedVector.hpp @@ -0,0 +1,657 @@ +/* $Id: CoinPackedVector.hpp 1509 2011-12-05 13:50:48Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVector_H +#define CoinPackedVector_H + +#include <map> + +#include "CoinPragma.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinSort.hpp" + +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif +/** Sparse Vector + +Stores vector of indices and associated element values. +Supports sorting of vector while maintaining the original indices. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==0 ); + assert( r.originalPosition()[1]==1 ); + assert( r.originalPosition()[2]==2 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.indices ()[0]== 0 ); + assert( r.elements()[0]== 1. ); + assert( r.indices ()[1]== 1 ); + assert( r.elements()[1]==10. ); + assert( r.indices ()[2]== 4 ); + assert( r.elements()[2]==40. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==2 ); + assert( r.originalPosition()[1]==0 ); + assert( r.originalPosition()[2]==1 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Restore orignal sort order + r.sortOriginalOrder(); + + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // Tests for equality and equivalence + CoinPackedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinPackedVector : public CoinPackedVectorBase { + friend void CoinPackedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + /// Get indices of elements + int * getIndices() { return indices_; } + /// Get the size + inline int getVectorNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getVectorIndices() const { return indices_; } + /// Get element values + inline const double * getVectorElements() const { return elements_; } + /// Get element values + double * getElements() { return elements_; } + /** Get pointer to int * vector of original postions. + If the packed vector has not been sorted then this + function returns the vector: 0, 1, 2, ..., size()-1. */ + const int * getOriginalPosition() const { return origIndices_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator. <br> + <strong>NOTE</strong>: This operator keeps the current + <code>testForDuplicateIndex</code> setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVector &); + /** Assignment operator from a CoinPackedVectorBase. <br> + <strong>NOTE</strong>: This operator keeps the current + <code>testForDuplicateIndex</code> setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVectorBase & rhs); + + /** Assign the ownership of the arguments to this vector. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument indicates whether this vector will have + to be tested for duplicate indices. + */ + void assignVector(int size, int*& inds, double*& elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set vector size, indices, and elements. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument specifies whether this vector will have + to be checked for duplicate indices whenever that can happen. */ + void setVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1, + but only where non zero*/ + void setFullNonZero(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set an existing element in the packed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /** Resize the packed vector to be the first newSize elements. + Problem with truncate: what happens with origIndices_ ??? */ + void truncate(int newSize); + //@} + + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(double value); + /// subtract <code>value</code> from every entry + void operator-=(double value); + /// multiply every entry by <code>value</code> + void operator*=(double value); + /// divide every entry by <code>value</code> + void operator/=(double value); + //@} + + /**@name Sorting */ + //@{ + /** Sort the packed storage vector. + Typcical usages: + <pre> + packedVector.sort(CoinIncrIndexOrdered()); //increasing indices + packedVector.sort(CoinIncrElementOrdered()); // increasing elements + </pre> + */ + template <class CoinCompare3> + void sort(const CoinCompare3 & tc) + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + tc); } + + void sortIncrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstLess_3<int, int, double>()); } + + void sortDecrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstGreater_3<int, int, double>()); } + + void sortIncrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstLess_3<double, int, int>()); } + + void sortDecrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstGreater_3<double, int, int>()); } + + + /** Sort in original order. + If the vector has been sorted, then this method restores + to its orignal sort order. + */ + void sortOriginalOrder(); + //@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the packed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + int capacity() const { return capacity_; } + //@} + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor copies the vectors provided as parameters. + */ + CoinPackedVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor takes ownership of the vectors passed as parameters. + \p inds and \p elems will be NULL on return. + */ + CoinPackedVector(int capacity, int size, int *&inds, double *&elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - set elements to same scalar value */ + CoinPackedVector(int size, const int * inds, double element, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinPackedVector(int size, const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Copy constructor. */ + CoinPackedVector(const CoinPackedVector &); + /** Copy constructor <em>from a PackedVectorBase</em>. */ + CoinPackedVector(const CoinPackedVectorBase & rhs); + /** Destructor */ + virtual ~CoinPackedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal date + void gutsOfSetVector(int size, + const int * inds, const double * elems, + bool testForDuplicateIndex, + const char * method); + /// + void gutsOfSetConstant(int size, + const int * inds, double value, + bool testForDuplicateIndex, + const char * method); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and elements vectors + int nElements_; + /// original unsorted indices + int * origIndices_; + /// Amount of memory allocated for indices_, origIndices_, and elements_. + int capacity_; + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on packed vectors. + + <strong>NOTE</strong>: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.<br> + <strong>NOTE 2</strong>: There are two kind of operators here. One is used + like "c = binaryOp(a, b)", the other is used like "binaryOp(c, a, b)", but + they are really the same. The first is much more natural to use, but it + involves the creation of a temporary object (the function *must* return an + object), while the second form puts the result directly into the argument + "c". Therefore, depending on the circumstances, the second form can be + significantly faster. + */ +//@{ +template <class BinaryFunction> void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + retVal.clear(); + const int s = op1.getNumElements(); + if (s > 0) { + retVal.reserve(s); + const int * inds = op1.getIndices(); + const double * elems = op1.getElements(); + for (int i=0; i<s; ++i ) { + retVal.insert(inds[i], bf(value, elems[i])); + } + } +} + +template <class BinaryFunction> inline void +binaryOp(CoinPackedVector& retVal, + double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + binaryOp(retVal, op2, value, bf); +} + +template <class BinaryFunction> void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + retVal.clear(); + const int s1 = op1.getNumElements(); + const int s2 = op2.getNumElements(); +/* + Replaced || with &&, in response to complaint from Sven deVries, who + rightly points out || is not appropriate for additive operations. && + should be ok as long as binaryOp is understood not to create something + from nothing. -- lh, 04.06.11 +*/ + if (s1 == 0 && s2 == 0) + return; + + retVal.reserve(s1+s2); + + const int * inds1 = op1.getIndices(); + const double * elems1 = op1.getElements(); + const int * inds2 = op2.getIndices(); + const double * elems2 = op2.getElements(); + + int i; + // loop once for each element in op1 + for ( i=0; i<s1; ++i ) { + const int index = inds1[i]; + const int pos2 = op2.findIndex(index); + const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]); + // if (val != 0.0) // *THINK* : should we put in only nonzeros? + retVal.insert(index, val); + } + // loop once for each element in operand2 + for ( i=0; i<s2; ++i ) { + const int index = inds2[i]; + // if index exists in op1, then element was processed in prior loop + if ( op1.isExistingIndex(index) ) + continue; + // Index does not exist in op1, so the element value must be zero + const double val = bf(0.0, elems2[i]); + // if (val != 0.0) // *THINK* : should we put in only nonzeros? + retVal.insert(index, val); + } +} + +//----------------------------------------------------------------------------- + +template <class BinaryFunction> CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, value, bf); + return retVal; +} + +template <class BinaryFunction> CoinPackedVector +binaryOp(double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op2, value, bf); + return retVal; +} + +template <class BinaryFunction> CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, bf); + return retVal; +} + +//----------------------------------------------------------------------------- +/// Return the sum of two packed vectors +inline CoinPackedVector operator+(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::plus<double>()); + return retVal; +} + +/// Return the difference of two packed vectors +inline CoinPackedVector operator-(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::minus<double>()); + return retVal; +} + +/// Return the element-wise product of two packed vectors +inline CoinPackedVector operator*(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::multiplies<double>()); + return retVal; +} + +/// Return the element-wise ratio of two packed vectors +inline CoinPackedVector operator/(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::divides<double>()); + return retVal; +} +//@} + +/// Returns the dot product of two CoinPackedVector objects whose elements are +/// doubles. Use this version if the vectors are *not* guaranteed to be sorted. +inline double sparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int len, i; + double acc = 0.0; + CoinPackedVector retVal; + + CoinPackedVector retval = op1*op2; + len = retval.getNumElements(); + double * CParray = retval.getElements(); + + for(i = 0; i < len; i++){ + acc += CParray[i]; + } +return acc; +} + + +/// Returns the dot product of two sorted CoinPackedVector objects. +/// The vectors should be sorted in ascending order of indices. +inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int i, j, len1, len2; + double acc = 0.0; + + const double* v1val = op1.getElements(); + const double* v2val = op2.getElements(); + const int* v1ind = op1.getIndices(); + const int* v2ind = op2.getIndices(); + + len1 = op1.getNumElements(); + len2 = op2.getNumElements(); + + i = 0; + j = 0; + + while(i < len1 && j < len2){ + if(v1ind[i] == v2ind[j]){ + acc += v1val[i] * v2val[j]; + i++; + j++; + } + else if(v2ind[j] < v1ind[i]){ + j++; + } + else{ + i++; + } // end if-else-elseif + } // end while + return acc; + } + + +//----------------------------------------------------------------------------- + +/**@name Arithmetic operators on packed vector and a constant. <br> + These functions create a packed vector as a result. That packed vector will + have the same indices as <code>op1</code> and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a packed vector and a constant +inline CoinPackedVector +operator+(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a packed vector and a constant +inline CoinPackedVector +operator-(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal -= value; + return retVal; +} + +/// Return the element-wise product of a packed vector and a constant +inline CoinPackedVector +operator*(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a packed vector and a constant +inline CoinPackedVector +operator/(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal /= value; + return retVal; +} + +//----------------------------------------------------------------------------- + +/// Return the sum of a constant and a packed vector +inline CoinPackedVector +operator+(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a constant and a packed vector +inline CoinPackedVector +operator-(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value - elems[i]; + } + return retVal; +} + +/// Return the element-wise product of a constant and a packed vector +inline CoinPackedVector +operator*(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a a constant and packed vector +inline CoinPackedVector +operator/(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value / elems[i]; + } + return retVal; +} +//@} + +//############################################################################# +/** A function that tests the methods in the CoinPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPackedVectorBase.hpp b/thirdparty/linux/include/coin/coin/CoinPackedVectorBase.hpp new file mode 100644 index 0000000..dccc1cd --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPackedVectorBase.hpp @@ -0,0 +1,269 @@ +/* $Id: CoinPackedVectorBase.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVectorBase_H +#define CoinPackedVectorBase_H + +#include <set> +#include <map> +#include "CoinPragma.hpp" +#include "CoinError.hpp" + +class CoinPackedVector; + +/** Abstract base class for various sparse vectors. + + Since this class is abstract, no object of this type can be created. The + sole purpose of this class is to provide access to a <em>constant</em> + packed vector. All members of this class are const methods, they can't + change the object. */ + +class CoinPackedVectorBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const = 0; + /// Get indices of elements + virtual const int * getIndices() const = 0; + /// Get element values + virtual const double * getElements() const = 0; + //@} + + /**@name Methods related to whether duplicate-index checking is performed. + + If the checking for duplicate indices is turned off, then + some CoinPackedVector methods may not work correctly if there + are duplicate indices. + Turning off the checking for duplicate indices may result in + better run time performance. + */ + //@{ + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur. + + Calling this method with \p test set to true will trigger an immediate + check for duplicate indices. + */ + void setTestForDuplicateIndex(bool test) const; + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur BUT we know that right + now the vector has no duplicate indices. + + Calling this method with \p test set to true will <em>not</em> trigger + an immediate check for duplicate indices; instead, it's assumed that + the result of the test will be true. + */ + void setTestForDuplicateIndexWhenTrue(bool test) const; + /** Returns true if the vector should be tested for duplicate indices when + they can occur. */ + bool testForDuplicateIndex() const { return testForDuplicateIndex_; } + /// Just sets test stuff false without a try etc + inline void setTestsOff() const + { testForDuplicateIndex_=false; testedDuplicateIndex_=false;} + //@} + + /**@name Methods for getting info on the packed vector as a full vector */ + //@{ + /** Get the vector as a dense vector. The argument specifies how long this + dense vector is. <br> + <strong>NOTE</strong>: The user needs to <code>delete[]</code> this + pointer after it's not needed anymore. + */ + double * denseVector(int denseSize) const; + /** Access the i'th element of the full storage vector. + If the i'th is not stored, then zero is returned. The initial use of + this method has some computational and storage overhead associated with + it.<br> + <strong>NOTE</strong>: This is <em>very</em> expensive. It is probably + much better to use <code>denseVector()</code>. + */ + double operator[](int i) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + + /// Throw an exception if there are duplicate indices + void duplicateIndex(const char* methodName = NULL, + const char * className = NULL) const; + + /** Return true if the i'th element of the full storage vector exists in + the packed storage vector.*/ + bool isExistingIndex(int i) const; + + /** Return the position of the i'th element of the full storage vector. + If index does not exist then -1 is returned */ + int findIndex(int i) const; + + //@} + + /**@name Comparison operators on two packed vectors */ + //@{ + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; + +#if 0 + // LL: This should be implemented eventually. It is useful to have. + /** Lexicographic comparisons of two packed vectors. Returns + negative/0/positive depending on whether \c this is + smaller/equal.greater than \c rhs */ + int lexCompare(const CoinPackedVectorBase& rhs); +#endif + + /** This method establishes an ordering on packed vectors. It is complete + ordering, but not the same as lexicographic ordering. However, it is + quick and dirty to compute and thus it is useful to keep packed vectors + in a heap when all we care is to quickly check whether a particular + vector is already in the heap or not. Returns negative/0/positive + depending on whether \c this is smaller/equal.greater than \c rhs. */ + int compare(const CoinPackedVectorBase& rhs) const; + + /** equivalent - If shallow packed vector A & B are equivalent, then they + are still equivalent no matter how they are sorted. + In this method the FloatEqual function operator can be specified. The + default equivalence test is that the entries are relatively equal.<br> + <strong>NOTE</strong>: This is a relatively expensive method as it + sorts the two shallow packed vectors. + */ + template <class FloatEqual> bool + isEquivalent(const CoinPackedVectorBase& rhs, const FloatEqual& eq) const + { + if (getNumElements() != rhs.getNumElements()) + return false; + + duplicateIndex("equivalent", "CoinPackedVector"); + rhs.duplicateIndex("equivalent", "CoinPackedVector"); + + std::map<int,double> mv; + const int * inds = getIndices(); + const double * elems = getElements(); + int i; + for ( i = getNumElements() - 1; i >= 0; --i) { + mv.insert(std::make_pair(inds[i], elems[i])); + } + + std::map<int,double> mvRhs; + inds = rhs.getIndices(); + elems = rhs.getElements(); + for ( i = getNumElements() - 1; i >= 0; --i) { + mvRhs.insert(std::make_pair(inds[i], elems[i])); + } + + std::map<int,double>::const_iterator mvI = mv.begin(); + std::map<int,double>::const_iterator mvIlast = mv.end(); + std::map<int,double>::const_iterator mvIrhs = mvRhs.begin(); + while (mvI != mvIlast) { + if (mvI->first != mvIrhs->first || ! eq(mvI->second, mvIrhs->second)) + return false; + ++mvI; + ++mvIrhs; + } + return true; + } + + bool isEquivalent(const CoinPackedVectorBase& rhs) const; + //@} + + + /**@name Arithmetic operators. */ + //@{ + /// Create the dot product with a full vector + double dotProduct(const double* dense) const; + + /// Return the 1-norm of the vector + double oneNorm() const; + + /// Return the square of the 2-norm of the vector + double normSquare() const; + + /// Return the 2-norm of the vector + double twoNorm() const; + + /// Return the infinity-norm of the vector + double infNorm() const; + + /// Sum elements of vector. + double sum() const; + //@} + +protected: + + /**@name Constructors, destructor + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + CoinPackedVectorBase(); + +public: + /** Destructor */ + virtual ~CoinPackedVectorBase(); + //@} + +private: + /**@name Disabled methods */ + //@{ + /** The copy constructor. <br> + This must be at least protected, but we make it private. The reason is + that when, say, a shallow packed vector is created, first the + underlying class, it this one is constructed. However, at that point we + don't know how much of the data members of this class we need to copy + over. Therefore the copy constructor is not used. */ + CoinPackedVectorBase(const CoinPackedVectorBase&); + /** This class provides <em>const</em> access to packed vectors, so there's + no need to provide an assignment operator. */ + CoinPackedVectorBase& operator=(const CoinPackedVectorBase&); + //@} + +protected: + + /**@name Protected methods */ + //@{ + /// Find Maximum and Minimum Indices + void findMaxMinIndices() const; + + /// Return indexSetPtr_ (create it if necessary). + std::set<int> * indexSet(const char* methodName = NULL, + const char * className = NULL) const; + + /// Delete the indexSet + void clearIndexSet() const; + void clearBase() const; + void copyMaxMinIndex(const CoinPackedVectorBase & x) const { + maxIndex_ = x.maxIndex_; + minIndex_ = x.minIndex_; + } + //@} + +private: + /**@name Protected member data */ + //@{ + /// Contains max index value or -infinity + mutable int maxIndex_; + /// Contains minimum index value or infinity + mutable int minIndex_; + /** Store the indices in a set. This set is only created if it is needed. + Its primary use is testing for duplicate indices. + */ + mutable std::set<int> * indexSetPtr_; + /** True if the vector should be tested for duplicate indices when they can + occur. */ + mutable bool testForDuplicateIndex_; + /** True if the vector has already been tested for duplicate indices. Most + of the operations in CoinPackedVector preserves this flag. */ + mutable bool testedDuplicateIndex_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinParam.hpp b/thirdparty/linux/include/coin/coin/CoinParam.hpp new file mode 100644 index 0000000..30cccc2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinParam.hpp @@ -0,0 +1,644 @@ +/* $Id: CoinParam.hpp 1493 2011-11-01 16:56:07Z tkr $ */ +#ifndef CoinParam_H +#define CoinParam_H + +/* + Copyright (C) 2002, International Business Machines + Corporation and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinParam.hpp + \brief Declaration of a class for command line parameters. +*/ + +#include <vector> +#include <string> +#include <cstdio> + +/*! \class CoinParam + \brief A base class for `keyword value' command line parameters. + + The underlying paradigm is that a parameter specifies an action to be + performed on a target object. The base class provides two function + pointers, a `push' function and a `pull' function. By convention, a push + function will set some value in the target object or perform some action + using the target object. A `pull' function will retrieve some value from + the target object. This is only a convention, however; CoinParam and + associated utilities make no use of these functions and have no hardcoded + notion of how they should be used. + + The action to be performed, and the target object, will be specific to a + particular application. It is expected that users will derive + application-specific parameter classes from this base class. A derived + class will typically add fields and methods to set/get a code for the + action to be performed (often, an enum class) and the target object (often, + a pointer or reference). + + Facilities provided by the base class and associated utility routines + include: + <ul> + <li> Support for common parameter types with numeric, string, or + keyword values. + <li> Support for short and long help messages. + <li> Pointers to `push' and `pull' functions as described above. + <li> Command line parsing and keyword matching. + </ul> + All utility routines are declared in the #CoinParamUtils namespace. + + The base class recognises five types of parameters: actions (which require + no value); numeric parameters with integer or real (double) values; keyword + parameters, where the value is one of a defined set of value-keywords; + and string parameters (where the value is a string). + The base class supports the definition of a valid range, a default value, + and short and long help messages for a parameter. + + As defined by the #CoinParamFunc typedef, push and pull functions + should take a single parameter, a pointer to a CoinParam. Typically this + object will actually be a derived class as described above, and the + implementation function will have access to all capabilities of CoinParam and + of the derived class. + + When specified as command line parameters, the expected syntax is `-keyword + value' or `-keyword=value'. You can also use the Gnu double-dash style, + `--keyword'. Spaces around the `=' will \e not work. + + The keyword (name) for a parameter can be defined with an `!' to mark the + minimal match point. For example, allow!ableGap will be considered matched + by the strings `allow', `allowa', `allowab', \e etc. Similarly, the + value-keyword strings for keyword parameters can be defined with `!' to + mark the minimal match point. Matching of keywords and value-keywords is + \e not case sensitive. +*/ + +class CoinParam +{ + +public: + +/*! \name Subtypes */ +//@{ + + /*! \brief Enumeration for the types of parameters supported by CoinParam + + CoinParam provides support for several types of parameters: + <ul> + <li> Action parameters, which require no value. + <li> Integer and double numeric parameters, with upper and lower bounds. + <li> String parameters that take an arbitrary string value. + <li> Keyword parameters that take a defined set of string (value-keyword) + values. Value-keywords are associated with integers in the order in + which they are added, starting from zero. + </ul> + */ + typedef enum { coinParamInvalid = 0, + coinParamAct, coinParamInt, coinParamDbl, + coinParamStr, coinParamKwd } CoinParamType ; + + /*! \brief Type declaration for push and pull functions. + + By convention, a return code of 0 indicates execution without error, >0 + indicates nonfatal error, and <0 indicates fatal error. This is only + convention, however; the base class makes no use of the push and pull + functions and has no hardcoded interpretation of the return code. + */ + typedef int (*CoinParamFunc)(CoinParam *param) ; + +//@} + +/*! \name Constructors and Destructors + + Be careful how you specify parameters for the constructors! Some compilers + are entirely too willing to convert almost anything to bool. +*/ +//@{ + + /*! \brief Default constructor */ + + CoinParam() ; + + /*! \brief Constructor for a parameter with a double value + + The default value is 0.0. Be careful to clearly indicate that \p lower and + \p upper are real (double) values to distinguish this constructor from the + constructor for an integer parameter. + */ + CoinParam(std::string name, std::string help, + double lower, double upper, double dflt = 0.0, + bool display = true) ; + + /*! \brief Constructor for a parameter with an integer value + + The default value is 0. + */ + CoinParam(std::string name, std::string help, + int lower, int upper, int dflt = 0, + bool display = true) ; + + /*! \brief Constructor for a parameter with keyword values + + The string supplied as \p firstValue becomes the first value-keyword. + Additional value-keywords can be added using appendKwd(). It's necessary + to specify both the first value-keyword (\p firstValue) and the default + value-keyword index (\p dflt) in order to distinguish this constructor + from the constructors for string and action parameters. + + Value-keywords are associated with an integer, starting with zero and + increasing as each keyword is added. The value-keyword given as \p + firstValue will be associated with the integer zero. The integer supplied + for \p dflt can be any value, as long as it will be valid once all + value-keywords have been added. + */ + CoinParam(std::string name, std::string help, + std::string firstValue, int dflt, bool display = true) ; + + /*! \brief Constructor for a string parameter + + For some compilers, the default value (\p dflt) must be specified + explicitly with type std::string to distinguish the constructor for a + string parameter from the constructor for an action parameter. For + example, use std::string("default") instead of simply "default", or use a + variable of type std::string. + */ + CoinParam(std::string name, std::string help, + std::string dflt, bool display = true) ; + + /*! \brief Constructor for an action parameter */ + + CoinParam(std::string name, std::string help, + bool display = true) ; + + /*! \brief Copy constructor */ + + CoinParam(const CoinParam &orig) ; + + /*! \brief Clone */ + + virtual CoinParam *clone() ; + + /*! \brief Assignment */ + + CoinParam &operator=(const CoinParam &rhs) ; + + /*! \brief Destructor */ + + virtual ~CoinParam() ; + +//@} + +/*! \name Methods to query and manipulate the value(s) of a parameter */ +//@{ + + /*! \brief Add an additional value-keyword to a keyword parameter */ + + void appendKwd(std::string kwd) ; + + /*! \brief Return the integer associated with the specified value-keyword + + Returns -1 if no value-keywords match the specified string. + */ + int kwdIndex(std::string kwd) const ; + + /*! \brief Return the value-keyword that is the current value of the + keyword parameter + */ + std::string kwdVal() const ; + + /*! \brief Set the value of the keyword parameter using the integer + associated with a value-keyword. + + If \p printIt is true, the corresponding value-keyword string will be + echoed to std::cout. + */ + void setKwdVal(int value, bool printIt = false) ; + + /*! \brief Set the value of the keyword parameter using a value-keyword + string. + + The given string will be tested against the set of value-keywords for + the parameter using the shortest match rules. + */ + void setKwdVal(const std::string value ) ; + + /*! \brief Prints the set of value-keywords defined for this keyword + parameter + */ + void printKwds() const ; + + + /*! \brief Set the value of a string parameter */ + + void setStrVal(std::string value) ; + + /*! \brief Get the value of a string parameter */ + + std::string strVal() const ; + + + /*! \brief Set the value of a double parameter */ + + void setDblVal(double value) ; + + /*! \brief Get the value of a double parameter */ + + double dblVal() const ; + + + /*! \brief Set the value of a integer parameter */ + + void setIntVal(int value) ; + + /*! \brief Get the value of a integer parameter */ + + int intVal() const ; + + + /*! \brief Add a short help string to a parameter */ + + inline void setShortHelp(const std::string help) { shortHelp_ = help ; } + + /*! \brief Retrieve the short help string */ + + inline std::string shortHelp() const { return (shortHelp_) ; } + + /*! \brief Add a long help message to a parameter + + See printLongHelp() for a description of how messages are broken into + lines. + */ + inline void setLongHelp(const std::string help) { longHelp_ = help ; } + + /*! \brief Retrieve the long help message */ + + inline std::string longHelp() const { return (longHelp_) ; } + + /*! \brief Print long help + + Prints the long help string, plus the valid range and/or keywords if + appropriate. The routine makes a best effort to break the message into + lines appropriate for an 80-character line. Explicit line breaks in the + message will be observed. The short help string will be used if + long help is not available. + */ + void printLongHelp() const ; + +//@} + +/*! \name Methods to query and manipulate a parameter object */ +//@{ + + /*! \brief Return the type of the parameter */ + + inline CoinParamType type() const { return (type_) ; } + + /*! \brief Set the type of the parameter */ + + inline void setType(CoinParamType type) { type_ = type ; } + + /*! \brief Return the parameter keyword (name) string */ + + inline std::string name() const { return (name_) ; } + + /*! \brief Set the parameter keyword (name) string */ + + inline void setName(std::string name) { name_ = name ; processName() ; } + + /*! \brief Check if the specified string matches the parameter keyword (name) + string + + Returns 1 if the string matches and meets the minimum match length, + 2 if the string matches but doesn't meet the minimum match length, + and 0 if the string doesn't match. Matches are \e not case-sensitive. + */ + int matches (std::string input) const ; + + /*! \brief Return the parameter keyword (name) string formatted to show + the minimum match length + + For example, if the parameter name was defined as allow!ableGap, the + string returned by matchName would be allow(ableGap). + */ + std::string matchName() const ; + + /*! \brief Set visibility of parameter + + Intended to control whether the parameter is shown when a list of + parameters is processed. Used by CoinParamUtils::printHelp when printing + help messages for a list of parameters. + */ + inline void setDisplay(bool display) { display_ = display ; } + + /*! \brief Get visibility of parameter */ + + inline bool display() const { return (display_) ; } + + /*! \brief Get push function */ + + inline CoinParamFunc pushFunc() { return (pushFunc_) ; } + + /*! \brief Set push function */ + + inline void setPushFunc(CoinParamFunc func) { pushFunc_ = func ; } + + /*! \brief Get pull function */ + + inline CoinParamFunc pullFunc() { return (pullFunc_) ; } + + /*! \brief Set pull function */ + + inline void setPullFunc(CoinParamFunc func) { pullFunc_ = func ; } + +//@} + +private: + +/*! \name Private methods */ +//@{ + + /*! Process a name for efficient matching */ + void processName() ; + +//@} + +/*! \name Private parameter data */ +//@{ + /// Parameter type (see #CoinParamType) + CoinParamType type_ ; + + /// Parameter name + std::string name_ ; + + /// Length of parameter name + size_t lengthName_ ; + + /*! \brief Minimum length required to declare a match for the parameter + name. + */ + size_t lengthMatch_ ; + + /// Lower bound on value for a double parameter + double lowerDblValue_ ; + + /// Upper bound on value for a double parameter + double upperDblValue_ ; + + /// Double parameter - current value + double dblValue_ ; + + /// Lower bound on value for an integer parameter + int lowerIntValue_ ; + + /// Upper bound on value for an integer parameter + int upperIntValue_ ; + + /// Integer parameter - current value + int intValue_ ; + + /// String parameter - current value + std::string strValue_ ; + + /// Set of valid value-keywords for a keyword parameter + std::vector<std::string> definedKwds_ ; + + /*! \brief Current value for a keyword parameter (index into #definedKwds_) + */ + int currentKwd_ ; + + /// Push function + CoinParamFunc pushFunc_ ; + + /// Pull function + CoinParamFunc pullFunc_ ; + + /// Short help + std::string shortHelp_ ; + + /// Long help + std::string longHelp_ ; + + /// Display when processing lists of parameters? + bool display_ ; +//@} + +} ; + +/*! \relatesalso CoinParam + \brief A type for a parameter vector. +*/ +typedef std::vector<CoinParam*> CoinParamVec ; + +/*! \relatesalso CoinParam + \brief A stream output function for a CoinParam object. +*/ +std::ostream &operator<< (std::ostream &s, const CoinParam ¶m) ; + +/* + Bring in the utility functions for parameter handling (CbcParamUtils). +*/ + +/*! \brief Utility functions for processing CoinParam parameters. + + The functions in CoinParamUtils support command line or interactive + parameter processing and a help facility. Consult the `Related Functions' + section of the CoinParam class documentation for individual function + documentation. +*/ +namespace CoinParamUtils { + /*! \relatesalso CoinParam + \brief Take command input from the file specified by src. + + Use stdin for \p src to specify interactive prompting for commands. + */ + void setInputSrc(FILE *src) ; + + /*! \relatesalso CoinParam + \brief Returns true if command line parameters are being processed. + */ + bool isCommandLine() ; + + /*! \relatesalso CoinParam + \brief Returns true if parameters are being obtained from stdin. + */ + bool isInteractive() ; + + /*! \relatesalso CoinParam + \brief Attempt to read a string from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a string is parsed + without error, 2 if no field is present. + */ + std::string getStringField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read an integer from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if an integer is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + int getIntField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read a real (double) from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a real number is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + double getDoubleField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Scan a parameter vector for parameters whose keyword (name) string + matches \p name using minimal match rules. + + \p matchNdx is set to the index of the last parameter that meets the + minimal match criteria (but note there should be at most one matching + parameter if the parameter vector is properly configured). \p shortCnt + is set to the number of short matches (should be zero for a properly + configured parameter vector if a minimal match is found). The return + value is the number of matches satisfying the minimal match requirement + (should be 0 or 1 in a properly configured vector). + */ + int matchParam(const CoinParamVec ¶mVec, std::string name, + int &matchNdx, int &shortCnt) ; + + /*! \relatesalso CoinParam + \brief Get the next command keyword (name) + + To be precise, return the next field from the current command input + source, after a bit of processing. In command line mode (isCommandLine() + returns true) the next field will normally be of the form `-keyword' or + `--keyword' (\e i.e., a parameter keyword), and the string returned would + be `keyword'. In interactive mode (isInteractive() returns true), the + user will be prompted if necessary. It is assumed that the user knows + not to use the `-' or `--' prefixes unless specifying parameters on the + command line. + + There are a number of special cases if we're in command line mode. The + order of processing of the raw string goes like this: + <ul> + <li> A stand-alone `-' is forced to `stdin'. + <li> A stand-alone '--' is returned as a word; interpretation is up to + the client. + <li> A prefix of '-' or '--' is stripped from the string. + </ul> + If the result is the string `stdin', command processing shifts to + interactive mode and the user is immediately prompted for a new command. + + Whatever results from the above sequence is returned to the user as the + return value of the function. An empty string indicates end of input. + + \p prompt will be used only if it's necessary to prompt the user in + interactive mode. + */ + + std::string getCommand(int argc, const char *argv[], + const std::string prompt, std::string *pfx = 0) ; + + /*! \relatesalso CoinParam + \brief Look up the command keyword (name) in the parameter vector. + Print help if requested. + + In the most straightforward use, \p name is a string without `?', and the + value returned is the index in \p paramVec of the single parameter that + matched \p name. One or more '?' characters at the end of \p name is a + query for information. The routine prints short (one '?') or long (more + than one '?') help messages for a query. Help is also printed in the case + where the name is ambiguous (some of the matches did not meet the minimal + match length requirement). + + Note that multiple matches meeting the minimal match requirement is a + configuration error. The mimimal match length for the parameters + involved is too short. + + If provided as parameters, on return + <ul> + <li> \p matchCnt will be set to the number of matches meeting the + minimal match requirement + <li> \p shortCnt will be set to the number of matches that did not + meet the miminal match requirement + <li> \p queryCnt will be set to the number of '?' characters at the + end of the name + </ul> + + The return values are: + <ul> + <li> >0: index in \p paramVec of the single unique match for \p name + <li> -1: a query was detected (one or more '?' characters at the end + of \p name + <li> -2: one or more short matches, not a query + <li> -3: no matches, not a query + <li> -4: multiple matches meeting the minimal match requirement + (configuration error) + </ul> + */ + int lookupParam(std::string name, CoinParamVec ¶mVec, + int *matchCnt = 0, int *shortCnt = 0, int *queryCnt = 0) ; + + /*! \relatesalso CoinParam + \brief Utility to print a long message as filled lines of text + + The routine makes a best effort to break lines without exceeding the + standard 80 character line length. Explicit newlines in \p msg will + be obeyed. + */ + void printIt(const char *msg) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given a short match or explicit + request for help. + + The two really are related, in that a query (a string that ends with + one or more `?' characters) will often result in a short match. The + routine expects that \p name matches a single parameter, and does not + look for multiple matches. + + If called with \p matchNdx < 0, the routine will look up \p name in \p + paramVec and print the full name from the parameter. If called with \p + matchNdx > 0, it just prints the name from the specified parameter. If + the name is a query, short (one '?') or long (more than one '?') help + is printed. + + */ void shortOrHelpOne(CoinParamVec ¶mVec,int matchNdx, std::string + name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given multiple matches. + + If the name is not a query, or asks for short help (\e i.e., contains + zero or one '?' characters), the list of matching names is printed. If + the name asks for long help (contains two or more '?' characters), + short help is printed for each matching name. + */ + void shortOrHelpMany(CoinParamVec ¶mVec, + std::string name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Print a generic `how to use the command interface' help message. + + The message is hard coded to match the behaviour of the parsing utilities. + */ + void printGenericHelp() ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help messages for one or more + parameters. + + Intended as a utility to implement explicit `help' commands. Help will be + printed for all parameters in \p paramVec from \p firstParam to \p + lastParam, inclusive. If \p shortHelp is true, short help messages will + be printed. If \p longHelp is true, long help messages are printed. \p + shortHelp overrules \p longHelp. If neither is true, only command + keywords are printed. \p prefix is printed before each line; it's an + imperfect attempt at indentation. + */ + void printHelp(CoinParamVec ¶mVec, int firstParam, int lastParam, + std::string prefix, + bool shortHelp, bool longHelp, bool hidden) ; +} + + +#endif /* CoinParam_H */ + diff --git a/thirdparty/linux/include/coin/coin/CoinPragma.hpp b/thirdparty/linux/include/coin/coin/CoinPragma.hpp new file mode 100644 index 0000000..b9f8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPragma.hpp @@ -0,0 +1,26 @@ +/* $Id: CoinPragma.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPragma_H +#define CoinPragma_H + +//------------------------------------------------------------------- +// +// This is a file which can contain Pragma's that are +// generally applicable to any source file. +// +//------------------------------------------------------------------- + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +// Turn off compiler warning: +// "empty controlled statement found; is this the intent?" +# pragma warning(disable:4390) +// Turn off compiler warning about deprecated functions +# pragma warning(disable:4996) +#endif + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveDoubleton.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveDoubleton.hpp new file mode 100644 index 0000000..3ad8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveDoubleton.hpp @@ -0,0 +1,73 @@ +/* $Id: CoinPresolveDoubleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDoubleton_H +#define CoinPresolveDoubleton_H + +#define DOUBLETON 5 + +/*! \class doubleton_action + \brief Solve ax+by=c for y and substitute y out of the problem. + + This moves the bounds information for y onto x, making y free and allowing + us to substitute it away. + \verbatim + a x + b y = c + l1 <= x <= u1 + l2 <= y <= u2 ==> + + l2 <= (c - a x) / b <= u2 + b/-a > 0 ==> (b l2 - c) / -a <= x <= (b u2 - c) / -a + b/-a < 0 ==> (b u2 - c) / -a <= x <= (b l2 - c) / -a + \endverbatim +*/ +class doubleton_action : public CoinPresolveAction { + public: + struct action { + + double clox; + double cupx; + double costx; + + double costy; + + double rlo; + + double coeffx; + double coeffy; + + double *colel; + + int icolx; + int icoly; + int row; + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("doubleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~doubleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveDual.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveDual.hpp new file mode 100644 index 0000000..b021ce0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveDual.hpp @@ -0,0 +1,85 @@ +/* $Id: CoinPresolveDual.hpp 1510 2011-12-08 23:56:01Z lou $ */ + +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDual_H +#define CoinPresolveDual_H + +/*! \class remove_dual_action + \brief Attempt to fix variables by bounding reduced costs + + The reduced cost of x_j is d_j = c_j - y*a_j (1). Assume minimization, + so that at optimality d_j >= 0 for x_j nonbasic at lower bound, and + d_j <= 0 for x_j nonbasic at upper bound. + + For a slack variable s_i, c_(n+i) = 0 and a_(n+i) is a unit vector, hence + d_(n+i) = -y_i. If s_i has a finite lower bound and no upper bound, we + must have y_i <= 0 at optimality. Similarly, if s_i has no lower bound and a + finite upper bound, we must have y_i >= 0. + + For a singleton variable x_j, d_j = c_j - y_i*a_ij. Given x_j with a + single finite bound, we can bound d_j greater or less than 0 at + optimality, and that allows us to calculate an upper or lower bound on y_i + (depending on the bound on d_j and the sign of a_ij). + + Now we have bounds on some subset of the y_i, and we can use these to + calculate upper and lower bounds on the d_j, using bound propagation on + (1). If we can manage to bound some d_j as strictly positive or strictly + negative, then at optimality the corresponding variable must be nonbasic + at its lower or upper bound, respectively. If the required bound is lacking, + the problem is unbounded. +*/ + +class remove_dual_action : public CoinPresolveAction { + + public: + + /// Destructor + ~remove_dual_action () ; + + /// Name + inline const char *name () const { return ("remove_dual_action") ; } + + /*! \brief Attempt to fix variables by bounding reduced costs + + Always scans all variables. Propagates bounds on reduced costs until there's + no change or until some set of variables can be fixed. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + /*! \brief Postsolve + + In addition to fixing variables (handled by make_fixed_action), we may + need use our own postsolve to restore constraint bounds. + */ + void postsolve (CoinPostsolveMatrix *prob) const ; + + private: + + /// Postsolve (bound restore) instruction + struct action { + double rlo_ ; ///< restored row lower bound + double rup_ ; ///< restored row upper bound + int ndx_ ; ///< row index + } ; + + /// Constructor with postsolve actions. + remove_dual_action(int nactions, const action *actions, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + /// Count of bound restore entries + const int nactions_ ; + /// Bound restore entries + const action *actions_ ; + +} ; +#endif + + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveDupcol.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveDupcol.hpp new file mode 100644 index 0000000..8610adb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveDupcol.hpp @@ -0,0 +1,230 @@ +/* $Id: CoinPresolveDupcol.hpp 1854 2015-12-18 14:18:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDupcol_H +#define CoinPresolveDupcol_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define DUPCOL 10 + +/*! \class dupcol_action + \brief Detect and remove duplicate columns + + The general technique is to sum the coefficients a_(*,j) of each column. + Columns with identical sums are duplicates. The obvious problem is that, + <i>e.g.</i>, [1 0 1 0] and [0 1 0 1] both add to 2. To minimize the + chances of false positives, the coefficients of each row are multipled by + a random number r_i, so that we sum r_i*a_ij. + + Candidate columns are checked to confirm they are identical. Where the + columns have the same objective coefficient, the two are combined. If the + columns have different objective coefficients, complications ensue. In order + to remove the duplicate, it must be possible to fix the variable at a bound. +*/ + +class dupcol_action : public CoinPresolveAction { + dupcol_action(); + dupcol_action(const dupcol_action& rhs); + dupcol_action& operator=(const dupcol_action& rhs); + + struct action { + double thislo; + double thisup; + double lastlo; + double lastup; + int ithis; + int ilast; + + double *colels; + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + dupcol_action(int nactions, const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~dupcol_action(); + +}; + + +/*! \class duprow_action + \brief Detect and remove duplicate rows + + The algorithm to detect duplicate rows is as outlined for dupcol_action. + + If the feasible interval for one constraint is strictly contained in the + other, the tighter (contained) constraint is kept. If the feasible + intervals are disjoint, the problem is infeasible. If the feasible + intervals overlap, both constraints are kept. + + duprow_action is definitely a work in progress; #postsolve is + unimplemented. + This doesn't matter as it uses useless_constraint. +*/ + +class duprow_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +class duprow3_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow3_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow3_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +/*! \class gubrow_action + \brief Detect and remove entries whose sum is known + + If we have an equality row where all entries same then + For other rows where all entries for that equality row are same + then we can delete entries and modify rhs + gubrow_action is definitely a work in progress; #postsolve is + unimplemented. +*/ + +class gubrow_action : public CoinPresolveAction { + struct action { + double rhs; + // last is row itself + int * deletedRow; + double * rowels; + int * indices; // indices in gub row + int nDrop; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + //gubrow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + gubrow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~gubrow_action(); +}; + +/*! \class twoxtwo_action + \brief Detect interesting 2 by 2 blocks + + If a variable has two entries and for each row there are only + two entries with same other variable then we can get rid of + one constraint and modify costs. + + This is a work in progress - I need more examples +*/ + +class twoxtwo_action : public CoinPresolveAction { + struct action { + double lbound_row; + double ubound_row; + double lbound_col; + double ubound_col; + double cost_col; + double cost_othercol; + int row; + int col; + int othercol; + }; + + const int nactions_; + const action *const actions_; + + twoxtwo_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + twoxtwo_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + ~twoxtwo_action() { delete [] actions_; } +}; + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveEmpty.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveEmpty.hpp new file mode 100644 index 0000000..336f1fd --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveEmpty.hpp @@ -0,0 +1,116 @@ +/* $Id: CoinPresolveEmpty.hpp 1561 2012-11-24 00:32:16Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveEmpty_H +#define CoinPresolveEmpty_H + +/*! \file + + Drop/reinsert empty rows/columns. +*/ + +const int DROP_ROW = 3; +const int DROP_COL = 4; + +/*! \class drop_empty_cols_action + \brief Physically removes empty columns in presolve, and reinserts + empty columns in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is <b>not</b> maintained by this transform. + + To physically drop the columns, CoinPrePostsolveMatrix::mcstrt_ and + CoinPrePostsolveMatrix::hincol_ are compressed, along with column bounds, + objective, and (if present) the column portions of the solution. This + renumbers the columns. drop_empty_cols_action::presolve will reconstruct + CoinPresolveMatrix::clink_. + + \todo Confirm correct behaviour with solution in presolve. +*/ + +class drop_empty_cols_action : public CoinPresolveAction { +private: + const int nactions_; + + struct action { + double clo; + double cup; + double cost; + double sol; + int jcol; + }; + const action *const actions_; + + drop_empty_cols_action(int nactions, + const action *const actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + public: + const char *name() const { return ("drop_empty_cols_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const int *ecols, + int necols, + const CoinPresolveAction*); + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_cols_action() { deleteAction(actions_,action*); } +}; + + +/*! \class drop_empty_rows_action + \brief Physically removes empty rows in presolve, and reinserts + empty rows in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is <b>not</b> maintained by this transform. + + To physically drop the rows, the rows are renumbered, excluding empty + rows. This involves rewriting CoinPrePostsolveMatrix::hrow_ and compressing + the row bounds and (if present) the row portions of the solution. + + \todo Confirm behaviour when a solution is present in presolve. +*/ +class drop_empty_rows_action : public CoinPresolveAction { +private: + struct action { + double rlo; + double rup; + int row; + int fill_row; // which row was moved into position row to fill it + }; + + const int nactions_; + const action *const actions_; + + drop_empty_rows_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("drop_empty_rows_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_rows_action() { deleteAction(actions_,action*); } +}; +#endif + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveFixed.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveFixed.hpp new file mode 100644 index 0000000..dc59207 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveFixed.hpp @@ -0,0 +1,181 @@ +/* $Id: CoinPresolveFixed.hpp 1510 2011-12-08 23:56:01Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveFixed_H +#define CoinPresolveFixed_H +#define FIXED_VARIABLE 1 + +/*! \class remove_fixed_action + \brief Excise fixed variables from the model. + + Implements the action of virtually removing one or more fixed variables + x_j from the model by substituting the value sol_j in each constraint. + Specifically, for each constraint i where a_ij != 0, rlo_i and rup_i + are adjusted by -a_ij*sol_j and a_ij is set to 0. + + There is an implicit assumption that the variable already has the correct + value. If this isn't true, corrections to row activity may be incorrect. + If you want to guard against this possibility, consider make_fixed_action. + + Actual removal of the empty column from the matrix is handled by + drop_empty_cols_action. Correction of the objective function is done there. +*/ +class remove_fixed_action : public CoinPresolveAction { + public: + /*! \brief Structure to hold information necessary to reintroduce a + column into the problem representation. + */ + struct action { + int col; ///< column index of variable + int start; ///< start of coefficients in #colels_ and #colrows_ + double sol; ///< value of variable + }; + /// Array of row indices for coefficients of excised columns + int *colrows_; + /// Array of coefficients of excised columns + double *colels_; + /// Number of entries in #actions_ + int nactions_; + /// Vector specifying variable(s) affected by this object + action *actions_; + + private: + /*! \brief Constructor */ + remove_fixed_action(int nactions, + action *actions, + double * colels, + int * colrows, + const CoinPresolveAction *next); + + public: + /// Returns string "remove_fixed_action". + const char *name() const; + + /*! \brief Excise the specified columns. + + Remove the specified columns (\p nfcols, \p fcols) from the problem + representation (\p prob), leaving the appropriate postsolve object + linked as the head of the list of postsolve objects (currently headed + by \p next). + */ + static const remove_fixed_action *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~remove_fixed_action(); +}; + + +/*! \relates remove_fixed_action + \brief Scan the problem for fixed columns and remove them. + + A front end to collect a list of columns with equal bounds and hand them to + remove_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *remove_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + +/*! \class make_fixed_action + \brief Fix a variable at a specified bound. + + Implements the action of fixing a variable by forcing both bounds to the same + value and forcing the value of the variable to match. + + If the bounds are already equal, and the value of the variable is already + correct, consider remove_fixed_action. +*/ +class make_fixed_action : public CoinPresolveAction { + + /// Structure to preserve the bound overwritten when fixing a variable + struct action { + double bound; ///< Value of bound overwritten to fix variable. + int col ; ///< column index of variable + }; + + /// Number of preserved bounds + int nactions_; + /// Vector of preserved bounds, one for each variable fixed in this object + const action *actions_; + + /*! \brief True to fix at lower bound, false to fix at upper bound. + + Note that this applies to all variables fixed in this object. + */ + const bool fix_to_lower_; + + /*! \brief The postsolve object with the information required to repopulate + the fixed columns. + */ + const remove_fixed_action *faction_; + + /*! \brief Constructor */ + make_fixed_action(int nactions, const action *actions, bool fix_to_lower, + const remove_fixed_action *faction, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), actions_(actions), + fix_to_lower_(fix_to_lower), + faction_(faction) + {} + + public: + /// Returns string "make_fixed_action". + const char *name() const; + + /*! \brief Perform actions to fix variables and return postsolve object + + For each specified variable (\p nfcols, \p fcols), fix the variable to + the specified bound (\p fix_to_lower) by setting the variable's bounds + to be equal in \p prob. Create a postsolve object, link it at the head of + the list of postsolve objects (\p next), and return the object. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + bool fix_to_lower, + const CoinPresolveAction *next); + + /*! \brief Postsolve (unfix variables) + + Back out the variables fixed by the presolve side of this object. + */ + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~make_fixed_action() { + deleteAction(actions_,action*); + delete faction_; + } +}; + +/*! \relates make_fixed_action + \brief Scan variables and fix any with equal bounds + + A front end to collect a list of columns with equal bounds and hand them to + make_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *make_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + +/*! \brief Transfer costs from singleton variables + \relates make_fixed_action + + Transfers costs from singleton variables in equalities onto the other + variables. Will also transfer costs from one integer variable to other + integer variables with zero cost if there's a net gain in integer variables + with non-zero cost. + + The relation to make_fixed_action is tenuous, but this transform should be + attempted before the initial round of variable fixing. +*/ +void transferCosts(CoinPresolveMatrix * prob); +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveForcing.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveForcing.hpp new file mode 100644 index 0000000..ee5a641 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveForcing.hpp @@ -0,0 +1,61 @@ +/* $Id: CoinPresolveForcing.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveForcing_H +#define CoinPresolveForcing_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define IMPLIED_BOUND 7 + +/*! \class forcing_constraint_action + \brief Detect and process forcing constraints and useless constraints + + A constraint is useless if the bounds on the variables prevent the constraint + from ever being violated. + + A constraint is a forcing constraint if the bounds on the constraint force + the value of an involved variable to one of its bounds. A constraint can + force more than one variable. +*/ +class forcing_constraint_action : public CoinPresolveAction { + forcing_constraint_action(); + forcing_constraint_action(const forcing_constraint_action& rhs); + forcing_constraint_action& operator=(const forcing_constraint_action& rhs); +public: + struct action { + const int *rowcols; + const double *bounds; + int row; + int nlo; + int nup; + }; +private: + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + +public: + forcing_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~forcing_constraint_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveImpliedFree.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveImpliedFree.hpp new file mode 100644 index 0000000..8215b98 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveImpliedFree.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveImpliedFree.hpp 1694 2014-04-29 02:08:35Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveImpliedFree_H +#define CoinPresolveImpliedFree_H + +/*! + \file +*/ + +#define IMPLIED_FREE 9 + +/*! \class implied_free_action + \brief Detect and process implied free variables + + Consider a singleton variable x (<i>i.e.</i>, a variable involved in only + one constraint). Suppose that the bounds on that constraint, combined with + the bounds on the other variables involved in the constraint, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. Both x and + the constraint can be deleted from the problem. + + A similar transform for the case where the variable is not a natural column + singleton is handled by #subst_constraint_action. +*/ +class implied_free_action : public CoinPresolveAction { + struct action { + int row, col; + double clo, cup; + double rlo, rup; + const double *rowels; + const double *costs; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + implied_free_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int & fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~implied_free_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveIsolated.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveIsolated.hpp new file mode 100644 index 0000000..38c700f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveIsolated.hpp @@ -0,0 +1,51 @@ +/* $Id: CoinPresolveIsolated.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveIsolated_H +#define CoinPresolveIsolated_H + +#include "CoinPresolveMatrix.hpp" + +class isolated_constraint_action : public CoinPresolveAction { + isolated_constraint_action(); + isolated_constraint_action(const isolated_constraint_action& rhs); + isolated_constraint_action& operator=(const isolated_constraint_action& rhs); + + double rlo_; + double rup_; + int row_; + int ninrow_; + // the arrays are owned by the class and must be deleted at destruction + const int *rowcols_; + const double *rowels_; + const double *costs_; + + isolated_constraint_action(double rlo, + double rup, + int row, + int ninrow, + const int *rowcols, + const double *rowels, + const double *costs, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + rlo_(rlo), rup_(rup), row_(row), ninrow_(ninrow), + rowcols_(rowcols), rowels_(rowels), costs_(costs) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + int row, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~isolated_constraint_action(); +}; + + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveMatrix.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveMatrix.hpp new file mode 100644 index 0000000..e608738 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveMatrix.hpp @@ -0,0 +1,1842 @@ +/* $Id: CoinPresolveMatrix.hpp 1761 2014-12-10 09:43:07Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveMatrix_H +#define CoinPresolveMatrix_H + +#include "CoinPragma.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +#include "CoinTime.hpp" + +#include <cmath> +#include <cassert> +#include <cfloat> +#include <cassert> +#include <cstdlib> + +#if PRESOLVE_DEBUG > 0 +#include "CoinFinite.hpp" +#endif + +/*! \file + + Declarations for CoinPresolveMatrix and CoinPostsolveMatrix and their + common base class CoinPrePostsolveMatrix. Also declarations for + CoinPresolveAction and a number of non-member utility functions. +*/ + + +#if defined(_MSC_VER) +// Avoid MS Compiler problem in recognizing type to delete +// by casting to type. +// Is this still necessary? -- lh, 111202 -- +#define deleteAction(array,type) delete [] ((type) array) +#else +#define deleteAction(array,type) delete [] array +#endif + +/* + Define PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure command + line or in a Makefile! See comments in CoinPresolvePsdebug.hpp. +*/ +#if PRESOLVE_DEBUG > 0 || PRESOLVE_CONSISTENCY > 0 + +#define PRESOLVE_STMT(s) s + +#define PRESOLVEASSERT(x) \ + ((x) ? 1 : ((std::cerr << "FAILED ASSERTION at line " \ + << __LINE__ << ": " #x "\n"), abort(), 0)) + +inline void DIE(const char *s) { std::cout << s ; abort() ; } + +/*! \brief Indicate column or row present at start of postsolve + + This code is used during postsolve in [cr]done to indicate columns and rows + that are present in the presolved system (i.e., present at the start of + postsolve processing). + + \todo + There are a bunch of these code definitions, scattered through presolve + files. They should be collected in one place. +*/ +#define PRESENT_IN_REDUCED '\377' + +#else + +#define PRESOLVEASSERT(x) {} +#define PRESOLVE_STMT(s) {} + +inline void DIE(const char *) {} + +#endif + +/* + Unclear why these are separate from standard debug. +*/ +#ifndef PRESOLVE_DETAIL +#define PRESOLVE_DETAIL_PRINT(s) {} +#else +#define PRESOLVE_DETAIL_PRINT(s) s +#endif + +/*! \brief Zero tolerance + + OSL had a fixed zero tolerance; we still use that here. +*/ +const double ZTOLDP = 1e-12 ; +/*! \brief Alternate zero tolerance + + Use a different one if we are doing doubletons, etc. +*/ +const double ZTOLDP2 = 1e-10 ; + +/// The usual finite infinity +#define PRESOLVE_INF COIN_DBL_MAX +/// And a small infinity +#define PRESOLVE_SMALL_INF 1.0e20 +/// Check for infinity using finite infinity +#define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF) + + +class CoinPostsolveMatrix ; + +/*! \class CoinPresolveAction + \brief Abstract base class of all presolve routines. + + The details will make more sense after a quick overview of the grand plan: + A presolve object is handed a problem object, which it is expected to + modify in some useful way. Assuming that it succeeds, the presolve object + should create a postsolve object, <i>i.e.</i>, an object that contains + instructions for backing out the presolve transform to recover the original + problem. These postsolve objects are accumulated in a linked list, with each + successive presolve action adding its postsolve action to the head of the + list. The end result of all this is a presolved problem object, and a list + of postsolve objects. The presolved problem object is then handed to a + solver for optimization, and the problem object augmented with the + results. The list of postsolve objects is then traversed. Each of them + (un)modifies the problem object, with the end result being the original + problem, augmented with solution information. + + The problem object representation is CoinPrePostsolveMatrix and subclasses. + Check there for details. The \c CoinPresolveAction class and subclasses + represent the presolve and postsolve objects. + + In spite of the name, the only information held in a \c CoinPresolveAction + object is the information needed to postsolve (<i>i.e.</i>, the information + needed to back out the presolve transformation). This information is not + expected to change, so the fields are all \c const. + + A subclass of \c CoinPresolveAction, implementing a specific pre/postsolve + action, is expected to declare a static function that attempts to perform a + presolve transformation. This function will be handed a CoinPresolveMatrix + to transform, and a pointer to the head of the list of postsolve objects. + If the transform is successful, the function will create a new + \c CoinPresolveAction object, link it at the head of the list of postsolve + objects, and return a pointer to the postsolve object it has just created. + Otherwise, it should return 0. It is expected that these static functions + will be the only things that can create new \c CoinPresolveAction objects; + this is expressed by making each subclass' constructor(s) private. + + Every subclass must also define a \c postsolve method. + This function will be handed a CoinPostsolveMatrix to transform. + + It is the client's responsibility to implement presolve and postsolve driver + routines. See OsiPresolve for examples. + + \note Since the only fields in a \c CoinPresolveAction are \c const, anything + one can do with a variable declared \c CoinPresolveAction* can also be + done with a variable declared \c const \c CoinPresolveAction* It is + expected that all derived subclasses of \c CoinPresolveAction also have + this property. +*/ +class CoinPresolveAction +{ + public: + /*! \brief Stub routine to throw exceptions. + + Exceptions are inefficient, particularly with g++. Even with xlC, the + use of exceptions adds a long prologue to a routine. Therefore, rather + than use throw directly in the routine, I use it in a stub routine. + */ + static void throwCoinError(const char *error, const char *ps_routine) + { throw CoinError(error, ps_routine, "CoinPresolve"); } + + /*! \brief The next presolve transformation + + Set at object construction. + */ + const CoinPresolveAction *next; + + /*! \brief Construct a postsolve object and add it to the transformation list. + + This is an `add to head' operation. This object will point to the + one passed as the parameter. + */ + CoinPresolveAction(const CoinPresolveAction *next) : next(next) {} + /// modify next (when building rather than passing) + inline void setNext(const CoinPresolveAction *nextAction) + { next = nextAction;} + + /*! \brief A name for debug printing. + + It is expected that the name is not stored in the transform itself. + */ + virtual const char *name() const = 0; + + /*! \brief Apply the postsolve transformation for this particular + presolve action. + */ + virtual void postsolve(CoinPostsolveMatrix *prob) const = 0; + + /*! \brief Virtual destructor. */ + virtual ~CoinPresolveAction() {} +}; + +/* + These are needed for OSI-aware constructors associated with + CoinPrePostsolveMatrix, CoinPresolveMatrix, and CoinPostsolveMatrix. +*/ +class ClpSimplex; +class OsiSolverInterface; + +/* + CoinWarmStartBasis is required for methods in CoinPrePostsolveMatrix + that accept/return a CoinWarmStartBasis object. +*/ +class CoinWarmStartBasis ; + +/*! \class CoinPrePostsolveMatrix + \brief Collects all the information about the problem that is needed + in both presolve and postsolve. + + In a bit more detail, a column-major representation of the constraint + matrix and upper and lower bounds on variables and constraints, plus row + and column solutions, reduced costs, and status. There's also a set of + arrays holding the original row and column numbers. + + As presolve and postsolve transform the matrix, it will occasionally be + necessary to expand the number of entries in a column. There are two + aspects: + <ul> + <li> During postsolve, the constraint system is expected to grow as + the smaller presolved system is transformed back to the original + system. + <li> During both pre- and postsolve, transforms can increase the number + of coefficients in a row or column. (See the + variable substitution, doubleton, and tripleton transforms.) + </ul> + + The first is addressed by the members #ncols0_, #nrows0_, and #nelems0_. + These should be set (via constructor parameters) to values large enough + for the largest size taken on by the constraint system. Typically, this + will be the size of the original constraint system. + + The second is addressed by a generous allocation of extra (empty) space + for the arrays used to hold coefficients and row indices. When columns + must be expanded, they are moved into the empty space. When it is used up, + the arrays are compacted. When compaction fails to produce sufficient + space, presolve/postsolve will fail. + + CoinPrePostsolveMatrix isn't really intended to be used `bare' --- the + expectation is that it'll be used through CoinPresolveMatrix or + CoinPostsolveMatrix. Some of the functions needed to load a problem are + defined in the derived classes. + + When CoinPresolve is applied when reoptimising, we need to be prepared to + accept a basis and modify it in step with the presolve actions (otherwise + we throw away all the advantages of warm start for reoptimization). But + other solution components (#acts_, #rowduals_, #sol_, and #rcosts_) are + needed only for postsolve, where they're used in places to determine the + proper action(s) when restoring rows or columns. If presolve is provided + with a solution, it will modify it in step with the presolve actions. + Moving the solution components from CoinPrePostsolveMatrix to + CoinPostsolveMatrix would break a lot of code. It's not clear that it's + worth it, and it would preclude upgrades to the presolve side that might + make use of any of these. -- lh, 080501 -- + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPrePostsolveMatrix +{ + public: + + /*! \name Constructors & Destructors */ + + //@{ + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. On + the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPrePostsolveMatrix(const OsiSolverInterface * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_); + + /*! ClpOsi constructor + + See Clp code for the definition. + */ + CoinPrePostsolveMatrix(const ClpSimplex * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_, + double bulkRatio); + + /// Destructor + ~CoinPrePostsolveMatrix(); + //@} + + /*! \brief Enum for status of various sorts + + Matches CoinWarmStartBasis::Status and adds superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + superBasic is an unresolved problem: there's no analogue in + CoinWarmStartBasis::Status. + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04 + }; + + /*! \name Functions to work with variable status + + Functions to work with the CoinPrePostsolveMatrix::Status enum and + related vectors. + + \todo + Why are we futzing around with three bit status? A holdover from the + packed arrays of CoinWarmStartBasis? Big swaths of the presolve code + manipulates colstat_ and rowstat_ as unsigned char arrays using simple + assignment to set values. + */ + //@{ + + /// Set row status (<i>i.e.</i>, status of artificial for this row) + inline void setRowStatus(int sequence, Status status) + { + unsigned char & st_byte = rowstat_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & (~7)) ; + st_byte = static_cast<unsigned char>(st_byte | status) ; + } + /// Get row status + inline Status getRowStatus(int sequence) const + {return static_cast<Status> (rowstat_[sequence]&7);} + /// Check if artificial for this row is basic + inline bool rowIsBasic(int sequence) const + {return (static_cast<Status> (rowstat_[sequence]&7)==basic);} + /// Set column status (<i>i.e.</i>, status of primal variable) + inline void setColumnStatus(int sequence, Status status) + { + unsigned char & st_byte = colstat_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & (~7)) ; + st_byte = static_cast<unsigned char>(st_byte | status) ; + +# ifdef PRESOLVE_DEBUG + switch (status) + { case isFree: + { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " isFree, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case basic: + { break ; } + case atUpperBound: + { if (cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atUpperBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case atLowerBound: + { if (clo_[sequence] <= -PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atLowerBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case superBasic: + { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " superBasic, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + default: + { assert(false) ; + break ; } } +# endif + } + /// Get column (structural variable) status + inline Status getColumnStatus(int sequence) const + {return static_cast<Status> (colstat_[sequence]&7);} + /// Check if column (structural variable) is basic + inline bool columnIsBasic(int sequence) const + {return (static_cast<Status> (colstat_[sequence]&7)==basic);} + /*! \brief Set status of row (artificial variable) to the correct nonbasic + status given bounds and current value + */ + void setRowStatusUsingValue(int iRow); + /*! \brief Set status of column (structural variable) to the correct + nonbasic status given bounds and current value + */ + void setColumnStatusUsingValue(int iColumn); + /*! \brief Set column (structural variable) status vector */ + void setStructuralStatus(const char *strucStatus, int lenParam) ; + /*! \brief Set row (artificial variable) status vector */ + void setArtificialStatus(const char *artifStatus, int lenParam) ; + /*! \brief Set the status of all variables from a basis */ + void setStatus(const CoinWarmStartBasis *basis) ; + /*! \brief Get status in the form of a CoinWarmStartBasis */ + CoinWarmStartBasis *getStatus() ; + /*! \brief Return a print string for status of a column (structural + variable) + */ + const char *columnStatusString(int j) const ; + /*! \brief Return a print string for status of a row (artificial + variable) + */ + const char *rowStatusString(int i) const ; + //@} + + /*! \name Functions to load problem and solution information + + These functions can be used to load portions of the problem definition + and solution. See also the CoinPresolveMatrix and CoinPostsolveMatrix + classes. + */ + //@{ + /// Set the objective function offset for the original system. + void setObjOffset(double offset) ; + /*! \brief Set the objective sense (max/min) + + Coded as 1.0 for min, -1.0 for max. + Yes, there's a method, and a matching attribute. No, you really + don't want to set this to maximise. + */ + void setObjSense(double objSense) ; + /// Set the primal feasibility tolerance + void setPrimalTolerance(double primTol) ; + /// Set the dual feasibility tolerance + void setDualTolerance(double dualTol) ; + /// Set column lower bounds + void setColLower(const double *colLower, int lenParam) ; + /// Set column upper bounds + void setColUpper(const double *colUpper, int lenParam) ; + /// Set column solution + void setColSolution(const double *colSol, int lenParam) ; + /// Set objective coefficients + void setCost(const double *cost, int lenParam) ; + /// Set reduced costs + void setReducedCost(const double *redCost, int lenParam) ; + /// Set row lower bounds + void setRowLower(const double *rowLower, int lenParam) ; + /// Set row upper bounds + void setRowUpper(const double *rowUpper, int lenParam) ; + /// Set row solution + void setRowPrice(const double *rowSol, int lenParam) ; + /// Set row activity + void setRowActivity(const double *rowAct, int lenParam) ; + //@} + + /*! \name Functions to retrieve problem and solution information */ + //@{ + /// Get current number of columns + inline int getNumCols() const + { return (ncols_) ; } + /// Get current number of rows + inline int getNumRows() const + { return (nrows_) ; } + /// Get current number of non-zero coefficients + inline int getNumElems() const + { return (nelems_) ; } + /// Get column start vector for column-major packed matrix + inline const CoinBigIndex *getColStarts() const + { return (mcstrt_) ; } + /// Get column length vector for column-major packed matrix + inline const int *getColLengths() const + { return (hincol_) ; } + /// Get vector of row indices for column-major packed matrix + inline const int *getRowIndicesByCol() const + { return (hrow_) ; } + /// Get vector of elements for column-major packed matrix + inline const double *getElementsByCol() const + { return (colels_) ; } + /// Get column lower bounds + inline const double *getColLower() const + { return (clo_) ; } + /// Get column upper bounds + inline const double *getColUpper() const + { return (cup_) ; } + /// Get objective coefficients + inline const double *getCost() const + { return (cost_) ; } + /// Get row lower bounds + inline const double *getRowLower() const + { return (rlo_) ; } + /// Get row upper bounds + inline const double *getRowUpper() const + { return (rup_) ; } + /// Get column solution (primal variable values) + inline const double *getColSolution() const + { return (sol_) ; } + /// Get row activity (constraint lhs values) + inline const double *getRowActivity() const + { return (acts_) ; } + /// Get row solution (dual variables) + inline const double *getRowPrice() const + { return (rowduals_) ; } + /// Get reduced costs + inline const double *getReducedCost() const + { return (rcosts_) ; } + /// Count empty columns + inline int countEmptyCols() + { int empty = 0 ; + for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ; + return (empty) ; } + //@} + + + /*! \name Message handling */ + //@{ + /// Return message handler + inline CoinMessageHandler *messageHandler() const + { return handler_; } + /*! \brief Set message handler + + The client retains responsibility for the handler --- it will not be + destroyed with the \c CoinPrePostsolveMatrix object. + */ + inline void setMessageHandler(CoinMessageHandler *handler) + { if (defaultHandler_ == true) + { delete handler_ ; + defaultHandler_ = false ; } + handler_ = handler ; } + /// Return messages + inline CoinMessages messages() const + { return messages_; } + //@} + + /*! \name Current and Allocated Size + + During pre- and postsolve, the matrix will change in size. During presolve + it will shrink; during postsolve it will grow. Hence there are two sets of + size variables, one for the current size and one for the allocated size. + (See the general comments for the CoinPrePostsolveMatrix class for more + information.) + */ + //@{ + + /// current number of columns + int ncols_; + /// current number of rows + int nrows_; + /// current number of coefficients + CoinBigIndex nelems_; + + /// Allocated number of columns + int ncols0_; + /// Allocated number of rows + int nrows0_ ; + /// Allocated number of coefficients + CoinBigIndex nelems0_ ; + /*! \brief Allocated size of bulk storage for row indices and coefficients + + This is the space allocated for hrow_ and colels_. This must be large + enough to allow columns to be copied into empty space when they need to + be expanded. For efficiency (to minimize the number of times the + representation must be compressed) it's recommended that this be at least + 2*nelems0_. + */ + CoinBigIndex bulk0_ ; + /// Ratio of bulk0_ to nelems0_; default is 2. + double bulkRatio_; + //@} + + /*! \name Problem representation + + The matrix is the common column-major format: A pair of vectors with + positional correspondence to hold coefficients and row indices, and a + second pair of vectors giving the starting position and length of each + column in the first pair. + */ + //@{ + /// Vector of column start positions in #hrow_, #colels_ + CoinBigIndex *mcstrt_; + /// Vector of column lengths + int *hincol_; + /// Row indices (positional correspondence with #colels_) + int *hrow_; + /// Coefficients (positional correspondence with #hrow_) + double *colels_; + + /// Objective coefficients + double *cost_; + /// Original objective offset + double originalOffset_; + + /// Column (primal variable) lower bounds + double *clo_; + /// Column (primal variable) upper bounds + double *cup_; + + /// Row (constraint) lower bounds + double *rlo_; + /// Row (constraint) upper bounds + double *rup_; + + /*! \brief Original column numbers + + Over the current range of column numbers in the presolved problem, + the entry for column j will contain the index of the corresponding + column in the original problem. + */ + int * originalColumn_; + /*! \brief Original row numbers + + Over the current range of row numbers in the presolved problem, the + entry for row i will contain the index of the corresponding row in + the original problem. + */ + int * originalRow_; + + /// Primal feasibility tolerance + double ztolzb_; + /// Dual feasibility tolerance + double ztoldj_; + + /*! \brief Maximization/minimization + + Yes, there's a variable here. No, you really don't want to set this to + maximise. See the main notes for CoinPresolveMatrix. + */ + double maxmin_; + //@} + + /*! \name Problem solution information + + The presolve phase will work without any solution information + (appropriate for initial optimisation) or with solution information + (appropriate for reoptimisation). When solution information is supplied, + presolve will maintain it to the best of its ability. #colstat_ is + checked to determine the presence/absence of status information. #sol_ is + checked for primal solution information, and #rowduals_ for dual solution + information. + + The postsolve phase requires the complete solution information from the + presolved problem (status, primal and dual solutions). It will be + transformed into a correct solution for the original problem. + */ + //@{ + /*! \brief Vector of primal variable values + + If #sol_ exists, it is assumed that primal solution information should be + updated and that #acts_ also exists. + */ + double *sol_; + /*! \brief Vector of dual variable values + + If #rowduals_ exists, it is assumed that dual solution information should + be updated and that #rcosts_ also exists. + */ + double *rowduals_; + /*! \brief Vector of constraint left-hand-side values (row activity) + + Produced by evaluating constraints according to #sol_. Updated iff + #sol_ exists. + */ + double *acts_; + /*! \brief Vector of reduced costs + + Produced by evaluating dual constraints according to #rowduals_. Updated + iff #rowduals_ exists. + */ + double *rcosts_; + + /*! \brief Status of primal variables + + Coded with CoinPrePostSolveMatrix::Status, one code per char. colstat_ and + #rowstat_ <b>MUST</b> be allocated as a single vector. This is to maintain + compatibility with ClpPresolve and OsiPresolve, which do it this way. + */ + unsigned char *colstat_; + + /*! \brief Status of constraints + + More accurately, the status of the logical variable associated with the + constraint. Coded with CoinPrePostSolveMatrix::Status, one code per char. + Note that this must be allocated as a single vector with #colstat_. + */ + unsigned char *rowstat_; + //@} + + /*! \name Message handling + + Uses the standard COIN approach: a default handler is installed, and the + CoinPrePostsolveMatrix object takes responsibility for it. If the client + replaces the handler with one of their own, it becomes their + responsibility. + */ + //@{ + /// Message handler + CoinMessageHandler *handler_; + /// Indicates if the current #handler_ is default (true) or not (false). + bool defaultHandler_; + /// Standard COIN messages + CoinMessage messages_; + //@} + +}; + +/*! \relates CoinPrePostsolveMatrix + \brief Generate a print string for a status code. +*/ +const char *statusName (CoinPrePostsolveMatrix::Status status) ; + + +/*! \class presolvehlink + \brief Links to aid in packed matrix modification + + Currently, the matrices held by the CoinPrePostsolveMatrix and + CoinPresolveMatrix objects are represented in the same way as a + CoinPackedMatrix. In the course of presolve and postsolve transforms, it + will happen that a major-dimension vector needs to increase in size. In + order to check whether there is enough room to add another coefficient in + place, it helps to know the next vector (in memory order) in the bulk + storage area. To do that, a linked list of major-dimension vectors is + maintained; the "pre" and "suc" fields give the previous and next vector, + in memory order (that is, the vector whose mcstrt_ or mrstrt_ entry is + next smaller or larger). + + Consider a column-major matrix with ncols columns. By definition, + presolvehlink[ncols].pre points to the column in the last occupied + position of the bulk storage arrays. There is no easy way to find the + column which occupies the first position (there is no presolvehlink[-1] to + consult). If the column that initially occupies the first position is + moved for expansion, there is no way to reclaim the space until the bulk + storage is compacted. The same holds for the last and first rows of a + row-major matrix, of course. +*/ + +class presolvehlink +{ public: + int pre, suc; +} ; + +#define NO_LINK -66666666 + +/*! \relates presolvehlink + \brief unlink vector i + + Remove vector i from the ordering. +*/ +inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = isuc; + } + if (isuc >= 0) { + link[isuc].pre = ipre; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + +/*! \relates presolvehlink + \brief insert vector i after vector j + + Insert vector i between j and j.suc. +*/ +inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j) +{ + int isuc = link[j].suc; + link[j].suc = i; + link[i].pre = j; + if (isuc >= 0) { + link[isuc].pre = i; + } + link[i].suc = isuc; +} + +/*! \relates presolvehlink + \brief relink vector j in place of vector i + + Replace vector i in the ordering with vector j. This is equivalent to + <pre> + int pre = link[i].pre; + PRESOLVE_REMOVE_LINK(link,i); + PRESOLVE_INSERT_LINK(link,j,pre); + </pre> + But, this routine will work even if i happens to be first in the order. +*/ +inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = j; + } + if (isuc >= 0) { + link[isuc].pre = j; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + + +/*! \class CoinPresolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during presolve. + + For problem manipulation, this class adds a row-major matrix + representation, linked lists that allow for easy manipulation of the matrix + when applying presolve transforms, and vectors to track row and column + processing status (changed, needs further processing, change prohibited) + + For problem representation, this class adds information about variable type + (integer or continuous), an objective offset, and a feasibility tolerance. + + <b>NOTE</b> that the #anyInteger_ and #anyProhibited_ flags are independent + of the vectors used to track this information for individual variables + (#integerType_ and #rowChanged_ and #colChanged_, respectively). + + <b>NOTE</b> also that at the end of presolve the column-major and row-major + matrix representations are loosely packed (<i>i.e.</i>, there may be gaps + between columns in the bulk storage arrays). + + <b>NOTE</b> that while you might think that CoinPresolve is prepared to + handle minimisation or maximisation, it's unlikely that this still works. + This is a good thing: better to convert objective coefficients and duals + once, before starting presolve, rather than doing it over and over in + each transform that considers dual variables. + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPresolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPresolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + + ClpSimplex * si, + + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + double bulkRatio); + + /*! \brief Update the model held by a Clp OSI */ + void update_model(ClpSimplex * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + OsiSolverInterface * si, + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + const char * prohibited, + const char * rowProhibited=NULL); + + /*! \brief Update the model held by a generic OSI */ + void update_model(OsiSolverInterface * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + + /// Destructor + ~CoinPresolveMatrix(); + + /*! \brief Initialize a CoinPostsolveMatrix object, destroying the + CoinPresolveMatrix object. + + See CoinPostsolveMatrix::assignPresolveToPostsolve. + */ + friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /*! \name Functions to load the problem representation + */ + //@{ + /*! \brief Load the cofficient matrix. + + Load the coefficient matrix before loading the other vectors (bounds, + objective, variable type) required to define the problem. + */ + void setMatrix(const CoinPackedMatrix *mtx) ; + + /// Count number of empty rows + inline int countEmptyRows() + { int empty = 0 ; + for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ; + return (empty) ; } + + /*! \brief Set variable type information for a single variable + + Set \p variableType to 0 for continous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + inline void setVariableType(int i, int variableType) + { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ; + integerType_[i] = static_cast<unsigned char>(variableType) ; } + + /*! \brief Set variable type information for all variables + + Set \p variableType[i] to 0 for continuous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + void setVariableType(const unsigned char *variableType, int lenParam) ; + + /*! \brief Set the type of all variables + + allIntegers should be true to set the type to integer, false to set the + type to continuous. + */ + void setVariableType (bool allIntegers, int lenParam) ; + + /// Set a flag for presence (true) or absence (false) of integer variables + inline void setAnyInteger (bool anyInteger = true) + { anyInteger_ = anyInteger ; } + //@} + + /*! \name Functions to retrieve problem information + */ + //@{ + + /// Get row start vector for row-major packed matrix + inline const CoinBigIndex *getRowStarts() const + { return (mrstrt_) ; } + /// Get vector of column indices for row-major packed matrix + inline const int *getColIndicesByRow() const + { return (hcol_) ; } + /// Get vector of elements for row-major packed matrix + inline const double *getElementsByRow() const + { return (rowels_) ; } + + /*! \brief Check for integrality of the specified variable. + + Consults the #integerType_ vector if present; fallback is the + #anyInteger_ flag. + */ + inline bool isInteger (int i) const + { if (integerType_ == 0) + { return (anyInteger_) ; } + else + if (integerType_[i] == 1) + { return (true) ; } + else + { return (false) ; } } + + /*! \brief Check if there are any integer variables + + Consults the #anyInteger_ flag + */ + inline bool anyInteger () const + { return (anyInteger_) ; } + /// Picks up any special options + inline int presolveOptions() const + { return presolveOptions_;} + /// Sets any special options (see #presolveOptions_) + inline void setPresolveOptions(int value) + { presolveOptions_=value;} + //@} + + /*! \name Matrix storage management links + + Linked lists, modelled after the linked lists used in OSL + factorization. They are used for management of the bulk coefficient + and minor index storage areas. + */ + //@{ + /// Linked list for the column-major representation. + presolvehlink *clink_; + /// Linked list for the row-major representation. + presolvehlink *rlink_; + //@} + + /// Objective function offset introduced during presolve + double dobias_ ; + + /// Adjust objective function constant offset + inline void change_bias(double change_amount) + { + dobias_ += change_amount ; + # if PRESOLVE_DEBUG > 2 + assert(fabs(change_amount)<1.0e50) ; + if (change_amount) + PRESOLVE_STMT(printf("changing bias by %g to %g\n", + change_amount, dobias_)) ; + # endif + } + + /*! \name Row-major representation + + Common row-major format: A pair of vectors with positional + correspondence to hold coefficients and column indices, and a second pair + of vectors giving the starting position and length of each row in + the first pair. + */ + //@{ + /// Vector of row start positions in #hcol, #rowels_ + CoinBigIndex *mrstrt_; + /// Vector of row lengths + int *hinrow_; + /// Coefficients (positional correspondence with #hcol_) + double *rowels_; + /// Column indices (positional correspondence with #rowels_) + int *hcol_; + //@} + + /// Tracks integrality of columns (1 for integer, 0 for continuous) + unsigned char *integerType_; + /*! \brief Flag to say if any variables are integer + + Note that this flag is <i>not</i> manipulated by the various + \c setVariableType routines. + */ + bool anyInteger_ ; + /// Print statistics for tuning + bool tuning_; + /// Say we want statistics - also set time + void statistics(); + /// Start time of presolve + double startTime_; + + /// Bounds can be moved by this to retain feasibility + double feasibilityTolerance_; + /// Return feasibility tolerance + inline double feasibilityTolerance() + { return (feasibilityTolerance_) ; } + /// Set feasibility tolerance + inline void setFeasibilityTolerance (double val) + { feasibilityTolerance_ = val ; } + + /*! \brief Output status: 0 = feasible, 1 = infeasible, 2 = unbounded + + Actually implemented as single bit flags: 1^0 = infeasible, 1^1 = + unbounded. + */ + int status_; + /// Returns problem status (0 = feasible, 1 = infeasible, 2 = unbounded) + inline int status() + { return (status_) ; } + /// Set problem status + inline void setStatus(int status) + { status_ = (status&0x3) ; } + + /*! \brief Presolve pass number + + Should be incremented externally by the method controlling application of + presolve transforms. + Used to control the execution of testRedundant (evoked by the + implied_free transform). + */ + int pass_; + /// Set pass number + inline void setPass (int pass = 0) + { pass_ = pass ; } + + /*! \brief Maximum substitution level + + Used to control the execution of subst from implied_free + */ + int maxSubstLevel_; + /// Set Maximum substitution level (normally 3) + inline void setMaximumSubstitutionLevel (int level) + { maxSubstLevel_ = level ; } + + + /*! \name Row and column processing status + + Information used to determine if rows or columns can be changed and + if they require further processing due to changes. + + There are four major lists: the [row,col]ToDo list, and the + [row,col]NextToDo list. In general, a transform processes entries from + the ToDo list and adds entries to the NextToDo list. + + There are two vectors, [row,col]Changed, which track the status of + individual rows and columns. + */ + //@{ + /*! \brief Column change status information + + Coded using the following bits: + <ul> + <li> 0x01: Column has changed + <li> 0x02: preprocessing prohibited + <li> 0x04: Column has been used + <li> 0x08: Column originally had infinite ub + </ul> + */ + unsigned char * colChanged_; + /// Input list of columns to process + int * colsToDo_; + /// Length of #colsToDo_ + int numberColsToDo_; + /// Output list of columns to process next + int * nextColsToDo_; + /// Length of #nextColsToDo_ + int numberNextColsToDo_; + + /*! \brief Row change status information + + Coded using the following bits: + <ul> + <li> 0x01: Row has changed + <li> 0x02: preprocessing prohibited + <li> 0x04: Row has been used + </ul> + */ + unsigned char * rowChanged_; + /// Input list of rows to process + int * rowsToDo_; + /// Length of #rowsToDo_ + int numberRowsToDo_; + /// Output list of rows to process next + int * nextRowsToDo_; + /// Length of #nextRowsToDo_ + int numberNextRowsToDo_; + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column tests for integer variables + - 0x02 not used + - 0x04 set to inhibit x+y+z=1 mods + - 0x08 not used + - 0x10 set to allow stuff which won't unroll easily (overlapping + duplicate rows; opportunistic fixing of variables from bound + propagation). + - 0x04000 allow presolve transforms to arbitrarily ignore infeasibility + and set arbitrary feasible bounds. + - 0x10000 instructs implied_free_action to be `more lightweight'; will + return without doing anything after 15 presolve passes. + - 0x(2,4,6)0000 instructs implied_free_action to remove small created elements + - 0x80000000 set by presolve to say dupcol_action compressed columns + */ + int presolveOptions_; + /*! Flag to say if any rows or columns are marked as prohibited + + Note that this flag is <i>not</i> manipulated by any of the + various \c set*Prohibited routines. + */ + bool anyProhibited_; + //@} + + /*! \name Scratch work arrays + + Preallocated work arrays are useful to avoid having to allocate and free + work arrays in individual presolve methods. + + All are allocated from #setMatrix by #initializeStuff, freed from + #~CoinPresolveMatrix. You can use #deleteStuff followed by + #initializeStuff to remove and recreate them. + */ + //@{ + /// Preallocated scratch work array, 3*nrows_ + int *usefulRowInt_ ; + /// Preallocated scratch work array, 2*nrows_ + double *usefulRowDouble_ ; + /// Preallocated scratch work array, 2*ncols_ + int *usefulColumnInt_ ; + /// Preallocated scratch work array, ncols_ + double *usefulColumnDouble_ ; + /// Array of random numbers (max row,column) + double *randomNumber_ ; + + /// Work array for count of infinite contributions to row lhs upper bound + int *infiniteUp_ ; + /// Work array for sum of finite contributions to row lhs upper bound + double *sumUp_ ; + /// Work array for count of infinite contributions to row lhs lower bound + int *infiniteDown_ ; + /// Work array for sum of finite contributions to row lhs lower bound + double *sumDown_ ; + //@} + + /*! \brief Recompute row lhs bounds + + Calculate finite contributions to row lhs upper and lower bounds + and count infinite contributions. Returns the number of rows found + to be infeasible. + + If \p whichRow < 0, bounds are recomputed for all rows. + + As of 110611, this seems to be a work in progress in the sense that it's + barely used by the existing presolve code. + */ + int recomputeSums(int whichRow) ; + + /// Allocate scratch arrays + void initializeStuff() ; + /// Free scratch arrays + void deleteStuff() ; + + /*! \name Functions to manipulate row and column processing status */ + //@{ + + /*! \brief Initialise the column ToDo lists + + Places all columns in the #colsToDo_ list except for columns marked + as prohibited (<i>viz.</i> #colChanged_). + */ + void initColsToDo () ; + + /*! \brief Step column ToDo lists + + Moves columns on the #nextColsToDo_ list to the #colsToDo_ list, emptying + #nextColsToDo_. Returns the number of columns transferred. + */ + int stepColsToDo () ; + + /// Return the number of columns on the #colsToDo_ list + inline int numberColsToDo() + { return (numberColsToDo_) ; } + + /// Has column been changed? + inline bool colChanged(int i) const { + return (colChanged_[i]&1)!=0; + } + /// Mark column as not changed + inline void unsetColChanged(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ; + } + /// Mark column as changed. + inline void setColChanged(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; + } + /// Mark column as changed and add to list of columns to process next + inline void addCol(int i) { + if ((colChanged_[i]&1)==0) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; + nextColsToDo_[numberNextColsToDo_++] = i; + } + } + /// Test if column is eligible for preprocessing + inline bool colProhibited(int i) const { + return (colChanged_[i]&2)!=0; + } + /*! \brief Test if column is eligible for preprocessing + + The difference between this method and #colProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified column. + */ + inline bool colProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (colChanged_[i]&2)!=0; + } + /// Mark column as ineligible for preprocessing + inline void setColProhibited(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ; + } + /*! \brief Test if column is marked as used + + This is for doing faster lookups to see where two columns have entries + in common. + */ + inline bool colUsed(int i) const { + return (colChanged_[i]&4)!=0; + } + /// Mark column as used + inline void setColUsed(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ; + } + /// Mark column as unused + inline void unsetColUsed(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ; + } + /// Has column infinite ub (originally) + inline bool colInfinite(int i) const { + return (colChanged_[i]&8)!=0; + } + /// Mark column as not infinite ub (originally) + inline void unsetColInfinite(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~8)) ; + } + /// Mark column as infinite ub (originally) + inline void setColInfinite(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (8)) ; + } + + /*! \brief Initialise the row ToDo lists + + Places all rows in the #rowsToDo_ list except for rows marked + as prohibited (<i>viz.</i> #rowChanged_). + */ + void initRowsToDo () ; + + /*! \brief Step row ToDo lists + + Moves rows on the #nextRowsToDo_ list to the #rowsToDo_ list, emptying + #nextRowsToDo_. Returns the number of rows transferred. + */ + int stepRowsToDo () ; + + /// Return the number of rows on the #rowsToDo_ list + inline int numberRowsToDo() + { return (numberRowsToDo_) ; } + + /// Has row been changed? + inline bool rowChanged(int i) const { + return (rowChanged_[i]&1)!=0; + } + /// Mark row as not changed + inline void unsetRowChanged(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ; + } + /// Mark row as changed + inline void setRowChanged(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; + } + /// Mark row as changed and add to list of rows to process next + inline void addRow(int i) { + if ((rowChanged_[i]&1)==0) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; + nextRowsToDo_[numberNextRowsToDo_++] = i; + } + } + /// Test if row is eligible for preprocessing + inline bool rowProhibited(int i) const { + return (rowChanged_[i]&2)!=0; + } + /*! \brief Test if row is eligible for preprocessing + + The difference between this method and #rowProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified row. + */ + inline bool rowProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (rowChanged_[i]&2)!=0; + } + /// Mark row as ineligible for preprocessing + inline void setRowProhibited(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ; + } + /*! \brief Test if row is marked as used + + This is for doing faster lookups to see where two rows have entries + in common. It can be used anywhere as long as it ends up zeroed out. + */ + inline bool rowUsed(int i) const { + return (rowChanged_[i]&4)!=0; + } + /// Mark row as used + inline void setRowUsed(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ; + } + /// Mark row as unused + inline void unsetRowUsed(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ; + } + + + /// Check if there are any prohibited rows or columns + inline bool anyProhibited() const + { return anyProhibited_;} + /// Set a flag for presence of prohibited rows or columns + inline void setAnyProhibited(bool val = true) + { anyProhibited_ = val ; } + //@} + +}; + +/*! \class CoinPostsolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during postsolve. + + The notable point is that the matrix representation is threaded. The + representation is column-major and starts with the standard two pairs of + arrays: one pair to hold the row indices and coefficients, the second pair + to hold the column starting positions and lengths. But the row indices and + coefficients for a column do not necessarily occupy a contiguous block in + their respective arrays. Instead, a link array gives the position of the + next (row index,coefficient) pair. If the row index and value of a + coefficient a<p,j> occupy position kp in their arrays, then the position of + the next coefficient a<q,j> is found as kq = link[kp]. + + This threaded representation allows for efficient expansion of columns as + rows are reintroduced during postsolve transformations. The basic packed + structures are allocated to the expected size of the postsolved matrix, + and as new coefficients are added, their location is simply added to the + thread for the column. + + There is no provision to convert the threaded representation to a packed + representation. In the context of postsolve, it's not required. (You did + keep a copy of the original matrix, eh?) + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ +class CoinPostsolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPostsolveMatrix(ClpSimplex * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPostsolveMatrix(OsiSolverInterface * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Load an empty CoinPostsolveMatrix from a CoinPresolveMatrix + + This routine transfers the contents of the CoinPrePostsolveMatrix + object from the CoinPresolveMatrix object to the CoinPostsolveMatrix + object and completes initialisation of the CoinPostsolveMatrix object. + The empty shell of the CoinPresolveMatrix object is destroyed. + + The routine expects an empty CoinPostsolveMatrix object. If handed a loaded + object, a lot of memory will leak. + */ + void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /// Destructor + ~CoinPostsolveMatrix(); + + /*! \name Column thread structures + + As mentioned in the class documentation, the entries for a given column + do not necessarily occupy a contiguous block of space. The #link_ array + is used to maintain the threading. There is one thread for each column, + and a single thread for all free entries in #hrow_ and #colels_. + + The allocated size of #link_ must be at least as large as the allocated + size of #hrow_ and #colels_. + */ + //@{ + + /*! \brief First entry in free entries thread */ + CoinBigIndex free_list_; + /// Allocated size of #link_ + int maxlink_; + /*! \brief Thread array + + Within a thread, link_[k] points to the next entry in the thread. + */ + CoinBigIndex *link_; + + //@} + + /*! \name Debugging aids + + These arrays are allocated only when CoinPresolve is compiled with + PRESOLVE_DEBUG defined. They hold codes which track the reason that + a column or row is added to the problem during postsolve. + */ + //@{ + char *cdone_; + char *rdone_; + //@} + + /// debug + void check_nbasic(); + +}; + + +/*! \defgroup MtxManip Presolve Matrix Manipulation Functions + + Functions to work with the loosely packed and threaded packed matrix + structures used during presolve and postsolve. +*/ +//@{ + +/*! \relates CoinPrePostsolveMatrix + \brief Initialise linked list for major vector order in bulk storage +*/ + +void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths, + presolvehlink *link, int n); + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a major-dimension vector k has room for one more + coefficient. + + You can use this directly, or use the inline wrappers presolve_expand_col + and presolve_expand_row +*/ +bool presolve_expand_major(CoinBigIndex *majstrts, double *majels, + int *minndxs, int *majlens, + presolvehlink *majlinks, int nmaj, int k) ; + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a column (colx) in a column-major matrix has room for + one more coefficient +*/ + +inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels, + int *hrow, int *hincol, + presolvehlink *clink, int ncols, int colx) +{ return presolve_expand_major(mcstrt,colels, + hrow,hincol,clink,ncols,colx) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a row (rowx) in a row-major matrix has room for one + more coefficient +*/ + +inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels, + int *hcol, int *hinrow, + presolvehlink *rlink, int nrows, int rowx) +{ return presolve_expand_major(mrstrt,rowels, + hcol,hinrow,rlink,nrows,rowx) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrappers presolve_find_row and + presolve_find_col. +*/ +inline CoinBigIndex presolve_find_minor(int tgt, + CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs) +{ CoinBigIndex k ; + for (k = ks ; k < ke ; k++) +#ifndef NDEBUG + { if (minndxs[k] == tgt) + return (k) ; } + DIE("FIND_MINOR") ; + + abort () ; return -1; +#else + { if (minndxs[k] == tgt) + break ; } + return (k) ; +#endif +} + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor(row,kcs,kce,hrow) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor(col,krs,kre,hcol) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. A return value of \p ke means the entry does not + exist. Can be used directly or via the inline wrappers + presolve_find_row1 and presolve_find_col1. +*/ +CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs); + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + A return value of \p kce means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor1(row,kcs,kce,hrow) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + A return value of \p kre means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor1(col,krs,kre,hcol) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrapper presolve_find_row2. +*/ +CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will return -1 if the entry does not exist. + Can be used directly or via the inline wrappers presolve_find_row3. +*/ +CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will return -1 if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for a minor index from a major vector. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index + (\p minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_major(int majndx, int minndx, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + + const CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ; + + minndxs[kmi] = minndxs[ke-1] ; + els[kmi] = els[ke-1] ; + majlens[majndx]-- ; + + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete marked entries + + Removes the entries specified in \p marked, compressing the major vector + to maintain loose packing. \p marked is cleared in the process. +*/ +inline void presolve_delete_many_from_major(int majndx, char *marked, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + CoinBigIndex put = ks ; + for (CoinBigIndex k = ks ; k < ke ; k++) { + int iMinor = minndxs[k] ; + if (!marked[iMinor]) { + minndxs[put] = iMinor ; + els[put++] = els[k] ; + } else { + marked[iMinor] = 0 ; + } + } + majlens[majndx] = put-ks ; + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_col(int row, int col, + const CoinBigIndex *mcstrt, + int *hincol, int *hrow, double *colels) +{ presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for column \p col from row \p row in a + row-major matrix + + Deletes the entry for \p col from the major vector for \p row. + Specifically, the relevant entries are removed from the column index (\p + hcol) and coefficient (\p rowels) arrays and the vector length (\p + hinrow) is decremented. Loose packing is maintained by swapping the last + entry in the column into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_row(int row, int col, + const CoinBigIndex *mrstrt, + int *hinrow, int *hcol, double *rowels) +{ presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; } + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for a minor index from a major vector in a + threaded matrix. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index (\p + minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +void presolve_delete_from_major2 (int majndx, int minndx, + CoinBigIndex *majstrts, int *majlens, + int *minndxs, int *majlinks, + CoinBigIndex *free_listp) ; + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major threaded matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt, + int *hincol, int *hrow, + int *clinks, CoinBigIndex *free_listp) +{ presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,free_listp) ; } + +//@} + +/*! \defgroup PresolveUtilities Presolve Utility Functions + + Utilities used by multiple presolve transform objects. +*/ +//@{ + +/*! \brief Duplicate a major-dimension vector; optionally omit the entry + with minor index \p tgt. + + Designed to copy a major-dimension vector from the paired coefficient + (\p elems) and minor index (\p indices) arrays used in the standard + packed matrix representation. Copies \p length entries starting at + \p offset. + + If \p tgt is specified, the entry with minor index == \p tgt is + omitted from the copy. +*/ +double *presolve_dupmajor(const double *elems, const int *indices, + int length, CoinBigIndex offset, int tgt = -1); + +/// Initialize a vector with random numbers +void coin_init_random_vec(double *work, int n); + +//@} + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveMonitor.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveMonitor.hpp new file mode 100644 index 0000000..cef7a41 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveMonitor.hpp @@ -0,0 +1,105 @@ + +#ifndef CoinPresolveMonitor_H +#define CoinPresolveMonitor_H + +/*! + \brief Monitor a row or column for modification + + The purpose of this class is to monitor a row or column for modifications + during presolve and postsolve. Each object can monitor one row or + column. The initial copy of the row or column is loaded by the constructor. + Each subsequent call to checkAndTell() compares the current state of the row + or column with the stored state and reports any modifications. + + Internally the row or column is held as a CoinPackedVector so that it's + possible to follow a row or column through presolve (CoinPresolveMatrix) + and postsolve (CoinPostsolveMatrix). + + Do not underestimate the amount of work required here. Extracting a row from + the CoinPostsolve matrix requires a scan of every element in the matrix. + That's one scan by the constructor and one scan with every call to modify. + But that's precisely why it's virtually impossible to debug presolve without + aids. + + Parameter overloads for CoinPresolveMatrix and CoinPostsolveMatrix are a + little clumsy, but not a problem in use. The alternative is to add methods + to the CoinPresolveMatrix and CoinPostsolveMatrix classes that will only be + used for debugging. That's not too attractive either. +*/ +class CoinPresolveMonitor +{ + public: + + /*! \brief Default constructor + + Creates an empty monitor. + */ + CoinPresolveMonitor() ; + + /*! \brief Initialise from a CoinPresolveMatrix + + Load the initial row or column from a CoinPresolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPresolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Initialise from a CoinPostsolveMatrix + + Load the initial row or column from a CoinPostsolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPostsolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPresolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPresolveMatrix *mtx) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPostsolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPostsolveMatrix *mtx) ; + + private: + + /// Extract a row from a CoinPresolveMatrix + CoinPackedVector *extractRow(int i, const CoinPresolveMatrix *mtx) const ; + + /// Extract a column from a CoinPresolveMatrix + CoinPackedVector *extractCol(int j, const CoinPresolveMatrix *mtx) const ; + + /// Extract a row from a CoinPostsolveMatrix + CoinPackedVector *extractRow(int i, const CoinPostsolveMatrix *mtx) const ; + + /// Extract a column from a CoinPostsolveMatrix + CoinPackedVector *extractCol(int j, const CoinPostsolveMatrix *mtx) const ; + + /// Worker method underlying the public checkAndTell methods. + void checkAndTell(CoinPackedVector *curVec, double lb, double ub) ; + + /// True to monitor a row, false to monitor a column + bool isRow_ ; + + /// Row or column index + int ndx_ ; + + /*! The original row or column + + Sorted in increasing order of indices. + */ + CoinPackedVector *origVec_ ; + + /// Original row or column lower bound + double lb_ ; + + /// Original row or column upper bound + double ub_ ; +} ; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolvePsdebug.hpp b/thirdparty/linux/include/coin/coin/CoinPresolvePsdebug.hpp new file mode 100644 index 0000000..445278e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolvePsdebug.hpp @@ -0,0 +1,169 @@ +/* $Id: CoinPresolvePsdebug.hpp 1854 2015-12-18 14:18:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolvePsdebug_H +#define CoinPresolvePsdebug_H + +/* + The current idea of the relation between PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY is that PRESOLVE_CONSISTENCY triggers the consistency + checks and PRESOLVE_DEBUG triggers consistency checks and output. + This isn't always true in the code, but that's the goal. Really, + the whole compile-time scheme should be replaced with something more + user-friendly (control variables that can be changed during the run). + + Also floating about are PRESOLVE_SUMMARY and COIN_PRESOLVE_TUNING. + -- lh, 111208 -- +*/ +/*! \defgroup PresolveDebugFunctions Presolve Debug Functions + + These functions implement consistency checks on data structures involved + in presolve and postsolve and on the components of the lp solution. + + To use these functions, include CoinPresolvePsdebug.hpp in your file and + define the compile-time constants PRESOLVE_SUMMARY, PRESOLVE_DEBUG, and + PRESOLVE_CONSISTENCY. A value is needed (<i>i.e.</i>, PRESOLVE_DEBUG=1). + In a few places, higher values will get you a bit more output. + + ******** + + Define the symbols PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure + command line (use ADD_CXXFLAGS), in a Makefile, or similar and do a full + rebuild (including any presolve driver code). If the symbols are not + consistently nonzero across *all* presolve code, you'll get something + between garbage and a core dump! Debugging adds messages to CoinMessage + and allocates and maintains arrays that hold debug information. + + That said, given that you've configured and built with PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY nonzero everywhere, it's safe to adjust PRESOLVE_DEBUG + to values in the range 1..n in individual files to increase or decrease the + amount of output. + + The suggested approach for PRESOLVE_DEBUG is to define it to 1 in the build + and then increase it in individual presolve code files to get more detail. + + ******** +*/ +//@{ + +/*! \relates CoinPresolveMatrix + \brief Check column-major and/or row-major matrices for duplicate + entries in the major vectors. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_dups(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check the links which track storage order for major vectors in + the bulk storage area. + + By default, scans both the column- and row-major matrix. Set doCol = false to + suppress the column-major scan. Set doRow = false to suppres the row-major + scan. +*/ +void presolve_links_ok(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check for explicit zeros in the column- and/or row-major matrices. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_zeros(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Checks for equivalence of the column- and row-major matrices. + + Normally the routine will test for coefficient presence and value. Set + \p chkvals to false to suppress the check for equal value. +*/ +void presolve_consistent(const CoinPresolveMatrix *preObj, + bool chkvals = true) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks that column threads agree with column lengths +*/ +void presolve_check_threads(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks the free list + + Scans the thread of free locations in the bulk store and checks that all + entries are reasonable (0 <= index < bulk0_). If chkElemCnt is true, it + also checks that the total number of entries in the matrix plus the + locations on the free list total to the size of the bulk store. Postsolve + routines do not maintain an accurate element count, but this is useful + for checking a newly constructed postsolve matrix. +*/ +void presolve_check_free_list(const CoinPostsolveMatrix *obj, + bool chkElemCnt = false) ; + +/*! \relates CoinPostsolveMatrix + \brief Check stored reduced costs for accuracy and consistency with + variable status. + + The routine will check the value of the reduced costs for architectural + variables (CoinPrePostsolveMatrix::rcosts_). It performs an accuracy check + by recalculating the reduced cost from scratch. It will also check the + value for consistency with the status information in + CoinPrePostsolveMatrix::colstat_. +*/ +void presolve_check_reduced_costs(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check the dual variables for consistency with row activity. + + The routine checks that the value of the dual variable is consistent + with the state of the constraint (loose, tight at lower bound, or tight at + upper bound). +*/ +void presolve_check_duals(const CoinPostsolveMatrix *postObj) ; + +/*! \relates CoinPresolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. By default, row activity is not checked (presolve is + sloppy about maintaining it). See the definitions in + CoinPresolvePsdebug.cpp for more information. +*/ +void presolve_check_sol(const CoinPresolveMatrix *preObj, + int chkColSol = 2, int chkRowAct = 1, + int chkStatus = 1) ; + +/*! \relates CoinPostsolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. See the definitions in CoinPresolvePsdebug.cpp for more + information. +*/ +void presolve_check_sol(const CoinPostsolveMatrix *postObj, + int chkColSol = 2, int chkRowAct = 2, + int chkStatus = 1) ; + +/*! \relates CoinPresolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPresolveMatrix *preObj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPostsolveMatrix *postObj) ; + +/// get a row copy in postsolve +void postsolve_get_rowcopy(const CoinPostsolveMatrix *postObj, + int * & rowStarts, int * & columns, double * & elements ) ; +//@} + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveSingleton.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveSingleton.hpp new file mode 100644 index 0000000..10bc1cc --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveSingleton.hpp @@ -0,0 +1,112 @@ +/* $Id: CoinPresolveSingleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSingleton_H +#define CoinPresolveSingleton_H +#define SLACK_DOUBLETON 2 +#define SLACK_SINGLETON 8 + +/*! + \file +*/ + +//const int MAX_SLACK_DOUBLETONS = 1000; + +/*! \class slack_doubleton_action + \brief Convert an explicit bound constraint to a column bound + + This transform looks for explicit bound constraints for a variable and + transfers the bound to the appropriate column bound array. + The constraint is removed from the constraint system. +*/ +class slack_doubleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_doubleton_action"); } + + /*! \brief Convert explicit bound constraints to column bounds. + + Not now There is a hard limit (#MAX_SLACK_DOUBLETONS) on the number of + constraints processed in a given call. \p notFinished is set to true + if candidates remain. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + bool ¬Finished); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_doubleton_action() { deleteAction(actions_,action*); } +}; +/*! \class slack_singleton_action + \brief For variables with one entry + + If we have a variable with one entry and no cost then we can + transform the row from E to G etc. + If there is a row objective region then we may be able to do + this even with a cost. +*/ +class slack_singleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_singleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_singleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + double * rowObjective); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_singleton_action() { deleteAction(actions_,action*); } +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveSubst.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveSubst.hpp new file mode 100644 index 0000000..93822a5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveSubst.hpp @@ -0,0 +1,101 @@ +/* $Id: CoinPresolveSubst.hpp 1562 2012-11-24 00:36:15Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSubst_H +#define CoinPresolveSubst_H + +/*! + \file +*/ + +#define SUBST_ROW 21 + +#include "CoinPresolveMatrix.hpp" + +/*! \class subst_constraint_action + \brief Detect and process implied free variables + + Consider a variable x. Suppose that we can find an equality such that the + bound on the equality, combined with + the bounds on the other variables involved in the equality, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. By solving + the equality for x and substituting for x in every other constraint + entangled with x, we can make x into a column singleton. Now x is an implied + free column singleton and both x and the equality can be removed. + + A similar transform for the case where the variable is a natural column + singleton is handled by #implied_free_action. In the current presolve + architecture, #implied_free_action is responsible for detecting implied free + variables that are natural column singletons or can be reduced to column + singletons. #implied_free_action calls subst_constraint_action to process + variables that must be reduced to column singletons. +*/ +class subst_constraint_action : public CoinPresolveAction { +private: + subst_constraint_action(); + subst_constraint_action(const subst_constraint_action& rhs); + subst_constraint_action& operator=(const subst_constraint_action& rhs); + + struct action { + double *rlos; + double *rups; + + double *coeffxs; + int *rows; + + int *ninrowxs; + int *rowcolsxs; + double *rowelsxs; + + const double *costsx; + int col; + int rowy; + + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + subst_constraint_action(int nactions, + action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *implied_free, + const int * which, + int numberFree, + const CoinPresolveAction *next, + int fill_level); + static const CoinPresolveAction *presolveX(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~subst_constraint_action(); +}; + + + + + +/*static*/ void implied_bounds(const double *els, + const double *clo, const double *cup, + const int *hcol, + CoinBigIndex krs, CoinBigIndex kre, + double *maxupp, double *maxdownp, + int jcol, + double rlo, double rup, + double *iclb, double *icub); +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveTighten.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveTighten.hpp new file mode 100644 index 0000000..3a5319b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveTighten.hpp @@ -0,0 +1,55 @@ +/* $Id: CoinPresolveTighten.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTighten_H +#define CoinPresolveTighten_H + +#include "CoinPresolveMatrix.hpp" + +// This action has no separate class; +// instead, it decides which columns can be made fixed +// and calls make_fixed_action::presolve. +const CoinPresolveAction *tighten_zero_cost(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#define DO_TIGHTEN 30 + +class do_tighten_action : public CoinPresolveAction { + do_tighten_action(); + do_tighten_action(const do_tighten_action& rhs); + do_tighten_action& operator=(const do_tighten_action& rhs); + + struct action { + int *rows; + double *lbound; + double *ubound; + int col; + int nrows; + int direction; // just for assertions + }; + + const int nactions_; + const action *const actions_; + + do_tighten_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~do_tighten_action(); + +}; +#endif + + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveTripleton.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveTripleton.hpp new file mode 100644 index 0000000..eaa79c5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveTripleton.hpp @@ -0,0 +1,66 @@ +/* $Id: CoinPresolveTripleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTripleton_H +#define CoinPresolveTripleton_H +#define TRIPLETON 11 +/** We are only going to do this if it does not increase number of elements?. + It could be generalized to more than three but it seems unlikely it would + help. + + As it is adapted from doubleton icoly is one dropped. + */ +class tripleton_action : public CoinPresolveAction { + public: + struct action { + int icolx; + int icolz; + int row; + + int icoly; + double cloy; + double cupy; + double costy; + double clox; + double cupx; + double costx; + + double rlo; + double rup; + + double coeffx; + double coeffy; + double coeffz; + + double *colel; + + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + tripleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("tripleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~tripleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveUseless.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveUseless.hpp new file mode 100644 index 0000000..624a373 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveUseless.hpp @@ -0,0 +1,63 @@ +/* $Id: CoinPresolveUseless.hpp 1566 2012-11-29 19:33:56Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveUseless_H +#define CoinPresolveUseless_H +#define USELESS 20 + +class useless_constraint_action : public CoinPresolveAction { + struct action { + double rlo; + double rup; + const int *rowcols; + const double *rowels; + int row; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + useless_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next); + + public: + const char *name() const; + + // These rows are asserted to be useless, + // that is, given a solution the row activity + // must be in range. + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *useless_rows, + int nuseless_rows, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~useless_constraint_action(); + +}; + +/*! \relates useless_constraint_action + \brief Scan constraints looking for useless constraints + + A front end to identify useless constraints and hand them to + useless_constraint_action::presolve() for processing. + + In a bit more detail, the routine implements a greedy algorithm that + identifies a set of necessary constraints. A constraint is necessary if it + implies a tighter bound on a variable than the original column bound. These + tighter column bounds are then used to calculate row activity and identify + constraints that are useless given the presence of the necessary + constraints. +*/ + +const CoinPresolveAction *testRedundant(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinPresolveZeros.hpp b/thirdparty/linux/include/coin/coin/CoinPresolveZeros.hpp new file mode 100644 index 0000000..219e613 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinPresolveZeros.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveZeros.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveZeros_H +#define CoinPresolveZeros_H + +/*! \file + + Drop/reintroduce explicit zeros. +*/ + +#define DROP_ZERO 8 + +/*! \brief Tracking information for an explicit zero coefficient + + \todo Why isn't this a nested class in drop_zero_coefficients_action? + That would match the structure of other presolve classes. +*/ + +struct dropped_zero { + int row; + int col; +}; + +/*! \brief Removal of explicit zeros + + The presolve action for this class removes explicit zeros from the constraint + matrix. The postsolve action puts them back. +*/ +class drop_zero_coefficients_action : public CoinPresolveAction { + + const int nzeros_; + const dropped_zero *const zeros_; + + drop_zero_coefficients_action(int nzeros, + const dropped_zero *zeros, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nzeros_(nzeros), zeros_(zeros) +{} + + public: + const char *name() const { return ("drop_zero_coefficients_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *checkcols, + int ncheckcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_zero_coefficients_action() { deleteAction(zeros_,dropped_zero*); } +}; + +const CoinPresolveAction *drop_zero_coefficients(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinRational.hpp b/thirdparty/linux/include/coin/coin/CoinRational.hpp new file mode 100644 index 0000000..bfbfa5f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinRational.hpp @@ -0,0 +1,44 @@ +// Authors: Matthew Saltzman and Ted Ralphs +// Copyright 2015, Matthew Saltzman and Ted Ralphs +// Licensed under the Eclipse Public License 1.0 + +#ifndef CoinRational_H +#define CoinRational_H + +#include <cmath> + +//Small class for rational numbers +class CoinRational +{ + +public : + long getDenominator() { return denominator_; } + long getNumerator() { return numerator_; } + + CoinRational(): + numerator_(0), + denominator_(1) + {}; + + CoinRational(long n, long d): + numerator_(n), + denominator_(d) + {}; + + CoinRational(double val, double maxdelta, long maxdnom) + { + if (!nearestRational_(val, maxdelta, maxdnom)){ + numerator_ = 0; + denominator_ = 1; + } + }; + +private : + + long numerator_; + long denominator_; + + bool nearestRational_(double val, double maxdelta, long maxdnom); +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSearchTree.hpp b/thirdparty/linux/include/coin/coin/CoinSearchTree.hpp new file mode 100644 index 0000000..f7c101d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSearchTree.hpp @@ -0,0 +1,465 @@ +/* $Id: CoinSearchTree.hpp 1824 2015-04-04 16:27:28Z tkr $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSearchTree_H +#define CoinSearchTree_H + +#include <vector> +#include <algorithm> +#include <cmath> +#include <string> + +#include "CoinFinite.hpp" +#include "CoinHelperFunctions.hpp" + +// #define DEBUG_PRINT + +//############################################################################# + +class BitVector128 { + friend bool operator<(const BitVector128& b0, const BitVector128& b1); +private: + unsigned int bits_[4]; +public: + BitVector128(); + BitVector128(unsigned int bits[4]); + ~BitVector128() {} + void set(unsigned int bits[4]); + void setBit(int i); + void clearBit(int i); + std::string str() const; +}; + +bool operator<(const BitVector128& b0, const BitVector128& b1); + +//############################################################################# + +/** A class from which the real tree nodes should be derived from. Some of the + data that undoubtedly exist in the real tree node is replicated here for + fast access. This class is used in the various comparison functions. */ +class CoinTreeNode { +protected: + CoinTreeNode() : + depth_(-1), + fractionality_(-1), + quality_(-COIN_DBL_MAX), + true_lower_bound_(-COIN_DBL_MAX), + preferred_() {} + CoinTreeNode(int d, + int f = -1, + double q = -COIN_DBL_MAX, + double tlb = -COIN_DBL_MAX, + BitVector128 p = BitVector128()) : + depth_(d), + fractionality_(f), + quality_(q), + true_lower_bound_(tlb), + preferred_(p) {} + CoinTreeNode(const CoinTreeNode& x) : + depth_(x.depth_), + fractionality_(x.fractionality_), + quality_(x.quality_), + true_lower_bound_(x.true_lower_bound_), + preferred_(x.preferred_) {} + CoinTreeNode& operator=(const CoinTreeNode& x) { + if (this != &x) { + depth_ = x.depth_; + fractionality_ = x.fractionality_; + quality_ = x.quality_; + true_lower_bound_ = x.true_lower_bound_; + preferred_ = x.preferred_; + } + return *this; + } +private: + /// The depth of the node in the tree + int depth_; + /** A measure of fractionality, e.g., the number of unsatisfied + integrality requirements */ + int fractionality_; + /** Some quality for the node. For normal branch-and-cut problems the LP + relaxation value will do just fine. It is probably an OK approximation + even if column generation is done. */ + double quality_; + /** A true lower bound on the node. May be -infinity. For normal + branch-and-cut problems the LP relaxation value is OK. It is different + when column generation is done. */ + double true_lower_bound_; + /** */ + BitVector128 preferred_; +public: + virtual ~CoinTreeNode() {} + + inline int getDepth() const { return depth_; } + inline int getFractionality() const { return fractionality_; } + inline double getQuality() const { return quality_; } + inline double getTrueLB() const { return true_lower_bound_; } + inline BitVector128 getPreferred() const { return preferred_; } + + inline void setDepth(int d) { depth_ = d; } + inline void setFractionality(int f) { fractionality_ = f; } + inline void setQuality(double q) { quality_ = q; } + inline void setTrueLB(double tlb) { true_lower_bound_ = tlb; } + inline void setPreferred(BitVector128 p) { preferred_ = p; } +}; + +//============================================================================== + +class CoinTreeSiblings { +private: + CoinTreeSiblings(); + CoinTreeSiblings& operator=(const CoinTreeSiblings&); +private: + int current_; + int numSiblings_; + CoinTreeNode** siblings_; +public: + CoinTreeSiblings(const int n, CoinTreeNode** nodes) : + current_(0), numSiblings_(n), siblings_(new CoinTreeNode*[n]) + { + CoinDisjointCopyN(nodes, n, siblings_); + } + CoinTreeSiblings(const CoinTreeSiblings& s) : + current_(s.current_), + numSiblings_(s.numSiblings_), + siblings_(new CoinTreeNode*[s.numSiblings_]) + { + CoinDisjointCopyN(s.siblings_, s.numSiblings_, siblings_); + } + ~CoinTreeSiblings() { delete[] siblings_; } + inline CoinTreeNode* currentNode() const { return siblings_[current_]; } + /** returns false if cannot be advanced */ + inline bool advanceNode() { return ++current_ != numSiblings_; } + inline int toProcess() const { return numSiblings_ - current_; } + inline int size() const { return numSiblings_; } + inline void printPref() const { + for (int i = 0; i < numSiblings_; ++i) { + std::string pref = siblings_[i]->getPreferred().str(); + printf("prefs of sibligs: sibling[%i]: %s\n", i, pref.c_str()); + } + } +}; + +//############################################################################# + +/** Function objects to compare search tree nodes. The comparison function + must return true if the first argument is "better" than the second one, + i.e., it should be processed first. */ +/*@{*/ +/** Depth First Search. */ +struct CoinSearchTreeComparePreferred { + static inline const char* name() { return "CoinSearchTreeComparePreferred"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + register const CoinTreeNode* xNode = x->currentNode(); + register const CoinTreeNode* yNode = y->currentNode(); + const BitVector128 xPref = xNode->getPreferred(); + const BitVector128 yPref = yNode->getPreferred(); + bool retval = true; + if (xPref < yPref) { + retval = true; + } else if (yPref < xPref) { + retval = false; + } else { + retval = xNode->getQuality() < yNode->getQuality(); + } +#ifdef DEBUG_PRINT + printf("Comparing xpref (%s) and ypref (%s) : %s\n", + xpref.str().c_str(), ypref.str().c_str(), retval ? "T" : "F"); +#endif + return retval; + } +}; + +//----------------------------------------------------------------------------- +/** Depth First Search. */ +struct CoinSearchTreeCompareDepth { + static inline const char* name() { return "CoinSearchTreeCompareDepth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { +#if 1 + return x->currentNode()->getDepth() >= y->currentNode()->getDepth(); +#else + if(x->currentNode()->getDepth() > y->currentNode()->getDepth()) + return 1; + if(x->currentNode()->getDepth() == y->currentNode()->getDepth() && + x->currentNode()->getQuality() <= y->currentNode()->getQuality()) + return 1; + return 0; +#endif + } +}; + +//----------------------------------------------------------------------------- +/* Breadth First Search */ +struct CoinSearchTreeCompareBreadth { + static inline const char* name() { return "CoinSearchTreeCompareBreadth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getDepth() < y->currentNode()->getDepth(); + } +}; + +//----------------------------------------------------------------------------- +/** Best first search */ +struct CoinSearchTreeCompareBest { + static inline const char* name() { return "CoinSearchTreeCompareBest"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getQuality() < y->currentNode()->getQuality(); + } +}; + +//############################################################################# + +class CoinSearchTreeBase +{ +private: + CoinSearchTreeBase(const CoinSearchTreeBase&); + CoinSearchTreeBase& operator=(const CoinSearchTreeBase&); + +protected: + std::vector<CoinTreeSiblings*> candidateList_; + int numInserted_; + int size_; + +protected: + CoinSearchTreeBase() : candidateList_(), numInserted_(0), size_(0) {} + + virtual void realpop() = 0; + virtual void realpush(CoinTreeSiblings* s) = 0; + virtual void fixTop() = 0; + +public: + virtual ~CoinSearchTreeBase() {} + virtual const char* compName() const = 0; + + inline const std::vector<CoinTreeSiblings*>& getCandidates() const { + return candidateList_; + } + inline bool empty() const { return candidateList_.empty(); } + inline int size() const { return size_; } + inline int numInserted() const { return numInserted_; } + inline CoinTreeNode* top() const { + if (size_ == 0 || candidateList_.size() == 0) + return NULL; +#ifdef DEBUG_PRINT + char output[44]; + output[43] = 0; + candidateList_.front()->currentNode()->getPreferred().print(output); + printf("top's pref: %s\n", output); +#endif + return candidateList_.front()->currentNode(); + } + /** pop will advance the \c next pointer among the siblings on the top and + then moves the top to its correct position. #realpop is the method + that actually removes the element from the heap */ + inline void pop() { + CoinTreeSiblings* s = candidateList_.front(); + if (!s->advanceNode()) { + realpop(); + delete s; + } else { + fixTop(); + } + --size_; + } + inline void push(int numNodes, CoinTreeNode** nodes, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(numNodes, nodes); + realpush(s); + if (incrInserted) { + numInserted_ += numNodes; + } + size_ += numNodes; + } + inline void push(const CoinTreeSiblings& sib, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(sib); +#ifdef DEBUG_PRINT + s->printPref(); +#endif + realpush(s); + if (incrInserted) { + numInserted_ += sib.toProcess(); + } + size_ += sib.toProcess(); + } +}; + +//############################################################################# + +// #define CAN_TRUST_STL_HEAP +#ifdef CAN_TRUST_STL_HEAP + +template <class Comp> +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; +protected: + virtual void realpop() { + candidateList_.pop_back(); + } + virtual void fixTop() { + CoinTreeSiblings* s = top(); + realpop(); + push(s, false); + } + virtual void realpush(CoinTreeSiblings* s) { + nodes_.push_back(s); + std::push_heap(candidateList_.begin(), candidateList_.end(), comp_); + } +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::make_heap(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted_; + size_ = t.size_; + } + ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#else + +template <class Comp> +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; + +protected: + virtual void realpop() { + candidateList_[0] = candidateList_.back(); + candidateList_.pop_back(); + fixTop(); + } + /** After changing data in the top node, fix the heap */ + virtual void fixTop() { + const size_t size = candidateList_.size(); + if (size > 1) { + CoinTreeSiblings** candidates = &candidateList_[0]; + CoinTreeSiblings* s = candidates[0]; + --candidates; + size_t pos = 1; + size_t ch; + for (ch = 2; ch < size; pos = ch, ch *= 2) { + if (comp_(candidates[ch+1], candidates[ch])) + ++ch; + if (comp_(s, candidates[ch])) + break; + candidates[pos] = candidates[ch]; + } + if (ch == size) { + if (comp_(candidates[ch], s)) { + candidates[pos] = candidates[ch]; + pos = ch; + } + } + candidates[pos] = s; + } + } + virtual void realpush(CoinTreeSiblings* s) { + candidateList_.push_back(s); + CoinTreeSiblings** candidates = &candidateList_[0]; + --candidates; + size_t pos = candidateList_.size(); + size_t ch; + for (ch = pos/2; ch != 0; pos = ch, ch /= 2) { + if (comp_(candidates[ch], s)) + break; + candidates[pos] = candidates[ch]; + } + candidates[pos] = s; + } + +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::sort(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted(); + size_ = t.size(); + } + virtual ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#endif + +//############################################################################# + +enum CoinNodeAction { + CoinAddNodeToCandidates, + CoinTestNodeForDiving, + CoinDiveIntoNode +}; + +class CoinSearchTreeManager +{ +private: + CoinSearchTreeManager(const CoinSearchTreeManager&); + CoinSearchTreeManager& operator=(const CoinSearchTreeManager&); +private: + CoinSearchTreeBase* candidates_; + int numSolution; + /** Whether there is an upper bound or not. The upper bound may have come + as input, not necessarily from a solution */ + bool hasUB_; + + /** variable used to test whether we need to reevaluate search strategy */ + bool recentlyReevaluatedSearchStrategy_; + +public: + CoinSearchTreeManager() : + candidates_(NULL), + numSolution(0), + recentlyReevaluatedSearchStrategy_(true) + {} + virtual ~CoinSearchTreeManager() { + delete candidates_; + } + + inline void setTree(CoinSearchTreeBase* t) { + delete candidates_; + candidates_ = t; + } + inline CoinSearchTreeBase* getTree() const { + return candidates_; + } + + inline bool empty() const { return candidates_->empty(); } + inline size_t size() const { return candidates_->size(); } + inline size_t numInserted() const { return candidates_->numInserted(); } + inline CoinTreeNode* top() const { return candidates_->top(); } + inline void pop() { candidates_->pop(); } + inline void push(CoinTreeNode* node, const bool incrInserted = true) { + candidates_->push(1, &node, incrInserted); + } + inline void push(const CoinTreeSiblings& s, const bool incrInserted=true) { + candidates_->push(s, incrInserted); + } + inline void push(const int n, CoinTreeNode** nodes, + const bool incrInserted = true) { + candidates_->push(n, nodes, incrInserted); + } + + inline CoinTreeNode* bestQualityCandidate() const { + return candidates_->top(); + } + inline double bestQuality() const { + return candidates_->top()->getQuality(); + } + void newSolution(double solValue); + void reevaluateSearchStrategy(); +}; + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinShallowPackedVector.hpp b/thirdparty/linux/include/coin/coin/CoinShallowPackedVector.hpp new file mode 100644 index 0000000..07c1870 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinShallowPackedVector.hpp @@ -0,0 +1,148 @@ +/* $Id: CoinShallowPackedVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinShallowPackedVector_H +#define CoinShallowPackedVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include "CoinError.hpp" +#include "CoinPackedVectorBase.hpp" + +/** Shallow Sparse Vector + +This class is for sparse vectors where the indices and +elements are stored elsewhere. This class only maintains +pointers to the indices and elements. Since this class +does not own the index and element data it provides +read only access to to the data. An CoinSparsePackedVector +must be used when the sparse vector's data will be altered. + +This class stores pointers to the vectors. +It does not actually contain the vectors. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 }; + double el[ne] = { 10., 40., 1., 50. }; + + // Create vector and set its value + CoinShallowPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinShallowPackedVector r1; + r1=r; + assert( r==r1 ); + r.sort(CoinIncrElementOrdered()); + assert( r!=r1 ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinShallowPackedVector : public CoinPackedVectorBase { + friend void CoinShallowPackedVectorUnitTest(); + +public: + + /**@name Get methods */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + //@} + + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator. */ + CoinShallowPackedVector& operator=(const CoinShallowPackedVector & x); + /** Assignment operator from a CoinPackedVectorBase. */ + CoinShallowPackedVector& operator=(const CoinPackedVectorBase & x); + /** just like the explicit constructor */ + void setVector(int size, const int * indices, const double * elements, + bool testForDuplicateIndex = true); + //@} + + /**@name Methods to create, set and destroy */ + //@{ + /** Default constructor. */ + CoinShallowPackedVector(bool testForDuplicateIndex = true); + /** Explicit Constructor. + Set vector size, indices, and elements. Size is the length of both the + indices and elements vectors. The indices and elements vectors are not + copied into this class instance. The ShallowPackedVector only maintains + the pointers to the indices and elements vectors. <br> + The last argument specifies whether the creator of the object knows in + advance that there are no duplicate indices. + */ + CoinShallowPackedVector(int size, + const int * indices, const double * elements, + bool testForDuplicateIndex = true); + /** Copy constructor from the base class. */ + CoinShallowPackedVector(const CoinPackedVectorBase &); + /** Copy constructor. */ + CoinShallowPackedVector(const CoinShallowPackedVector &); + /** Destructor. */ + virtual ~CoinShallowPackedVector() {} + /// Print vector information. + void print(); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + const int * indices_; + ///Vector elements + const double * elements_; + /// Size of indices and elements vectors + int nElements_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinShallowPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinShallowPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSignal.hpp b/thirdparty/linux/include/coin/coin/CoinSignal.hpp new file mode 100644 index 0000000..2bbf0d0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSignal.hpp @@ -0,0 +1,117 @@ +/* $Id: CoinSignal.hpp 1810 2015-03-13 20:16:34Z tkr $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinSignal_hpp +#define _CoinSignal_hpp + +// This file is fully docified. +// There's nothing to docify... + +//############################################################################# + +#include <csignal> + +//############################################################################# + +#if defined(_MSC_VER) + typedef void (__cdecl *CoinSighandler_t) (int); +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if (defined(__GNUC__) && defined(__linux__)) + typedef sighandler_t CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MINGW32__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__FreeBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__NetBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(_AIX) +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined (__hpux) +# define CoinSighandler_t_defined +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# else + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__sun) +# if defined(__SUNPRO_CC) +# include <signal.h> + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# define CoinSighandler_t_defined +# endif +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MACH__) && defined(__GNUC__) +typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//############################################################################# + +#ifndef CoinSighandler_t_defined +# warning("OS and/or compiler is not recognized. Defaulting to:"); +# warning("extern 'C' {") +# warning(" typedef void (*CoinSighandler_t) (int);") +# warning("}") + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSimpFactorization.hpp b/thirdparty/linux/include/coin/coin/CoinSimpFactorization.hpp new file mode 100644 index 0000000..242b6cd --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSimpFactorization.hpp @@ -0,0 +1,431 @@ +/* $Id: CoinSimpFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + This is a simple factorization of the LP Basis + */ +#ifndef CoinSimpFactorization_H +#define CoinSimpFactorization_H + +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; + + +/// pointers used during factorization +class FactorPointers{ +public: + double *rowMax; + int *firstRowKnonzeros; + int *prevRow; + int *nextRow; + int *firstColKnonzeros; + int *prevColumn; + int *nextColumn; + int *newCols; + //constructor + FactorPointers( int numRows, int numCols, int *UrowLengths_, int *UcolLengths_ ); + // destructor + ~ FactorPointers(); +}; + +class CoinSimpFactorization : public CoinOtherFactorization { + friend void CoinSimpFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinSimpFactorization ( ); + /// Copy constructor + CoinSimpFactorization ( const CoinSimpFactorization &other); + + /// Destructor + virtual ~CoinSimpFactorization ( ); + /// = copy + CoinSimpFactorization & operator = ( const CoinSimpFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as status */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /// does updatecolumn if save==true keeps column for replace column + int upColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false, bool save=false) const; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /// does updateColumnTranspose, the other is a wrapper + int upColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + inline int * indices() const + { return reinterpret_cast<int *> (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return pivotRow_;} + //@} + + /// The real work of destructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinSimpFactorization &other); + + + /// calls factorization + void factorize(int numberOfRows, + int numberOfColumns, + const int colStarts[], + const int indicesRow[], + const double elements[]); + /// main loop of factorization + int mainLoopFactor (FactorPointers &pointers ); + /// copies L by rows + void copyLbyRows(); + /// copies U by columns + void copyUbyColumns(); + /// finds a pivot element using Markowitz count + int findPivot(FactorPointers &pointers, int &r, int &s, bool &ifSlack); + /// finds a pivot in a shortest column + int findPivotShCol(FactorPointers &pointers, int &r, int &s); + /// finds a pivot in the first column available + int findPivotSimp(FactorPointers &pointers, int &r, int &s); + /// does Gauss elimination + void GaussEliminate(FactorPointers &pointers, int &r, int &s); + /// finds short row that intersects a given column + int findShortRow(const int column, const int length, int &minRow, + int &minRowLength, FactorPointers &pointers); + /// finds short column that intersects a given row + int findShortColumn(const int row, const int length, int &minCol, + int &minColLength, FactorPointers &pointers); + /// finds maximum absolute value in a row + double findMaxInRrow(const int row, FactorPointers &pointers); + /// does pivoting + void pivoting(const int pivotRow, const int pivotColumn, + const double invPivot, FactorPointers &pointers); + /// part of pivoting + void updateCurrentRow(const int pivotRow, const int row, + const double multiplier, FactorPointers &pointers, + int &newNonZeros); + /// allocates more space for L + void increaseLsize(); + /// allocates more space for a row of U + void increaseRowSize(const int row, const int newSize); + /// allocates more space for a column of U + void increaseColSize(const int column, const int newSize, const bool b); + /// allocates more space for rows of U + void enlargeUrow(const int numNewElements); + /// allocates more space for columns of U + void enlargeUcol(const int numNewElements, const bool b); + /// finds a given row in a column + int findInRow(const int row, const int column); + /// finds a given column in a row + int findInColumn(const int column, const int row); + /// declares a row inactive + void removeRowFromActSet(const int row, FactorPointers &pointers); + /// declares a column inactive + void removeColumnFromActSet(const int column, FactorPointers &pointers); + /// allocates space for U + void allocateSpaceForU(); + /// allocates several working arrays + void allocateSomeArrays(); + /// initializes some numbers + void initialSomeNumbers(); + /// solves L x = b + void Lxeqb(double *b) const; + /// same as above but with two rhs + void Lxeqb2(double *b1, double *b2) const; + /// solves U x = b + void Uxeqb(double *b, double *sol) const; + /// same as above but with two rhs + void Uxeqb2(double *b1, double *sol1, double *sol2, double *b2) const; + /// solves x L = b + void xLeqb(double *b) const; + /// solves x U = b + void xUeqb(double *b, double *sol) const; + /// updates factorization after a Simplex iteration + int LUupdate(int newBasicCol); + /// creates a new eta vector + void newEta(int row, int numNewElements); + /// makes a copy of row permutations + void copyRowPermutations(); + /// solves H x = b, where H is a product of eta matrices + void Hxeqb(double *b) const; + /// same as above but with two rhs + void Hxeqb2(double *b1, double *b2) const; + /// solves x H = b + void xHeqb(double *b) const; + /// does FTRAN + void ftran(double *b, double *sol, bool save) const; + /// same as above but with two columns + void ftran2(double *b1, double *sol1, double *b2, double *sol2) const; + /// does BTRAN + void btran(double *b, double *sol) const; + ///--------------------------------------- + + + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// work array (should be initialized to zero) + double *denseVector_; + /// work array + double *workArea2_; + /// work array + double *workArea3_; + /// array of labels (should be initialized to zero) + int *vecLabels_; + /// array of indices + int *indVector_; + + /// auxiliary vector + double *auxVector_; + /// auxiliary vector + int *auxInd_; + + /// vector to keep for LUupdate + double *vecKeep_; + /// indices of this vector + int *indKeep_; + /// number of nonzeros + mutable int keepSize_; + + + + /// Starts of the rows of L + int *LrowStarts_; + /// Lengths of the rows of L + int *LrowLengths_; + /// L by rows + double *Lrows_; + /// indices in the rows of L + int *LrowInd_; + /// Size of Lrows_; + int LrowSize_; + /// Capacity of Lrows_ + int LrowCap_; + + /// Starts of the columns of L + int *LcolStarts_; + /// Lengths of the columns of L + int *LcolLengths_; + /// L by columns + double *Lcolumns_; + /// indices in the columns of L + int *LcolInd_; + /// numbers of elements in L + int LcolSize_; + /// maximum capacity of L + int LcolCap_; + + + /// Starts of the rows of U + int *UrowStarts_; + /// Lengths of the rows of U + int *UrowLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the rows of U + int *UrowCapacities_; +#endif + /// U by rows + double *Urows_; + /// Indices in the rows of U + int *UrowInd_; + /// maximum capacity of Urows + int UrowMaxCap_; + /// number of used places in Urows + int UrowEnd_; + /// first row in U + int firstRowInU_; + /// last row in U + int lastRowInU_; + /// previous row in U + int *prevRowInU_; + /// next row in U + int *nextRowInU_; + + /// Starts of the columns of U + int *UcolStarts_; + /// Lengths of the columns of U + int *UcolLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the columns of U + int *UcolCapacities_; +#endif + /// U by columns + double *Ucolumns_; + /// Indices in the columns of U + int *UcolInd_; + /// previous column in U + int *prevColInU_; + /// next column in U + int *nextColInU_; + /// first column in U + int firstColInU_; + /// last column in U + int lastColInU_; + /// maximum capacity of Ucolumns_ + int UcolMaxCap_; + /// last used position in Ucolumns_ + int UcolEnd_; + /// indicator of slack variables + int *colSlack_; + + /// inverse values of the elements of diagonal of U + double *invOfPivots_; + + /// permutation of columns + int *colOfU_; + /// position of column after permutation + int *colPosition_; + /// permutations of rows + int *rowOfU_; + /// position of row after permutation + int *rowPosition_; + /// permutations of rows during LUupdate + int *secRowOfU_; + /// position of row after permutation during LUupdate + int *secRowPosition_; + + /// position of Eta vector + int *EtaPosition_; + /// Starts of eta vectors + int *EtaStarts_; + /// Lengths of eta vectors + int *EtaLengths_; + /// columns of eta vectors + int *EtaInd_; + /// elements of eta vectors + double *Eta_; + /// number of elements in Eta_ + int EtaSize_; + /// last eta row + int lastEtaRow_; + /// maximum number of eta vectors + int maxEtaRows_; + /// Capacity of Eta_ + int EtaMaxCap_; + + /// minimum storage increase + int minIncrease_; + /// maximum size for the diagonal of U after update + double updateTol_; + /// do Shul heuristic + bool doSuhlHeuristic_; + /// maximum of U + double maxU_; + /// bound on the growth rate + double maxGrowth_; + /// maximum of A + double maxA_; + /// maximum number of candidates for pivot + int pivotCandLimit_; + /// number of slacks in basis + int numberSlacks_; + /// number of slacks in irst basis + int firstNumberSlacks_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSmartPtr.hpp b/thirdparty/linux/include/coin/coin/CoinSmartPtr.hpp new file mode 100644 index 0000000..93366a2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSmartPtr.hpp @@ -0,0 +1,528 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: CoinSmartPtr.hpp 1520 2012-01-29 00:43:31Z tkr $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +// Removed lots of debugging stuff and reformatted: Laszlo Ladanyi, IBM +#ifndef CoinSmartPtr_hpp +#define CoinSmartPtr_hpp + +#include <list> +#include <cassert> +#include <cstddef> +#include <cstring> + +namespace Coin { + + //######################################################################### + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * Coin::SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point + * to A and B, but A and B also point to each other (i.e. A has a + * SmartPtr to B and B has a SmartPtr to A). In this scenario, when the + * higher level object is finished with A and B, their reference counts + * will never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject { + public: + ReferencedObject() : reference_count_(0) {} + virtual ~ReferencedObject() { assert(reference_count_ == 0); } + inline int ReferenceCount() const { return reference_count_; } + inline void AddRef() const { ++reference_count_; } + inline void ReleaseRef() const { --reference_count_; } + + private: + mutable int reference_count_; + }; + + //######################################################################### + + +//#define IP_DEBUG_SMARTPTR +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifdef IP_DEBUG_SMARTPTR +# include "IpDebug.hpp" +#endif + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template <class T> + class SmartPtr { + public: + /** Returns the raw pointer contained. Use to get the value of the + * raw ptr (i.e. to pass to other methods/functions, etc.) Note: This + * method does NOT copy, therefore, modifications using this value + * modify the underlying object contained by the SmartPtr, NEVER + * delete this returned value. + */ + T* GetRawPtr() const { return ptr_; } + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + bool IsValid() const { return ptr_ != NULL; } + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + bool IsNull() const { return ptr_ == NULL; } + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Release the currently referenced object. */ + void ReleasePointer_() { + if (ptr_) { + ptr_->ReleaseRef(); + if (ptr_->ReferenceCount() == 0) { + delete ptr_; + } + ptr_ = NULL; + } + } + + /** Set the value of the internal raw pointer from another raw + * pointer, releasing the previously referenced object if necessary. */ + SmartPtr<T>& SetFromRawPtr_(T* rhs){ + ReleasePointer_(); // Release any old pointer + if (rhs != NULL) { + rhs->AddRef(); + ptr_ = rhs; + } + return *this; + } + + /** Set the value of the internal raw pointer from a SmartPtr, + * releasing the previously referenced object if necessary. */ + inline SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs) { + SetFromRawPtr_(rhs.GetRawPtr()); + return (*this); + } + + //@} + + public: +#define dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr() : ptr_(NULL) {} + + /** Copy constructor, initialized from copy */ + SmartPtr(const SmartPtr<T>& copy) : ptr_(NULL) { + (void) SetFromSmartPtr_(copy); + } + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr) : ptr_(NULL) { + (void) SetFromRawPtr_(ptr); + } + + /** Destructor, automatically decrements the reference count, deletes + * the object if necessary.*/ + ~SmartPtr() { + ReleasePointer_(); + } + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const { +#if COIN_COINUTILS_CHECKLEVEL > 0 + assert(ptr_); +#endif + return ptr_; + } + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const { +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + return *ptr_; + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr<T>& operator=(T* rhs) { + return SetFromRawPtr_(rhs); + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr<T>& operator=(const SmartPtr<T>& rhs) { + return SetFromSmartPtr_(rhs); + } + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template <class U1, class U2> + friend + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + //@} + + }; + + template <class U1, class U2> + bool ComparePointers(const U1* lhs, const U2* rhs) { + if (lhs == rhs) { + return true; + } + // If lhs and rhs point to the same object with different interfaces + // U1 and U2, we cannot guarantee that the value of the pointers will + // be equivalent. We can guarantee this if we convert to void*. + return static_cast<const void*>(lhs) == static_cast<const void*>(rhs); + } + +} // namespace Coin + +//############################################################################# + +/**@name SmartPtr friends that are overloaded operators, so they are not in + the Coin namespace. */ +//@{ +template <class U1, class U2> +bool operator==(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr()); +} + +template <class U1, class U2> +bool operator==(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs); +} + +template <class U1, class U2> +bool operator==(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { + return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr()); +} + +template <class U1, class U2> +bool operator!=(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { + return ! operator==(lhs, rhs); +} + +template <class U1, class U2> +bool operator!=(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { + return ! operator==(lhs, raw_rhs); +} + +template <class U1, class U2> +bool operator!=(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { + return ! operator==(raw_lhs, rhs); +} +//@} + +#define CoinReferencedObject Coin::ReferencedObject +#define CoinSmartPtr Coin::SmartPtr +#define CoinComparePointers Coin::ComparePointers + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSnapshot.hpp b/thirdparty/linux/include/coin/coin/CoinSnapshot.hpp new file mode 100644 index 0000000..e928026 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSnapshot.hpp @@ -0,0 +1,476 @@ +/* $Id: CoinSnapshot.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSnapshot_H +#define CoinSnapshot_H + +class CoinPackedMatrix; +#include "CoinTypes.hpp" + +//############################################################################# + +/** NON Abstract Base Class for interfacing with cut generators or branching code or .. + It is designed to be snapshot of a problem at a node in tree + + The class may or may not own the arrays - see owned_ + + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return arrays. +*/ + +class CoinSnapshot { + +public: + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + The Matrix pointers may be NULL + */ + //@{ + /// Get number of columns + inline int getNumCols() const + { return numCols_;} + + /// Get number of rows + inline int getNumRows() const + { return numRows_;} + + /// Get number of nonzero elements + inline int getNumElements() const + { return numElements_;} + + /// Get number of integer variables + inline int getNumIntegers() const + { return numIntegers_;} + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const + { return colLower_;} + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const + { return colUpper_;} + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const + { return rowLower_;} + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const + { return rowUpper_;} + + /** Get pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + inline const double * getRightHandSide() const + { return rightHandSide_;} + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const + { return objCoefficients_;} + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const + { return objSense_;} + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const + { return colType_[colIndex]=='C';} + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const + { return colType_[colIndex]=='B';} + + /// Return true if column is integer. + inline bool isInteger(int colIndex) const + { return colType_[colIndex]=='B'||colType_[colIndex]=='I';} + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const + { return colType_[colIndex]=='I';} + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const + { return colType_[colIndex]=='B'&&colUpper_[colIndex]>colLower_[colIndex];} + + /// Get colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + inline const char * getColType() const + { return colType_;} + + /// Get pointer to row-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByRow() const + { return matrixByRow_;} + + /// Get pointer to column-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByCol() const + { return matrixByCol_;} + + /// Get pointer to row-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByRow() const + { return originalMatrixByRow_;} + + /// Get pointer to column-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByCol() const + { return originalMatrixByCol_;} + //@} + + /**@name Solution query methods */ + //@{ + /// Get pointer to array[getNumCols()] of primal variable values + inline const double * getColSolution() const + { return colSolution_;} + + /// Get pointer to array[getNumRows()] of dual variable values + inline const double * getRowPrice() const + { return rowPrice_;} + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const + { return reducedCost_;} + + /// Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + inline const double * getRowActivity() const + { return rowActivity_;} + + /// Get pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + inline const double * getDoNotSeparateThis() const + { return doNotSeparateThis_;} + //@} + + /**@name Other scalar get methods */ + //@{ + /// Get solver's value for infinity + inline double getInfinity() const + { return infinity_;} + + /** Get objective function value - includinbg any offset i.e. + sum c sub j * x subj - objValue = objOffset */ + inline double getObjValue() const + { return objValue_;} + + /// Get objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline double getObjOffset() const + { return objOffset_;} + + /// Get dual tolerance + inline double getDualTolerance() const + { return dualTolerance_;} + + /// Get primal tolerance + inline double getPrimalTolerance() const + { return primalTolerance_;} + + /// Get integer tolerance + inline double getIntegerTolerance() const + { return integerTolerance_;} + + /// Get integer upper bound i.e. best solution * getObjSense + inline double getIntegerUpperBound() const + { return integerUpperBound_;} + + /// Get integer lower bound i.e. best possible solution * getObjSense + inline double getIntegerLowerBound() const + { return integerLowerBound_;} + //@} + + //--------------------------------------------------------------------------- + + /**@name Method to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + All solution type arrays will be deleted + */ + void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + bool makeRowCopy=false); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods to set data */ + //@{ + /// Set number of columns + inline void setNumCols(int value) + { numCols_ = value;} + + /// Set number of rows + inline void setNumRows(int value) + { numRows_ = value;} + + /// Set number of nonzero elements + inline void setNumElements(int value) + { numElements_ = value;} + + /// Set number of integer variables + inline void setNumIntegers(int value) + { numIntegers_ = value;} + + /// Set pointer to array[getNumCols()] of column lower bounds + void setColLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of column upper bounds + void setColUpper(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row lower bounds + void setRowLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row upper bounds + void setRowUpper(const double * array, bool copyIn=true); + + /** Set pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void setRightHandSide(const double * array, bool copyIn=true); + + /** Create array[getNumRows()] of row right-hand sides + using existing information + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void createRightHandSide(); + + /// Set pointer to array[getNumCols()] of objective function coefficients + void setObjCoefficients(const double * array, bool copyIn=true); + + /// Set objective function sense (1 for min (default), -1 for max) + inline void setObjSense(double value) + { objSense_ = value;} + + /// Set colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + void setColType(const char *array, bool copyIn=true); + + /// Set pointer to row-wise copy of current matrix + void setMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Create row-wise copy from MatrixByCol + void createMatrixByRow(); + + /// Set pointer to column-wise copy of current matrix + void setMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to row-wise copy of "original" matrix + void setOriginalMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to column-wise copy of "original" matrix + void setOriginalMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values + void setColSolution(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of dual variable values + void setRowPrice(const double * array, bool copyIn=true); + + /// Set a pointer to array[getNumCols()] of reduced costs + void setReducedCost(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + void setRowActivity(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + void setDoNotSeparateThis(const double * array, bool copyIn=true); + + /// Set solver's value for infinity + inline void setInfinity(double value) + { infinity_ = value;} + + /// Set objective function value (including any rhs offset) + inline void setObjValue(double value) + { objValue_ = value;} + + /// Set objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline void setObjOffset(double value) + { objOffset_ = value;} + + /// Set dual tolerance + inline void setDualTolerance(double value) + { dualTolerance_ = value;} + + /// Set primal tolerance + inline void setPrimalTolerance(double value) + { primalTolerance_ = value;} + + /// Set integer tolerance + inline void setIntegerTolerance(double value) + { integerTolerance_ = value;} + + /// Set integer upper bound i.e. best solution * getObjSense + inline void setIntegerUpperBound(double value) + { integerUpperBound_ = value;} + + /// Set integer lower bound i.e. best possible solution * getObjSense + inline void setIntegerLowerBound(double value) + { integerLowerBound_ = value;} + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + CoinSnapshot(); + + /// Copy constructor + CoinSnapshot(const CoinSnapshot &); + + /// Assignment operator + CoinSnapshot & operator=(const CoinSnapshot& rhs); + + /// Destructor + virtual ~CoinSnapshot (); + + //@} + +private: + ///@name private functions + //@{ + /** Does main work of destructor - type (or'ed) + 1 - NULLify pointers + 2 - delete pointers + 4 - initialize scalars (tolerances etc) + 8 - initialize scalars (objValue etc0 + */ + void gutsOfDestructor(int type); + /// Does main work of copy + void gutsOfCopy(const CoinSnapshot & rhs); + //@} + + ///@name Private member data + + /// objective function sense (1 for min (default), -1 for max) + double objSense_; + + /// solver's value for infinity + double infinity_; + + /// objective function value (including any rhs offset) + double objValue_; + + /// objective offset i.e. sum c sub j * x subj -objValue = objOffset + double objOffset_; + + /// dual tolerance + double dualTolerance_; + + /// primal tolerance + double primalTolerance_; + + /// integer tolerance + double integerTolerance_; + + /// integer upper bound i.e. best solution * getObjSense + double integerUpperBound_; + + /// integer lower bound i.e. best possible solution * getObjSense + double integerLowerBound_; + + /// pointer to array[getNumCols()] of column lower bounds + const double * colLower_; + + /// pointer to array[getNumCols()] of column upper bounds + const double * colUpper_; + + /// pointer to array[getNumRows()] of row lower bounds + const double * rowLower_; + + /// pointer to array[getNumRows()] of row upper bounds + const double * rowUpper_; + + /// pointer to array[getNumRows()] of rhs side values + const double * rightHandSide_; + + /// pointer to array[getNumCols()] of objective function coefficients + const double * objCoefficients_; + + /// colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + const char * colType_; + + /// pointer to row-wise copy of current matrix + const CoinPackedMatrix * matrixByRow_; + + /// pointer to column-wise copy of current matrix + const CoinPackedMatrix * matrixByCol_; + + /// pointer to row-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByRow_; + + /// pointer to column-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByCol_; + + /// pointer to array[getNumCols()] of primal variable values + const double * colSolution_; + + /// pointer to array[getNumRows()] of dual variable values + const double * rowPrice_; + + /// a pointer to array[getNumCols()] of reduced costs + const double * reducedCost_; + + /// pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + const double * rowActivity_; + + /// pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + const double * doNotSeparateThis_; + + /// number of columns + int numCols_; + + /// number of rows + int numRows_; + + /// number of nonzero elements + int numElements_; + + /// number of integer variables + int numIntegers_; + + /// To say whether arrays etc are owned by CoinSnapshot + typedef struct { + unsigned int colLower:1; + unsigned int colUpper:1; + unsigned int rowLower:1; + unsigned int rowUpper:1; + unsigned int rightHandSide:1; + unsigned int objCoefficients:1; + unsigned int colType:1; + unsigned int matrixByRow:1; + unsigned int matrixByCol:1; + unsigned int originalMatrixByRow:1; + unsigned int originalMatrixByCol:1; + unsigned int colSolution:1; + unsigned int rowPrice:1; + unsigned int reducedCost:1; + unsigned int rowActivity:1; + unsigned int doNotSeparateThis:1; + } coinOwned; + coinOwned owned_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinSort.hpp b/thirdparty/linux/include/coin/coin/CoinSort.hpp new file mode 100644 index 0000000..259fb35 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinSort.hpp @@ -0,0 +1,678 @@ +/* $Id: CoinSort.hpp 1594 2013-04-19 14:33:00Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSort_H +#define CoinSort_H + +#include <functional> +#include <new> +#include <algorithm> +#include "CoinDistance.hpp" + +// Uncomment the next three lines to get thorough initialisation of memory. +// #ifndef ZEROFAULT +// #define ZEROFAULT +// #endif + +#ifdef COIN_FAST_CODE +#ifndef COIN_USE_EKK_SORT +#define COIN_USE_EKK_SORT +#endif +#endif + +//############################################################################# + +/** An ordered pair. It's the same as std::pair, just this way it'll have the + same look as the triple sorting. */ +template <class S, class T> +struct CoinPair { +public: + /// First member of pair + S first; + /// Second member of pair + T second; +public: + /// Construct from ordered pair + CoinPair(const S& s, const T& t) : first(s), second(t) {} +}; + +//############################################################################# + +/**@name Comparisons on first element of two ordered pairs */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T> +class CoinFirstLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T> +class CoinFirstGreater_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return t1.first > t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T> +class CoinFirstAbsLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T> +class CoinFirstAbsGreater_2 { +public: + /// Compare function + inline bool operator()(CoinPair<S,T> t1, CoinPair<S,T> t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstLess_2 { +private: + CoinExternalVectorFirstLess_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_2(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstGreater_2 { +private: + CoinExternalVectorFirstGreater_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_2(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/** Sort a pair of containers.<br> + + Iter_S - iterator for first container<br> + Iter_T - iterator for 2nd container<br> + CoinCompare2 - class comparing CoinPairs<br> +*/ + +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template <class Iter_S, class Iter_T, class CoinCompare2> void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst, const CoinCompare2& pc) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair<S,T> ST_pair; + ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x.begin(), x.end(), pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class Iter_S, class Iter_T> void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} + +#else //======================================================================= + +template <class S, class T, class CoinCompare2> void +CoinSort_2(S* sfirst, S* slast, T* tfirst, const CoinCompare2& pc) +{ + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair<S,T> ST_pair; + ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + // Can show RUI errors on some systems due to copy of ST_pair with gaps. + // E.g., <int, double> has 4 byte alignment gap on Solaris/SUNWspro. + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x, x + len, pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +template <class S, class T> void +// This Always uses std::sort +CoinSort_2Std(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} +#ifndef COIN_USE_EKK_SORT +//----------------------------------------------------------------------------- +template <class S, class T> void +CoinSort_2(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} +#else +//----------------------------------------------------------------------------- +extern int boundary_sort; +extern int boundary_sort2; +extern int boundary_sort3; +/// Sort without new and delete +template <class S, class T> void +CoinSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 1) { + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } +#if 0 + if (number==boundary_sort3) { + printf("before sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + } +#endif + int minsize=10; + int n = static_cast<int>(number); + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + int j; + /*check already sorted */ + S last=key[0]; + for (j=1;j<n;j++) { + if (key[j]>=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +#if 0 + if (number==boundary_sort3) { + printf("after sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + CoinSort_2Many(key, lastKey, array2); + printf("after2 sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + } +#endif +} +#endif +#endif +/// Sort without new and delete +template <class S, class T> void +CoinShortSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 2) { + if (number == 2 && key[0] > key[1]) { + S tempS = key[0]; + T tempT = array2[0]; + key[0] = key[1]; + array2[0] = array2[1]; + key[1] = tempS; + array2[1] = tempT; + } + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } + int minsize=10; + size_t n = number; + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + size_t j; + /*check already sorted */ + S last=key[0]; + for (j=1;j<n;j++) { + if (key[j]>=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +} +//############################################################################# +//############################################################################# + +/**@name Ordered Triple Struct */ +template <class S, class T, class U> +class CoinTriple { +public: + /// First member of triple + S first; + /// Second member of triple + T second; + /// Third member of triple + U third; +public: + /// Construct from ordered triple + CoinTriple(const S& s, const T& t, const U& u):first(s),second(t),third(u) {} +}; + +//############################################################################# +/**@name Comparisons on first element of two ordered triples */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T, class U > +class CoinFirstGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return t1.first>t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstAbsLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T, class U > +class CoinFirstAbsGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstLess_3 { +private: + CoinExternalVectorFirstLess_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_3(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstGreater_3 { +private: + CoinExternalVectorFirstGreater_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_3(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/**@name Typedefs for sorting the entries of a packed vector based on an + external vector. */ +//@{ +/// Sort packed vector in increasing order of the external vector +typedef CoinExternalVectorFirstLess_3<int, int, double, double> +CoinIncrSolutionOrdered; +/// Sort packed vector in decreasing order of the external vector +typedef CoinExternalVectorFirstGreater_3<int, int, double, double> +CoinDecrSolutionOrdered; +//@} + +//############################################################################# + +/** Sort a triple of containers.<br> + + Iter_S - iterator for first container<br> + Iter_T - iterator for 2nd container<br> + Iter_U - iterator for 3rd container<br> + CoinCompare3 - class comparing CoinTriples<br> +*/ +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template <class Iter_S, class Iter_T, class Iter_U, class CoinCompare3> void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst, + const CoinCompare3& tc) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + typedef typename std::iterator_traits<Iter_U>::value_type U; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinTriple<S,T,U> STU_triple; + STU_triple* x = + static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple))); + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + Iter_U ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class Iter_S, class Iter_T, class Iter_U> void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + typedef typename std::iterator_traits<Iter_U>::value_type U; + CoinSort_3(sfirts, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>()); +} + +#else //======================================================================= + +template <class S, class T, class U, class CoinCompare3> void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst, const CoinCompare3& tc) +{ + const size_t len = coinDistance(sfirst,slast); + if (len <= 1) + return; + + typedef CoinTriple<S,T,U> STU_triple; + STU_triple* x = + static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple))); + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + U* ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class S, class T, class U> void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst) +{ + CoinSort_3(sfirst, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>()); +} + +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinStructuredModel.hpp b/thirdparty/linux/include/coin/coin/CoinStructuredModel.hpp new file mode 100644 index 0000000..19659b8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinStructuredModel.hpp @@ -0,0 +1,247 @@ +/* $Id: CoinStructuredModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinStructuredModel_H +#define CoinStructuredModel_H + +#include "CoinModel.hpp" +#include <vector> + +/** + This is a model which is made up of Coin(Structured)Model blocks. +*/ + typedef struct CoinModelInfo2 { + int rowBlock; // Which row block + int columnBlock; // Which column block + char matrix; // nonzero if matrix exists + char rhs; // nonzero if non default rhs exists + char rowName; // nonzero if row names exists + char integer; // nonzero if integer information exists + char bounds; // nonzero if non default bounds/objective exists + char columnName; // nonzero if column names exists + CoinModelInfo2() : + rowBlock(0), + columnBlock(0), + matrix(0), + rhs(0), + rowName(0), + integer(0), + bounds(0), + columnName(0) + {} +} CoinModelBlockInfo; + +class CoinStructuredModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinBaseModel & block); + /** add a block from a CoinModel with names in model + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const CoinBaseModel & block); + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + This passes in block - structured model takes ownership + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + CoinBaseModel * block); + /** add a block using names + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + /// Read SMPS model + int readSmps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + + /** Decompose a CoinModel + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinModel &model,int type, + int maxBlocks=50, const char ** starts=NULL); + /** Decompose a model specified as arrays + CoinPackedMatrix + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective, int type,int maxBlocks=50, + int * starts=NULL, + double objectiveOffset=0.0); + + //@} + + + /**@name For getting information */ + //@{ + /// Return number of row blocks + inline int numberRowBlocks() const + { return numberRowBlocks_;} + /// Return number of column blocks + inline int numberColumnBlocks() const + { return numberColumnBlocks_;} + /// Return number of elementBlocks + inline CoinBigIndex numberElementBlocks() const + { return numberElementBlocks_;} + /// Return number of elements + CoinBigIndex numberElements() const; + /// Return the i'th row block name + inline const std::string & getRowBlock(int i) const + { return rowBlockNames_[i];} + /// Set i'th row block name + inline void setRowBlock(int i,const std::string &name) + { rowBlockNames_[i] = name;} + /// Add or check a row block name and number of rows + int addRowBlock(int numberRows,const std::string &name) ; + /// Return a row block index given a row block name + int rowBlock(const std::string &name) const; + /// Return i'th the column block name + inline const std::string & getColumnBlock(int i) const + { return columnBlockNames_[i];} + /// Set i'th column block name + inline void setColumnBlock(int i,const std::string &name) + { columnBlockNames_[i] = name;} + /// Add or check a column block name and number of columns + int addColumnBlock(int numberColumns,const std::string &name) ; + /// Return a column block index given a column block name + int columnBlock(const std::string &name) const; + /// Return i'th block type + inline const CoinModelBlockInfo & blockType(int i) const + { return blockType_[i];} + /// Return i'th block + inline CoinBaseModel * block(int i) const + { return blocks_[i];} + /// Return block corresponding to row and column + const CoinBaseModel * block(int row,int column) const; + /// Return i'th block as CoinModel (or NULL) + CoinModel * coinBlock(int i) const; + /// Return block corresponding to row and column as CoinModel + const CoinBaseModel * coinBlock(int row,int column) const; + /// Return block number corresponding to row and column + int blockIndex(int row,int column) const; + /** Return model as a CoinModel block + and fill in info structure and update counts + */ + CoinModel * coinModelBlock(CoinModelBlockInfo & info) ; + /// Sets given block into coinModelBlocks_ + void setCoinModel(CoinModel * block, int iBlock); + /// Refresh info in blockType_ + void refresh(int iBlock); + /** Fill pointers corresponding to row and column */ + + CoinModelBlockInfo block(int row,int column, + const double * & rowLower, const double * & rowUpper, + const double * & columnLower, const double * & columnUpper, + const double * & objective) const; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinStructuredModel(); + /** Read a problem in MPS format from the given filename. + May try and decompose + */ + CoinStructuredModel(const char *fileName,int decompose=0, + int maxBlocks=50); + /** Destructor */ + virtual ~CoinStructuredModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinStructuredModel(const CoinStructuredModel&); + /// = + CoinStructuredModel& operator=(const CoinStructuredModel&); + /// Clone + virtual CoinBaseModel * clone() const; + //@} + +private: + + /** Fill in info structure and update counts + Returns number of inconsistencies on border + */ + int fillInfo(CoinModelBlockInfo & info,const CoinModel * block); + /** Fill in info structure and update counts + */ + void fillInfo(CoinModelBlockInfo & info,const CoinStructuredModel * block); + /**@name Data members */ + //@{ + /// Current number of row blocks + int numberRowBlocks_; + /// Current number of column blocks + int numberColumnBlocks_; + /// Current number of element blocks + int numberElementBlocks_; + /// Maximum number of element blocks + int maximumElementBlocks_; + /// Rowblock name + std::vector<std::string> rowBlockNames_; + /// Columnblock name + std::vector<std::string> columnBlockNames_; + /// Blocks + CoinBaseModel ** blocks_; + /// CoinModel copies of blocks or NULL if original CoinModel + CoinModel ** coinModelBlocks_; + /// Which parts of model are set in block + CoinModelBlockInfo * blockType_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinTime.hpp b/thirdparty/linux/include/coin/coin/CoinTime.hpp new file mode 100644 index 0000000..49e8507 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinTime.hpp @@ -0,0 +1,310 @@ +/* $Id: CoinTime.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTime_hpp +#define _CoinTime_hpp + +// Uncomment the next three lines for thorough memory initialisation. +// #ifndef ZEROFAULT +// # define ZEROFAULT +// #endif + +//############################################################################# + +#include <ctime> +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#else +// MacOS-X and FreeBSD needs sys/time.h +#if defined(__MACH__) || defined (__FreeBSD__) +#include <sys/time.h> +#endif +#if !defined(__MSVCRT__) +#include <sys/resource.h> +#endif +#endif + +//############################################################################# + +#if defined(_MSC_VER) + +#if 0 // change this to 1 if want to use the win32 API +#include <windows.h> +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#define DELTA_EPOCH_IN_SECS 11644473600.0 +inline double CoinGetTimeOfDay() +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + double t = ft.dwHighDateTime * TWO_TO_THE_THIRTYTWO + ft.dwLowDateTime; + t = t/10000000.0 - DELTA_EPOCH_IN_SECS; + return t; +} +#else +#include <sys/types.h> +#include <sys/timeb.h> +inline double CoinGetTimeOfDay() +{ + struct _timeb timebuffer; +#pragma warning(disable:4996) + _ftime( &timebuffer ); // C4996 +#pragma warning(default:4996) + return timebuffer.time + timebuffer.millitm/1000.0; +} +#endif + +#else + +#include <sys/time.h> + +inline double CoinGetTimeOfDay() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return static_cast<double>(tv.tv_sec) + static_cast<int>(tv.tv_usec)/1000000.0; +} + +#endif // _MSC_VER + +/** + Query the elapsed wallclock time since the first call to this function. If + a positive argument is passed to the function then the time of the first + call is set to that value (this kind of argument is allowed only at the + first call!). If a negative argument is passed to the function then it + returns the time when it was set. +*/ + +inline double CoinWallclockTime(double callType = 0) +{ + double callTime = CoinGetTimeOfDay(); + static const double firstCall = callType > 0 ? callType : callTime; + return callType < 0 ? firstCall : callTime - firstCall; +} + +//############################################################################# + +//#define HAVE_SDK // if SDK under Win32 is installed, for CPU instead of elapsed time under Win +#ifdef HAVE_SDK +#include <windows.h> +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#endif + +static inline double CoinCpuTime() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) +#ifdef HAVE_SDK + FILETIME creation; + FILETIME exit; + FILETIME kernel; + FILETIME user; + GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user); + double t = user.dwHighDateTime * TWO_TO_THE_THIRTYTWO + user.dwLowDateTime; + return t/10000000.0; +#else + unsigned int ticksnow; /* clock_t is same as int */ + ticksnow = (unsigned int)clock(); + cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC); +#endif + +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + cpu_temp = static_cast<double>(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast<double> (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} + +//############################################################################# + + + +static inline double CoinSysTime() +{ + double sys_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + sys_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + sys_temp = static_cast<double>(usage.ru_stime.tv_sec); + sys_temp += 1.0e-6*(static_cast<double> (usage.ru_stime.tv_usec)); +#endif + return sys_temp; +} + +//############################################################################# +// On most systems SELF seems to include children threads, This is for when it doesn't +static inline double CoinCpuTimeJustChildren() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + cpu_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_CHILDREN,&usage); + cpu_temp = static_cast<double>(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast<double> (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} +//############################################################################# + +#include <fstream> + +/** + This class implements a timer that also implements a tracing functionality. + + The timer stores the start time of the timer, for how much time it was set to + and when does it expire (start + limit = end). Queries can be made that tell + whether the timer is expired, is past an absolute time, is past a percentage + of the length of the timer. All times are given in seconds, but as double + numbers, so there can be fractional values. + + The timer can also be initialized with a stream and a specification whether + to write to or read from the stream. In the former case the result of every + query is written into the stream, in the latter case timing is not tested at + all, rather the supposed result is read out from the stream. This makes it + possible to exactly retrace time sensitive program execution. +*/ +class CoinTimer +{ +private: + /// When the timer was initialized/reset/restarted + double start; + /// + double limit; + double end; +#ifdef COIN_COMPILE_WITH_TRACING + std::fstream* stream; + bool write_stream; +#endif + +private: +#ifdef COIN_COMPILE_WITH_TRACING + inline bool evaluate(bool b_tmp) const { + int i_tmp = b_tmp; + if (stream) { + if (write_stream) + (*stream) << i_tmp << "\n"; + else + (*stream) >> i_tmp; + } + return i_tmp; + } + inline double evaluate(double d_tmp) const { + if (stream) { + if (write_stream) + (*stream) << d_tmp << "\n"; + else + (*stream) >> d_tmp; + } + return d_tmp; + } +#else + inline bool evaluate(const bool b_tmp) const { + return b_tmp; + } + inline double evaluate(const double d_tmp) const { + return d_tmp; + } +#endif + +public: + /// Default constructor creates a timer with no time limit and no tracing + CoinTimer() : + start(0), limit(1e100), end(1e100) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + + /// Create a timer with the given time limit and with no tracing + CoinTimer(double lim) : + start(CoinCpuTime()), limit(lim), end(start+lim) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + +#ifdef COIN_COMPILE_WITH_TRACING + /** Create a timer with no time limit and with writing/reading the trace + to/from the given stream, depending on the argument \c write. */ + CoinTimer(std::fstream* s, bool write) : + start(0), limit(1e100), end(1e100), + stream(s), write_stream(write) {} + + /** Create a timer with the given time limit and with writing/reading the + trace to/from the given stream, depending on the argument \c write. */ + CoinTimer(double lim, std::fstream* s, bool w) : + start(CoinCpuTime()), limit(lim), end(start+lim), + stream(s), write_stream(w) {} +#endif + + /// Restart the timer (keeping the same time limit) + inline void restart() { start=CoinCpuTime(); end=start+limit; } + /// An alternate name for \c restart() + inline void reset() { restart(); } + /// Reset (and restart) the timer and change its time limit + inline void reset(double lim) { limit=lim; restart(); } + + /** Return whether the given percentage of the time limit has elapsed since + the timer was started */ + inline bool isPastPercent(double pct) const { + return evaluate(start + limit * pct < CoinCpuTime()); + } + /** Return whether the given amount of time has elapsed since the timer was + started */ + inline bool isPast(double lim) const { + return evaluate(start + lim < CoinCpuTime()); + } + /** Return whether the originally specified time limit has passed since the + timer was started */ + inline bool isExpired() const { + return evaluate(end < CoinCpuTime()); + } + + /** Return how much time is left on the timer */ + inline double timeLeft() const { + return evaluate(end - CoinCpuTime()); + } + + /** Return how much time has elapsed */ + inline double timeElapsed() const { + return evaluate(CoinCpuTime() - start); + } + + inline void setLimit(double l) { + limit = l; + return; + } +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinTypes.hpp b/thirdparty/linux/include/coin/coin/CoinTypes.hpp new file mode 100644 index 0000000..3adee2e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinTypes.hpp @@ -0,0 +1,64 @@ +/* $Id: CoinTypes.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTypes_hpp +#define _CoinTypes_hpp + +#include "CoinUtilsConfig.h" +/* On some systems, we require stdint.h to have the 64bit integer type defined. */ +#ifdef COINUTILS_HAS_STDINT_H +#include <stdint.h> +#endif +#ifdef COINUTILS_HAS_CSTDINT +#include <cstdint> +#endif + +#define CoinInt64 COIN_INT64_T +#define CoinUInt64 COIN_UINT64_T +#define CoinIntPtr COIN_INTPTR_T + +//============================================================================= +#ifndef COIN_BIG_INDEX +#define COIN_BIG_INDEX 0 +#endif + +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif + +//============================================================================= +#ifndef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#endif + +// See if we want the ability to have long double work arrays +#if COIN_BIG_DOUBLE==2 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#elif COIN_BIG_DOUBLE==3 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 1 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#else +#define COIN_LONG_WORK 0 +typedef double CoinWorkDouble; +#endif + +#if COIN_BIG_DOUBLE==0 +typedef double CoinFactorizationDouble; +#elif COIN_BIG_DOUBLE==1 +typedef long double CoinFactorizationDouble; +#else +typedef double CoinFactorizationDouble; +#endif + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinUtility.hpp b/thirdparty/linux/include/coin/coin/CoinUtility.hpp new file mode 100644 index 0000000..49a30e2 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinUtility.hpp @@ -0,0 +1,19 @@ +/* $Id: CoinUtility.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinUtility_h_ +#define CoinUtility_h_ + +#include "CoinSort.hpp" + +template <typename S, typename T> +CoinPair<S,T> CoinMakePair(const S& s, const T& t) +{ return CoinPair<S,T>(s, t); } + +template <typename S, typename T, typename U> +CoinTriple<S,T,U> CoinMakeTriple(const S& s, const T& t, const U& u) +{ return CoinTriple<S,T,U>(s, t, u); } + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinUtilsConfig.h b/thirdparty/linux/include/coin/coin/CoinUtilsConfig.h new file mode 100644 index 0000000..d7e8eaa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinUtilsConfig.h @@ -0,0 +1,34 @@ +/* src/config_coinutils.h. Generated by configure. */ +/* inc/config_coinutils.h.in. */ + +#ifndef __CONFIG_COINUTILS_H__ +#define __CONFIG_COINUTILS_H__ + +/* Define to 1 if stdint.h is available for CoinUtils */ +#define COINUTILS_HAS_STDINT_H 1 + +/* Define to 1 if stdint.h is available for CoinUtils */ +/* #undef COINUTILS_HAS_CSTDINT */ + +/* Version number of project */ +#define COINUTILS_VERSION "2.10.13" + +/* Major Version number of project */ +#define COINUTILS_VERSION_MAJOR 2 + +/* Minor Version number of project */ +#define COINUTILS_VERSION_MINOR 10 + +/* Release Version number of project */ +#define COINUTILS_VERSION_RELEASE 13 + +/* Define to 64bit integer type */ +#define COIN_INT64_T int64_t + +/* Define to integer type capturing pointer */ +#define COIN_INTPTR_T intptr_t + +/* Define to 64bit unsigned integer type */ +#define COIN_UINT64_T int64_t + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinWarmStart.hpp b/thirdparty/linux/include/coin/coin/CoinWarmStart.hpp new file mode 100644 index 0000000..a7e28c8 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinWarmStart.hpp @@ -0,0 +1,58 @@ +/* $Id: CoinWarmStart.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStart_H +#define CoinWarmStart_H + +//############################################################################# + +class CoinWarmStartDiff; + +/** Abstract base class for warm start information. + + Really nothing can be generalized for warm start information --- all we + know is that it exists. Hence the abstract base class contains only a + virtual destructor and a virtual clone function (a virtual constructor), + so that derived classes can provide these functions. +*/ + +class CoinWarmStart { +public: + + /// Abstract destructor + virtual ~CoinWarmStart() {} + + /// `Virtual constructor' + virtual CoinWarmStart *clone() const = 0 ; + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const ) const { return 0; } + + + virtual void + applyDiff (const CoinWarmStartDiff *const ) {} + +}; + + +/*! \class CoinWarmStartDiff + \brief Abstract base class for warm start `diff' objects + + For those types of warm start objects where the notion of a `diff' makes + sense, this virtual base class is provided. As with CoinWarmStart, its sole + reason for existence is to make it possible to write solver-independent code. +*/ + +class CoinWarmStartDiff { +public: + + /// Abstract destructor + virtual ~CoinWarmStartDiff() {} + + /// `Virtual constructor' + virtual CoinWarmStartDiff *clone() const = 0 ; +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinWarmStartBasis.hpp b/thirdparty/linux/include/coin/coin/CoinWarmStartBasis.hpp new file mode 100644 index 0000000..272d393 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinWarmStartBasis.hpp @@ -0,0 +1,456 @@ +/* $Id: CoinWarmStartBasis.hpp 1515 2011-12-10 23:38:04Z lou $ */ +/*! \legal + Copyright (C) 2000 -- 2003, International Business Machines Corporation + and others. All Rights Reserved. + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinWarmStart.hpp + \brief Declaration of the generic simplex (basis-oriented) warm start + class. Also contains a basis diff class. +*/ + +#ifndef CoinWarmStartBasis_H +#define CoinWarmStartBasis_H + +#include <vector> + +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + +//############################################################################# + +/*! \class CoinWarmStartBasis + \brief The default COIN simplex (basis-oriented) warm start class + + CoinWarmStartBasis provides for a warm start object which contains the + status of each variable (structural and artificial). + + \todo Modify this class so that the number of status entries per byte + and bytes per status vector allocation unit are not hardcoded. + At the least, collect this into a couple of macros. + + \todo Consider separate fields for allocated capacity and actual basis + size. We could avoid some reallocation, at the price of retaining + more space than we need. Perhaps more important, we could do much + better sanity checks. +*/ + +class CoinWarmStartBasis : public virtual CoinWarmStart { +public: + + /*! \brief Enum for status of variables + + Matches CoinPrePostsolveMatrix::Status, without superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + The status vectors are currently packed using two bits per status code, + four codes per byte. The location of the status information for + variable \c i is in byte <code>i>>2</code> and occupies bits 0:1 + if <code>i\%4 == 0</code>, bits 2:3 if <code>i\%4 == 1</code>, etc. + The non-member functions getStatus(const char*,int) and + setStatus(char*,int,CoinWarmStartBasis::Status) are provided to hide + details of the packing. + */ + enum Status { + isFree = 0x00, ///< Nonbasic free variable + basic = 0x01, ///< Basic variable + atUpperBound = 0x02, ///< Nonbasic at upper bound + atLowerBound = 0x03 ///< Nonbasic at lower bound + }; + + /** \brief Transfer vector entry for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef CoinTriple<int,int,int> XferEntry ; + + /** \brief Transfer vector for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef std::vector<XferEntry> XferVec ; + +public: + +/*! \name Methods to get and set basis information. + + The status of variables is kept in a pair of arrays, one for structural + variables, and one for artificials (aka logicals and slacks). The status + is coded using the values of the Status enum. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. +*/ +//@{ + /// Return the number of structural variables + inline int getNumStructural() const { return numStructural_; } + + /// Return the number of artificial variables + inline int getNumArtificial() const { return numArtificial_; } + + /** Return the number of basic structurals + + A fast test for an all-slack basis. + */ + int numberBasicStructurals() const ; + + /// Return the status of the specified structural variable. + inline Status getStructStatus(int i) const { + const int st = (structuralStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); + } + + /// Set the status of the specified structural variable. + inline void setStructStatus(int i, Status st) { + char& st_byte = structuralStatus_[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; + } + + /** Return the status array for the structural variables + + The status information is stored using the codes defined in the + Status enum, 2 bits per variable, packed 4 variables per byte. + */ + inline char * getStructuralStatus() { return structuralStatus_; } + + /** \c const overload for + \link CoinWarmStartBasis::getStructuralStatus() + getStructuralStatus() + \endlink + */ + inline const char * getStructuralStatus() const { return structuralStatus_; } + + /** As for \link getStructuralStatus() getStructuralStatus \endlink, + but returns the status array for the artificial variables. + */ + inline char * getArtificialStatus() { return artificialStatus_; } + + /// Return the status of the specified artificial variable. + inline Status getArtifStatus(int i) const { + const int st = (artificialStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); + } + + /// Set the status of the specified artificial variable. + inline void setArtifStatus(int i, Status st) { + char& st_byte = artificialStatus_[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; + } + + /** \c const overload for + \link CoinWarmStartBasis::getArtificialStatus() + getArtificialStatus() + \endlink + */ + inline const char * getArtificialStatus() const { return artificialStatus_; } + +//@} + +/*! \name Basis `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start basis passed as + a parameter to the warm start basis specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this basis + + Update this basis by applying \p diff. It's assumed that the allocated + capacity of the basis is sufficiently large. + */ + + virtual void + applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +//@} + + +/*! \name Methods to modify the warm start object */ +//@{ + + /*! \brief Set basis capacity; existing basis is discarded. + + After execution of this routine, the warm start object does not describe + a valid basis: all structural and artificial variables have status isFree. + */ + virtual void setSize(int ns, int na) ; + + /*! \brief Set basis capacity; existing basis is maintained. + + After execution of this routine, the warm start object describes a valid + basis: the status of new structural variables (added columns) is set to + nonbasic at lower bound, and the status of new artificial variables + (added rows) is set to basic. (The basis can be invalid if new structural + variables do not have a finite lower bound.) + */ + virtual void resize (int newNumberRows, int newNumberColumns); + + /** \brief Delete a set of rows from the basis + + \warning + This routine assumes that the set of indices to be deleted is sorted in + ascending order and contains no duplicates. Use deleteRows() if this is + not the case. + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void compressRows (int tgtCnt, const int *tgts) ; + + /** \brief Delete a set of rows from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void deleteRows(int rawTgtCnt, const int *rawTgts) ; + + /** \brief Delete a set of columns from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted variables + are nonbasic. + + Removal of a basic variable implies that some nonbasic variable must be + made basic. This correction is left to the client. + */ + + virtual void deleteColumns(int number, const int * which); + + /** \brief Merge entries from a source basis into this basis. + + \warning + It's the client's responsibility to ensure validity of the merged basis, + if that's important to the application. + + The vector xferCols (xferRows) specifies runs of entries to be taken from + the source basis and placed in this basis. Each entry is a CoinTriple, + with first specifying the starting source index of a run, second + specifying the starting destination index, and third specifying the run + length. + */ + virtual void mergeBasis(const CoinWarmStartBasis *src, + const XferVec *xferRows, + const XferVec *xferCols) ; + +//@} + +/*! \name Constructors, destructors, and related functions */ + +//@{ + + /** Default constructor + + Creates a warm start object representing an empty basis + (0 rows, 0 columns). + */ + CoinWarmStartBasis(); + + /** Constructs a warm start object with the specified status vectors. + + The parameters are copied. + Consider assignBasisStatus(int,int,char*&,char*&) if the object should + assume ownership. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + CoinWarmStartBasis(int ns, int na, const char* sStat, const char* aStat) ; + + /** Copy constructor */ + CoinWarmStartBasis(const CoinWarmStartBasis& ws) ; + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const + { + return new CoinWarmStartBasis(*this); + } + + /** Destructor */ + virtual ~CoinWarmStartBasis(); + + /** Assignment */ + + virtual CoinWarmStartBasis& operator=(const CoinWarmStartBasis& rhs) ; + + /** Assign the status vectors to be the warm start information. + + In this method the CoinWarmStartBasis object assumes ownership of the + pointers and upon return the argument pointers will be NULL. + If copying is desirable, use the + \link CoinWarmStartBasis(int,int,const char*,const char*) + array constructor \endlink + or the + \link operator=(const CoinWarmStartBasis&) + assignment operator \endlink. + + \note + The pointers passed to this method will be + freed using delete[], so they must be created using new[]. + */ + virtual void assignBasisStatus(int ns, int na, char*& sStat, char*& aStat) ; +//@} + +/*! \name Miscellaneous methods */ +//@{ + + /// Prints in readable format (for debug) + virtual void print() const; + /// Returns true if full basis (for debug) + bool fullBasis() const; + /// Returns true if full basis and fixes up (for debug) + bool fixFullBasis(); + +//@} + +protected: + /** \name Protected data members + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + //@{ + /// The number of structural variables + int numStructural_; + /// The number of artificial variables + int numArtificial_; + /// The maximum sise (in ints - actually 4*char) (so resize does not need to do new) + int maxSize_; + /** The status of the structural variables. */ + char * structuralStatus_; + /** The status of the artificial variables. */ + char * artificialStatus_; + //@} +}; + + +/*! \relates CoinWarmStartBasis + \brief Get the status of the specified variable in the given status array. +*/ + +inline CoinWarmStartBasis::Status getStatus(const char *array, int i) { + const int st = (array[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); +} + +/*! \relates CoinWarmStartBasis + \brief Set the status of the specified variable in the given status array. +*/ + +inline void setStatus(char * array, int i, CoinWarmStartBasis::Status st) { + char& st_byte = array[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; +} + +/*! \relates CoinWarmStartBasis + \brief Generate a print string for a status code +*/ +const char *statusName(CoinWarmStartBasis::Status status) ; + + +/*! \class CoinWarmStartBasisDiff + \brief A `diff' between two CoinWarmStartBasis objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartBasis + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartBasis::generateDiff() and CoinWarmStartBasis::applyDiff(). + + The actual data structure is an unsigned int vector, #difference_ which + starts with indices of changed and then has values starting after #sze_ + + \todo This is a pretty generic structure, and vector diff is a pretty generic + activity. We should be able to convert this to a template. + + \todo Using unsigned int as the data type for the diff vectors might help + to contain the damage when this code is inevitably compiled for 64 bit + architectures. But the notion of int as 4 bytes is hardwired into + CoinWarmStartBasis, so changes are definitely required. +*/ + +class CoinWarmStartBasisDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { CoinWarmStartBasisDiff *cwsbd = new CoinWarmStartBasisDiff(*this) ; + return (dynamic_cast<CoinWarmStartDiff *>(cwsbd)) ; } + + /*! \brief Assignment */ + virtual + CoinWarmStartBasisDiff &operator= (const CoinWarmStartBasisDiff &rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartBasisDiff(); + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartBasisDiff () : sze_(0), difference_(0) { } + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartBasisDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartBasisDiff (const CoinWarmStartBasisDiff &cwsbd) ; + + /*! \brief Standard constructor */ + CoinWarmStartBasisDiff (int sze, const unsigned int *const diffNdxs, + const unsigned int *const diffVals) ; + + /*! \brief Constructor when full is smaller than diff!*/ + CoinWarmStartBasisDiff (const CoinWarmStartBasis * rhs); + + private: + + friend CoinWarmStartDiff* + CoinWarmStartBasis::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartBasis::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Number of entries (and allocated capacity), in units of \c int. */ + int sze_ ; + + /*! \brief Array of diff indices and diff values */ + + unsigned int *difference_ ; + +} ; + + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinWarmStartDual.hpp b/thirdparty/linux/include/coin/coin/CoinWarmStartDual.hpp new file mode 100644 index 0000000..3e60d11 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinWarmStartDual.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinWarmStartDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartDual_H +#define CoinWarmStartDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int size() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /** Assign the dual vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return "dual" will + be a NULL pointer. If copying is desirable use the constructor. */ + inline void assignDual(int size, double *& dual) + { dual_.assignVector(size, dual); } + + CoinWarmStartDual() {} + + CoinWarmStartDual(int size, const double * dual) : dual_(size, dual) {} + + CoinWarmStartDual(const CoinWarmStartDual& rhs) : dual_(rhs.dual_) {} + + CoinWarmStartDual& operator=(const CoinWarmStartDual& rhs) { + if (this != &rhs) { + dual_ = rhs.dual_; + } + return *this; + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartDual(*this); + } + + virtual ~CoinWarmStartDual() {} + +/*! \name Dual warm start `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +#if 0 +protected: + inline const CoinWarmStartVector<double>& warmStartVector() const { return dual_; } +#endif + +//@} + +private: + ///@name Private data members + CoinWarmStartVector<double> dual_; +}; + +//############################################################################# + +/*! \class CoinWarmStartDualDiff + \brief A `diff' between two CoinWarmStartDual objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartDual + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartDual::generateDiff() and CoinWarmStartDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartDualDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartDualDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartDualDiff &operator= (const CoinWarmStartDualDiff &rhs) + { + if (this != &rhs) { + diff_ = rhs.diff_; + } + return *this; + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartDualDiff() {} + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartDualDiff () : diff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartDualDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartDualDiff (const CoinWarmStartDualDiff &rhs) : + diff_(rhs.diff_) {} + + private: + + friend CoinWarmStartDiff* + CoinWarmStartDual::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartDual::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Standard constructor */ + CoinWarmStartDualDiff (int sze, const unsigned int *const diffNdxs, + const double *const diffVals) : + diff_(sze, diffNdxs, diffVals) {} + + /*! + \brief The difference in the dual vector is simply the difference in a + vector. + */ + CoinWarmStartVectorDiff<double> diff_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin/coin/CoinWarmStartPrimalDual.hpp b/thirdparty/linux/include/coin/coin/CoinWarmStartPrimalDual.hpp new file mode 100644 index 0000000..c98d423 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinWarmStartPrimalDual.hpp @@ -0,0 +1,211 @@ +/* $Id: CoinWarmStartPrimalDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartPrimalDual_H +#define CoinWarmStartPrimalDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartPrimalDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int dualSize() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /// return the size of the primal vector + inline int primalSize() const { return primal_.size(); } + /// return a pointer to the array of primals + inline const double * primal() const { return primal_.values(); } + + /** Assign the primal/dual vectors to be the warmstart information. In this + method the object assumes ownership of the pointers and upon return \c + primal and \c dual will be a NULL pointers. If copying is desirable use + the constructor. + + NOTE: \c primal and \c dual must have been allocated by new double[], + because they will be freed by delete[] upon the desructtion of this + object... + */ + void assign(int primalSize, int dualSize, double*& primal, double *& dual) { + primal_.assignVector(primalSize, primal); + dual_.assignVector(dualSize, dual); + } + + CoinWarmStartPrimalDual() : primal_(), dual_() {} + + CoinWarmStartPrimalDual(int primalSize, int dualSize, + const double* primal, const double * dual) : + primal_(primalSize, primal), dual_(dualSize, dual) {} + + CoinWarmStartPrimalDual(const CoinWarmStartPrimalDual& rhs) : + primal_(rhs.primal_), dual_(rhs.dual_) {} + + CoinWarmStartPrimalDual& operator=(const CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_ = rhs.primal_; + dual_ = rhs.dual_; + } + return *this; + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + primal_.clear(); + dual_.clear(); + } + + inline void swap(CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_.swap(rhs.primal_); + dual_.swap(rhs.dual_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartPrimalDual(*this); + } + + virtual ~CoinWarmStartPrimalDual() {} + + /*! \name PrimalDual warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +#if 0 +protected: + inline const CoinWarmStartVector<double>& primalWarmStartVector() const + { return primal_; } + inline const CoinWarmStartVector<double>& dualWarmStartVector() const + { return dual_; } +#endif + +private: + ///@name Private data members + //@{ + CoinWarmStartVector<double> primal_; + CoinWarmStartVector<double> dual_; + //@} +}; + +//############################################################################# + +/*! \class CoinWarmStartPrimalDualDiff + \brief A `diff' between two CoinWarmStartPrimalDual objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartPrimalDual objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartPrimalDual::generateDiff() and + CoinWarmStartPrimalDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartPrimalDualDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartPrimalDual::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartPrimalDual::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor'. To be used when retaining polymorphism is + important */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartPrimalDualDiff(*this); + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartPrimalDualDiff() {} + +protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff () : primalDiff_(), dualDiff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing + CoinWarmStartPrimalDualDiff objects. But consider whether you should be + using #clone() to retain polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff (const CoinWarmStartPrimalDualDiff &rhs) : + primalDiff_(rhs.primalDiff_), dualDiff_(rhs.dualDiff_) {} + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + primalDiff_.clear(); + dualDiff_.clear(); + } + + inline void swap(CoinWarmStartPrimalDualDiff& rhs) { + if (this != &rhs) { + primalDiff_.swap(rhs.primalDiff_); + dualDiff_.swap(rhs.dualDiff_); + } + } + +private: + + /*! + \brief These two differences describe the differences in the primal and + in the dual vector. + */ + CoinWarmStartVectorDiff<double> primalDiff_; + CoinWarmStartVectorDiff<double> dualDiff_; +} ; + +#endif diff --git a/thirdparty/linux/include/coin/coin/CoinWarmStartVector.hpp b/thirdparty/linux/include/coin/coin/CoinWarmStartVector.hpp new file mode 100644 index 0000000..e43ea10 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/CoinWarmStartVector.hpp @@ -0,0 +1,488 @@ +/* $Id: CoinWarmStartVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartVector_H +#define CoinWarmStartVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <cassert> +#include <cmath> + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + + +//############################################################################# + +/** WarmStart information that is only a vector */ + +template <typename T> +class CoinWarmStartVector : public virtual CoinWarmStart +{ +protected: + inline void gutsOfDestructor() { + delete[] values_; + } + inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) { + size_ = rhs.size_; + values_ = new T[size_]; + CoinDisjointCopyN(rhs.values_, size_, values_); + } + +public: + /// return the size of the vector + int size() const { return size_; } + /// return a pointer to the array of vectors + const T* values() const { return values_; } + + /** Assign the vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return #vector will + be a NULL pointer. If copying is desirable use the constructor. */ + void assignVector(int size, T*& vec) { + size_ = size; + delete[] values_; + values_ = vec; + vec = NULL; + } + + CoinWarmStartVector() : size_(0), values_(NULL) {} + + CoinWarmStartVector(int size, const T* vec) : + size_(size), values_(new T[size]) { + CoinDisjointCopyN(vec, size, values_); + } + + CoinWarmStartVector(const CoinWarmStartVector& rhs) { + gutsOfCopy(rhs); + } + + CoinWarmStartVector& operator=(const CoinWarmStartVector& rhs) { + if (this != &rhs) { + gutsOfDestructor(); + gutsOfCopy(rhs); + } + return *this; + } + + inline void swap(CoinWarmStartVector& rhs) { + if (this != &rhs) { + std::swap(size_, rhs.size_); + std::swap(values_, rhs.values_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVector(*this); + } + + virtual ~CoinWarmStartVector() { + gutsOfDestructor(); + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + size_ = 0; + delete[] values_; + values_ = NULL; + } + + /*! \name Vector warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +private: + ///@name Private data members + //@{ + /// the size of the vector + int size_; + /// the vector itself + T* values_; + //@} +}; + +//============================================================================= + +/*! \class CoinWarmStartVectorDiff + \brief A `diff' between two CoinWarmStartVector objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartVector objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartVector::generateDiff() and CoinWarmStartVector::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +template <typename T> +class CoinWarmStartVectorDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVector<T>::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartVectorDiff & + operator= (const CoinWarmStartVectorDiff<T>& rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartVectorDiff() { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + + inline void swap(CoinWarmStartVectorDiff& rhs) { + if (this != &rhs) { + std::swap(sze_, rhs.sze_); + std::swap(diffNdxs_, rhs.diffNdxs_); + std::swap(diffVals_, rhs.diffVals_); + } + } + + /*! \brief Default constructor + */ + CoinWarmStartVectorDiff () : sze_(0), diffNdxs_(0), diffVals_(NULL) {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartVectorDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + */ + CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T>& rhs) ; + + /*! \brief Standard constructor */ + CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs, + const T* const diffVals) ; + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + sze_ = 0; + delete[] diffNdxs_; diffNdxs_ = NULL; + delete[] diffVals_; diffVals_ = NULL; + } + +private: + + /*! + \brief Number of entries (and allocated capacity), in units of \c T. + */ + int sze_ ; + + /*! \brief Array of diff indices */ + + unsigned int* diffNdxs_ ; + + /*! \brief Array of diff values */ + + T* diffVals_ ; +}; + +//############################################################################## + +template <typename T, typename U> +class CoinWarmStartVectorPair : public virtual CoinWarmStart +{ +private: + CoinWarmStartVector<T> t_; + CoinWarmStartVector<U> u_; + +public: + inline int size0() const { return t_.size(); } + inline int size1() const { return u_.size(); } + inline const T* values0() const { return t_.values(); } + inline const U* values1() const { return u_.values(); } + + inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); } + inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); } + + CoinWarmStartVectorPair() {} + CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) : + t_(s0, v0), u_(s1, v1) {} + + CoinWarmStartVectorPair(const CoinWarmStartVectorPair<T,U>& rhs) : + t_(rhs.t_), u_(rhs.u_) {} + CoinWarmStartVectorPair& operator=(const CoinWarmStartVectorPair<T,U>& rhs) { + if (this != &rhs) { + t_ = rhs.t_; + u_ = rhs.u_; + } + return *this; + } + + inline void swap(CoinWarmStartVectorPair<T,U>& rhs) { + t_.swap(rhs.t_); + u_.swap(rhs.u_); + } + + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVectorPair(*this); + } + + virtual ~CoinWarmStartVectorPair() {} + + inline void clear() { + t_.clear(); + u_.clear(); + } + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; +}; + +//============================================================================= + +template <typename T, typename U> +class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVectorPair<T,U>::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVectorPair<T,U>::applyDiff(const CoinWarmStartDiff *const diff) ; + +private: + CoinWarmStartVectorDiff<T> tdiff_; + CoinWarmStartVectorDiff<U> udiff_; + +public: + CoinWarmStartVectorPairDiff() {} + CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff<T,U>& rhs) : + tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {} + virtual ~CoinWarmStartVectorPairDiff() {} + + virtual CoinWarmStartVectorPairDiff& + operator=(const CoinWarmStartVectorPairDiff<T,U>& rhs) { + if (this != &rhs) { + tdiff_ = rhs.tdiff_; + udiff_ = rhs.udiff_; + } + return *this; + } + + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorPairDiff(*this) ; + } + + inline void swap(CoinWarmStartVectorPairDiff<T,U>& rhs) { + tdiff_.swap(rhs.tdiff_); + udiff_.swap(rhs.udiff_); + } + + inline void clear() { + tdiff_.clear(); + udiff_.clear(); + } +}; + +//############################################################################## +//############################################################################# + +/* + Generate a `diff' that can convert the warm start passed as a parameter to + the warm start specified by this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by this. +*/ + +template <typename T> CoinWarmStartDiff* +CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const +{ +/* + Make sure the parameter is CoinWarmStartVector or derived class. +*/ + const CoinWarmStartVector<T>* oldVector = + dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS); + if (!oldVector) + { throw CoinError("Old warm start not derived from CoinWarmStartVector.", + "generateDiff","CoinWarmStartVector") ; } + const CoinWarmStartVector<T>* newVector = this ; + /* + Make sure newVector is equal or bigger than oldVector. Calculate the worst + case number of diffs and allocate vectors to hold them. + */ + const int oldCnt = oldVector->size() ; + const int newCnt = newVector->size() ; + + assert(newCnt >= oldCnt) ; + + unsigned int *diffNdx = new unsigned int [newCnt]; + T* diffVal = new T[newCnt]; + /* + Scan the vector vectors. For the portion of the vectors which overlap, + create diffs. Then add any additional entries from newVector. + */ + const T*oldVal = oldVector->values() ; + const T*newVal = newVector->values() ; + int numberChanged = 0 ; + int i ; + for (i = 0 ; i < oldCnt ; i++) { + if (oldVal[i] != newVal[i]) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + } + for ( ; i < newCnt ; i++) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + /* + Create the object of our desire. + */ + CoinWarmStartVectorDiff<T> *diff = + new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ; + /* + Clean up and return. + */ + delete[] diffNdx ; + delete[] diffVal ; + + return diff; + // return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ; +} + + +/* + Apply diff to this warm start. + + Update this warm start by applying diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. +*/ + +template <typename T> void +CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff) +{ + /* + Make sure we have a CoinWarmStartVectorDiff + */ + const CoinWarmStartVectorDiff<T>* diff = + dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ; + if (!diff) { + throw CoinError("Diff not derived from CoinWarmStartVectorDiff.", + "applyDiff","CoinWarmStartVector") ; + } + /* + Application is by straighforward replacement of words in the vector vector. + */ + const int numberChanges = diff->sze_ ; + const unsigned int *diffNdxs = diff->diffNdxs_ ; + const T* diffVals = diff->diffVals_ ; + T* vals = this->values_ ; + + for (int i = 0 ; i < numberChanges ; i++) { + unsigned int diffNdx = diffNdxs[i] ; + T diffVal = diffVals[i] ; + vals[diffNdx] = diffVal ; + } +} + +//############################################################################# + + +// Assignment + +template <typename T> CoinWarmStartVectorDiff<T>& +CoinWarmStartVectorDiff<T>::operator=(const CoinWarmStartVectorDiff<T> &rhs) +{ + if (this != &rhs) { + if (sze_ > 0) { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + sze_ = rhs.sze_ ; + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } else { + diffNdxs_ = 0 ; + diffVals_ = 0 ; + } + } + + return (*this) ; +} + + +// Copy constructor + +template <typename T> +CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T> &rhs) + : sze_(rhs.sze_), + diffNdxs_(0), + diffVals_(0) +{ + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } +} + +/// Standard constructor + +template <typename T> +CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff +(int sze, const unsigned int *const diffNdxs, const T *const diffVals) + : sze_(sze), + diffNdxs_(0), + diffVals_(0) +{ + if (sze > 0) { + diffNdxs_ = new unsigned int[sze] ; + memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ; + diffVals_ = new T[sze] ; + memcpy(diffVals_,diffVals,sze*sizeof(T)) ; + } +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/Coin_C_defines.h b/thirdparty/linux/include/coin/coin/Coin_C_defines.h new file mode 100644 index 0000000..5c43aaa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/Coin_C_defines.h @@ -0,0 +1,115 @@ +/* $Id: Coin_C_defines.h 1690 2014-03-13 17:45:21Z mlubin $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef CoinCDefine_H +#define CoinCDefine_H + +/** This has #defines etc for the "C" interface to Coin. + If COIN_EXTERN_C defined then an extra extern C +*/ + +#if defined (CLP_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_SBB +#define COIN_NO_CBC +#endif +#if defined (SBB_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +#if defined (CBC_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +/* We need to allow for Microsoft */ +#ifndef COINLIBAPI + +#if defined(CBCCINTERFACEDLL_EXPORTS) || defined(CLPMSDLL) +#if defined (COIN_EXTERN_C) +# define COINLIBAPI __declspec(dllexport) +#else +# define COINLIBAPI __declspec(dllexport) +#endif +# define COINLINKAGE __stdcall +# define COINLINKAGE_CB __cdecl +#else +#if defined (COIN_EXTERN_C) +# define COINLIBAPI extern "C" +#else +# define COINLIBAPI +#endif +# define COINLINKAGE +# define COINLINKAGE_CB +#endif + +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (CLP_EXTERN_C) +/* Real typedef for structure */ +class CMessageHandler; +typedef struct { + ClpSimplex * model_; + CMessageHandler * handler_; +} Clp_Simplex; +#else +typedef void Clp_Simplex; +#endif + +#ifndef COIN_NO_CLP +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *clp_callback) (Clp_Simplex * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (SBB_EXTERN_C) +/* Real typedef for structure */ +class Sbb_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + SbbModel * model_; + Sbb_MessageHandler * handler_; + char * information_; +} Sbb_Model; +#else +typedef void Sbb_Model; +#endif +#if defined (CBC_EXTERN_C) +/* Real typedef for structure */ +class Cbc_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + CbcModel * model_; + Cbc_MessageHandler * handler_; + std::vector<std::string> cmdargs_; +} Cbc_Model; +#else +typedef void Cbc_Model; +#endif +#ifndef COIN_NO_SBB +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *sbb_callback) (Sbb_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +typedef void (COINLINKAGE_CB *cbc_callback) (Cbc_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif +/* just in case used somewhere */ +#undef COIN_NO_CLP +#undef COIN_NO_SBB +#undef COIN_NO_CBC +#endif diff --git a/thirdparty/linux/include/coin/coin/HSLLoader.h b/thirdparty/linux/include/coin/coin/HSLLoader.h new file mode 100644 index 0000000..c38915c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/HSLLoader.h @@ -0,0 +1,378 @@ +/* Copyright (C) 2008, 2011 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: HSLLoader.h 2317 2013-06-01 13:16:07Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef HSLLOADER_H_ +#define HSLLOADER_H_ + +#include "IpoptConfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ma77_default_control +#define ma77_control ma77_control_d +#define ma77_info ma77_info_d +#define ma77_default_control ma77_default_control_d +#define ma77_open_nelt ma77_open_nelt_d +#define ma77_open ma77_open_d +#define ma77_input_vars ma77_input_vars_d +#define ma77_input_reals ma77_input_reals_d +#define ma77_analyse ma77_analyse_d +#define ma77_factor ma77_factor_d +#define ma77_factor_solve ma77_factor_solve_d +#define ma77_solve ma77_solve_d +#define ma77_resid ma77_resid_d +#define ma77_scale ma77_scale_d +#define ma77_enquire_posdef ma77_enquire_posdef_d +#define ma77_enquire_indef ma77_enquire_indef_d +#define ma77_alter ma77_alter_d +#define ma77_restart ma77_restart_d +#define ma77_finalise ma77_finalise_d +#endif + +struct ma77_control; +struct ma77_info; +typedef double ma77pkgtype_d_; + + +#ifndef ma86_default_control +#define ma86_control ma86_control_d +#define ma86_info ma86_info_d +#define ma86_default_control ma86_default_control_d +#define ma86_analyse ma86_analyse_d +#define ma86_factor ma86_factor_d +#define ma86_factor_solve ma86_factor_solve_d +#define ma86_solve ma86_solve_d +#define ma86_finalise ma86_finalise_d +#endif + +struct ma86_control; +struct ma86_info; +typedef double ma86pkgtype_d_; +typedef double ma86realtype_d_; + +#ifndef ma97_default_control +#define ma97_control ma97_control_d +#define ma97_info ma97_info_d +#define ma97_default_control ma97_default_control_d +#define ma97_analyse ma97_analyse_d +#define ma97_factor ma97_factor_d +#define ma97_factor_solve ma97_factor_solve_d +#define ma97_solve ma97_solve_d +#define ma97_finalise ma97_finalise_d +#define ma97_free_akeep ma97_free_akeep_d +#endif + +struct ma97_control; +struct ma97_info; +typedef double ma97pkgtype_d_; +typedef double ma97realtype_d_; + +struct mc68_control_i; +struct mc68_info_i; + +#ifndef __IPTYPES_HPP__ +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; +#endif + +typedef void (*ma27ad_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + ipfint *IW, ipfint* LIW, ipfint* IKEEP, ipfint *IW1, + ipfint* NSTEPS, ipfint* IFLAG, ipfint* ICNTL, + double* CNTL, ipfint *INFO, double* OPS); +typedef void (*ma27bd_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + double* A, ipfint* LA, ipfint* IW, ipfint* LIW, + ipfint* IKEEP, ipfint* NSTEPS, ipfint* MAXFRT, + ipfint* IW1, ipfint* ICNTL, double* CNTL, + ipfint* INFO); +typedef void (*ma27cd_t)(ipfint *N, double* A, ipfint* LA, ipfint* IW, + ipfint* LIW, double* W, ipfint* MAXFRT, + double* RHS, ipfint* IW1, ipfint* NSTEPS, + ipfint* ICNTL, double* CNTL); +typedef void (*ma27id_t)(ipfint* ICNTL, double* CNTL); + +typedef void (*ma28ad_t)(void* nsize, void* nz, void* rw, void* licn, void* iw, + void* lirn, void* iw2, void* pivtol, void* iw3, void* iw4, void* rw2, void* iflag); + +typedef void (*ma57ad_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + const ipfint *irn, /* Matrix nonzero row structure */ + const ipfint *jcn, /* Matrix nonzero column structure */ + ipfint *lkeep, /* Workspace for the pivot order of lenght 3*n */ + ipfint *keep, /* Workspace for the pivot order of lenght 3*n */ + /* Automatically iflag = 0; ikeep pivot order iflag = 1 */ + ipfint *iwork, /* Integer work space. */ + ipfint *icntl, /* Integer Control parameter of length 30*/ + ipfint *info, /* Statistical Information; Integer array of length 20 */ + double *rinfo); /* Double Control parameter of length 5 */ + +typedef void (*ma57bd_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + double *a, /* Numerical values. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *lkeep, /* Length of array `keep'. */ + ipfint *keep, /* Integer array. */ + ipfint *iwork, /* Workspace of length `n'. */ + ipfint *icntl, /* Integer Control parameter of length 20. */ + double *cntl, /* Double Control parameter of length 5. */ + ipfint *info, /* Statistical Information; Integer array of length 40. */ + double *rinfo); /* Statistical Information; Real array of length 20. */ + +typedef void (*ma57cd_t) ( + ipfint *job, /* Solution job. Solve for... */ + ipfint *n, /* Order of matrix. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *nrhs, /* Number of right hand sides. */ + double *rhs, /* Numerical Values. */ + ipfint *lrhs, /* Leading dimensions of `rhs'. */ + double *work, /* Real workspace. */ + ipfint *lwork, /* Length of `work', >= N*NRHS. */ + ipfint *iwork, /* Integer array of length `n'. */ + ipfint *icntl, /* Integer Control parameter array of length 20. */ + ipfint *info); /* Statistical Information; Integer array of length 40. */ + +typedef void (*ma57ed_t) ( + ipfint *n, + ipfint *ic, /* 0: copy real array. >=1: copy integer array. */ + ipfint *keep, + double *fact, + ipfint *lfact, + double *newfac, + ipfint *lnew, + ipfint *ifact, + ipfint *lifact, + ipfint *newifc, + ipfint *linew, + ipfint *info); + +typedef void (*ma57id_t) (double *cntl, ipfint *icntl); + +typedef void (*ma77_default_control_t)(struct ma77_control_d *control); +typedef void (*ma77_open_nelt_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const int nelt); +typedef void (*ma77_open_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_vars_t)(const int idx, const int nvar, const int list[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_reals_t)(const int idx, const int length, + const double reals[], void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); +typedef void (*ma77_analyse_t)(const int order[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_factor_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_factor_solve_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale, const int nrhs, const int lx, + double rhs[]); +typedef void (*ma77_solve_t)(const int job, const int nrhs, const int lx, double x[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_resid_t)(const int nrhs, const int lx, const double x[], + const int lresid, double resid[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm_bnd); +typedef void (*ma77_scale_t)(double scale[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm); +typedef void (*ma77_enquire_posdef_t)(double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_enquire_indef_t)(int piv_order[], double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_alter_t)(const double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_restart_t)(const char *restart_file, const char *fname1, + const char *fname2, const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_finalise_t)(void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); + +typedef void (*ma86_default_control_t)(struct ma86_control *control); +typedef void (*ma86_analyse_t)(const int n, const int ptr[], const int row[], + int order[], void **keep, const struct ma86_control *control, + struct ma86_info *info); +typedef void (*ma86_factor_t)(const int n, const int ptr[], const int row[], + const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_factor_solve_t)(const int n, const int ptr[], + const int row[], const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, const int nrhs, + const int ldx, ma86pkgtype_d_ x[], const ma86pkgtype_d_ scale[]); +typedef void (*ma86_solve_t)(const int job, const int nrhs, const int ldx, + ma86pkgtype_d_ *x, const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_finalise_t)(void **keep, + const struct ma86_control *control); + +typedef void (*ma97_default_control_t)(struct ma97_control *control); +typedef void (*ma97_analyse_t)(const int check, const int n, const int ptr[], + const int row[], ma97pkgtype_d_ val[], void **akeep, + const struct ma97_control *control, struct ma97_info *info, int order[]); +typedef void (*ma97_factor_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_factor_solve_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], const int nrhs, + ma97pkgtype_d_ x[], const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_solve_t)(const int job, const int nrhs, ma97pkgtype_d_ *x, + const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info); +typedef void (*ma97_finalise_t)(void **akeep, void **fkeep); +typedef void (*ma97_free_akeep_t)(void **akeep); + +typedef void (*mc19ad_t)(ipfint *N, ipfint *NZ, double* A, ipfint *IRN, ipfint* ICN, float* R, float* C, float* W); + +typedef void (*mc68_default_control_t)(struct mc68_control_i *control); +typedef void (*mc68_order_t)(int ord, int n, const int ptr[], + const int row[], int perm[], const struct mc68_control_i *control, + struct mc68_info_i *info); + + /** Tries to load a dynamically linked library with HSL routines. + * Also tries to load symbols for those HSL routines that are not linked into Ipopt, i.e., HAVE_... is not defined. + * Return a failure if the library cannot be loaded, but not if a symbol is not found. + * @see LSL_isMA27available + * @see LSL_isMA28available + * @see LSL_isMA57available + * @see LSL_isMA77available + * @see LSL_isMA86available + * @see LSL_isMA97available + * @see LSL_isMC19available + * @param libname The name under which the HSL lib can be found, or NULL to use a default name (libhsl.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadHSL(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded HSL library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadHSL(); + + /** Indicates whether a HSL library has been loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isHSLLoaded(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA27 have been found. + * @return Zero if not available, nonzero if MA27 is available in the loaded library. + */ + int LSL_isMA27available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA28 have been found. + * @return Zero if not available, nonzero if MA28 is available in the loaded library. + */ + int LSL_isMA28available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MA57 is available in the loaded library. + */ + int LSL_isMA57available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA77 have been found. + * @return Zero if not available, nonzero if HSL_MA77 is available in the loaded library. + */ + int LSL_isMA77available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA86 have been found. + * @return Zero if not available, nonzero if HSL_MA86 is available in the loaded library. + */ + int LSL_isMA86available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA97 have been found. + * @return Zero if not available, nonzero if HSL_MA97 is available in the loaded library. + */ + int LSL_isMA97available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MC19 is available in the loaded library. + */ + int LSL_isMC19available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MC68 have been found. + * @return Zero if not available, nonzero if MC68 is available in the loaded library. + */ + int LSL_isMC68available(); + + /** Returns name of the shared library that should contain HSL */ + char* LSL_HSLLibraryName(); + + /** sets pointers to MA27 functions */ + void LSL_setMA27(ma27ad_t ma27ad, ma27bd_t ma27bd, ma27cd_t ma27cd, ma27id_t ma27id); + + /** sets pointers to MA28 functions */ + void LSL_setMA28(ma28ad_t ma28ad); + + /** sets pointers to MA57 functions */ + void LSL_setMA57(ma57ad_t ma57ad, ma57bd_t ma57bd, ma57cd_t ma57cd, ma57ed_t ma57ed, ma57id_t ma57id); + + /** sets pointers to MA77 functions */ + void LSL_setMA77(ma77_default_control_t ma77_default_control, + ma77_open_nelt_t ma77_open_nelt, + ma77_open_t ma77_open, + ma77_input_vars_t ma77_input_vars, + ma77_input_reals_t ma77_input_reals, + ma77_analyse_t ma77_analyse, + ma77_factor_t ma77_factor, + ma77_factor_solve_t ma77_factor_solve, + ma77_solve_t ma77_solve, + ma77_resid_t ma77_resid, + ma77_scale_t ma77_scale, + ma77_enquire_posdef_t ma77_enquire_posdef, + ma77_enquire_indef_t ma77_enquire_indef, + ma77_alter_t ma77_alter, + ma77_restart_t ma77_restart, + ma77_finalise_t ma77_finalise); + + /** sets pointers to MA86 functions */ + void LSL_setMA86(ma86_default_control_t ma86_default_control, + ma86_analyse_t ma86_analyse, + ma86_factor_t ma86_factor, + ma86_factor_solve_t ma86_factor_solve, + ma86_solve_t ma86_solve, + ma86_finalise_t ma86_finalise); + + /** sets pointers to MA97 functions */ + void LSL_setMA97(ma97_default_control_t ma97_default_control, + ma97_analyse_t ma97_analyse, + ma97_factor_t ma97_factor, + ma97_factor_solve_t ma97_factor_solve, + ma97_solve_t ma97_solve, + ma97_finalise_t ma97_finalise, + ma97_free_akeep_t ma97_free_akeep); + + /** sets pointer to MC19 function */ + void LSL_setMC19(mc19ad_t mc19ad); + + /** sets pointers to MC68 functions */ + void LSL_setMC68(mc68_default_control_t mc68_default_control, mc68_order_t mc68_order); + +#ifdef __cplusplus +} +#endif + +#endif /*HSLLOADER_H_*/ diff --git a/thirdparty/linux/include/coin/coin/Idiot.hpp b/thirdparty/linux/include/coin/coin/Idiot.hpp new file mode 100644 index 0000000..b675c4f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/Idiot.hpp @@ -0,0 +1,298 @@ +/* $Id: Idiot.hpp 2143 2015-05-20 15:49:17Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// "Idiot" as the name of this algorithm is copylefted. If you want to change +// the name then it should be something equally stupid (but not "Stupid") or +// even better something witty. + +#ifndef Idiot_H +#define Idiot_H +#ifndef OSI_IDIOT +#include "ClpSimplex.hpp" +#define OsiSolverInterface ClpSimplex +#else +#include "OsiSolverInterface.hpp" +typedef int CoinBigIndex; +#endif +class CoinMessageHandler; +class CoinMessages; +/// for use internally +typedef struct { + double infeas; + double objval; + double dropThis; + double weighted; + double sumSquared; + double djAtBeginning; + double djAtEnd; + int iteration; +} IdiotResult; +/** This class implements a very silly algorithm. It has no merit + apart from the fact that it gets an approximate solution to + some classes of problems. Better if vaguely homogeneous. + It works on problems where volume algorithm works and often + gets a better primal solution but it has no dual solution. + + It can also be used as a "crash" to get a problem started. This + is probably its most useful function. + + It is based on the idea that algorithms with terrible convergence + properties may be okay at first. Throw in some random dubious tricks + and the resulting code may be worth keeping as long as you don't + look at it. + +*/ + +class Idiot { + +public: + + /**@name Constructors and destructor + Just a pointer to model is kept + */ + //@{ + /// Default constructor + Idiot ( ); + /// Constructor with model + Idiot ( OsiSolverInterface & model ); + + /// Copy constructor. + Idiot(const Idiot &); + /// Assignment operator. This copies the data + Idiot & operator=(const Idiot & rhs); + /// Destructor + ~Idiot ( ); + //@} + + + /**@name Algorithmic calls + */ + //@{ + /// Get an approximate solution with the idiot code + void solve(); + /// Lightweight "crash" + void crash(int numberPass, CoinMessageHandler * handler, + const CoinMessages * messages, bool doCrossover = true); + /** Use simplex to get an optimal solution + mode is how many steps the simplex crossover should take to + arrive to an extreme point: + 0 - chosen,all ever used, all + 1 - chosen, all + 2 - all + 3 - do not do anything - maybe basis + + 16 do presolves + */ + void crossOver(int mode); + //@} + + + /**@name Gets and sets of most useful data + */ + //@{ + /** Starting weight - small emphasizes feasibility, + default 1.0e-4 */ + inline double getStartingWeight() const { + return mu_; + } + inline void setStartingWeight(double value) { + mu_ = value; + } + /** Weight factor - weight multiplied by this when changes, + default 0.333 */ + inline double getWeightFactor() const { + return muFactor_; + } + inline void setWeightFactor(double value) { + muFactor_ = value; + } + /** Feasibility tolerance - problem essentially feasible if + individual infeasibilities less than this. + default 0.1 */ + inline double getFeasibilityTolerance() const { + return smallInfeas_; + } + inline void setFeasibilityTolerance(double value) { + smallInfeas_ = value; + } + /** Reasonably feasible. Dubious method concentrates more on + objective when sum of infeasibilities less than this. + Very dubious default value of (Number of rows)/20 */ + inline double getReasonablyFeasible() const { + return reasonableInfeas_; + } + inline void setReasonablyFeasible(double value) { + reasonableInfeas_ = value; + } + /** Exit infeasibility - exit if sum of infeasibilities less than this. + Default -1.0 (i.e. switched off) */ + inline double getExitInfeasibility() const { + return exitFeasibility_; + } + inline void setExitInfeasibility(double value) { + exitFeasibility_ = value; + } + /** Major iterations. stop after this number. + Default 30. Use 2-5 for "crash" 50-100 for serious crunching */ + inline int getMajorIterations() const { + return majorIterations_; + } + inline void setMajorIterations(int value) { + majorIterations_ = value; + } + /** Minor iterations. Do this number of tiny steps before + deciding whether to change weights etc. + Default - dubious sqrt(Number of Rows). + Good numbers 105 to 405 say (5 is dubious method of making sure + idiot is not trying to be clever which it may do every 10 minor + iterations) */ + inline int getMinorIterations() const { + return maxIts2_; + } + inline void setMinorIterations(int value) { + maxIts2_ = value; + } + // minor iterations for first time + inline int getMinorIterations0() const { + return maxIts_; + } + inline void setMinorIterations0(int value) { + maxIts_ = value; + } + /** Reduce weight after this many major iterations. It may + get reduced before this but this is a maximum. + Default 3. 3-10 plausible. */ + inline int getReduceIterations() const { + return maxBigIts_; + } + inline void setReduceIterations(int value) { + maxBigIts_ = value; + } + /// Amount of information - default of 1 should be okay + inline int getLogLevel() const { + return logLevel_; + } + inline void setLogLevel(int value) { + logLevel_ = value; + } + /// How lightweight - 0 not, 1 yes, 2 very lightweight + inline int getLightweight() const { + return lightWeight_; + } + inline void setLightweight(int value) { + lightWeight_ = value; + } + /// strategy + inline int getStrategy() const { + return strategy_; + } + inline void setStrategy(int value) { + strategy_ = value; + } + /// Fine tuning - okay if feasibility drop this factor + inline double getDropEnoughFeasibility() const { + return dropEnoughFeasibility_; + } + inline void setDropEnoughFeasibility(double value) { + dropEnoughFeasibility_ = value; + } + /// Fine tuning - okay if weighted obj drop this factor + inline double getDropEnoughWeighted() const { + return dropEnoughWeighted_; + } + inline void setDropEnoughWeighted(double value) { + dropEnoughWeighted_ = value; + } + /// Set model + inline void setModel(OsiSolverInterface * model) { + model_ = model; + }; + //@} + + +/// Stuff for internal use +private: + + /// Does actual work + // allow public! +public: + void solve2(CoinMessageHandler * handler, const CoinMessages *messages); +private: + IdiotResult IdiSolve( + int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * origcost , + double * rowlower, + double * rowupper, const double * lower, + const double * upper, const double * element, + const int * row, const CoinBigIndex * colcc, + const int * length, double * lambda, + int maxIts, double mu, double drop, + double maxmin, double offset, + int strategy, double djTol, double djExit, double djFlag, + CoinThreadRandom * randomNumberGenerator); + int dropping(IdiotResult result, + double tolerance, + double small, + int *nbad); + IdiotResult objval(int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * cost , + const double * rowlower, + const double * rowupper, const double * lower, + const double * upper, const double * elemnt, + const int * row, const CoinBigIndex * columnStart, + const int * length, int extraBlock, int * rowExtra, + double * solExtra, double * elemExtra, double * upperExtra, + double * costExtra, double weight); + // Deals with whenUsed and slacks + int cleanIteration(int iteration, int ordinaryStart, int ordinaryEnd, + double * colsol, const double * lower, const double * upper, + const double * rowLower, const double * rowUpper, + const double * cost, const double * element, double fixTolerance, double & objChange, + double & infChange, double & maxInfeasibility); +private: + /// Underlying model + OsiSolverInterface * model_; + + double djTolerance_; + double mu_; /* starting mu */ + double drop_; /* exit if drop over 5 checks less than this */ + double muFactor_; /* reduce mu by this */ + double stopMu_; /* exit if mu gets smaller than this */ + double smallInfeas_; /* feasibility tolerance */ + double reasonableInfeas_; /* use lambdas if feasibility less than this */ + double exitDrop_; /* candidate for stopping after a major iteration */ + double muAtExit_; /* mu on exit */ + double exitFeasibility_; /* exit if infeasibility less than this */ + double dropEnoughFeasibility_; /* okay if feasibility drop this factor */ + double dropEnoughWeighted_; /* okay if weighted obj drop this factor */ + int * whenUsed_; /* array to say what was used */ + int maxBigIts_; /* always reduce mu after this */ + int maxIts_; /* do this many iterations on first go */ + int majorIterations_; + int logLevel_; + int logFreq_; + int checkFrequency_; /* can exit after 5 * this iterations (on drop) */ + int lambdaIterations_; /* do at least this many lambda iterations */ + int maxIts2_; /* do this many iterations on subsequent goes */ + int strategy_; /* 0 - default strategy + 1 - do accelerator step but be cautious + 2 - do not do accelerator step + 4 - drop, exitDrop and djTolerance all relative + 8 - keep accelerator step to theta=10.0 + + 32 - Scale + 512 - crossover + 2048 - keep lambda across mu change + 4096 - return best solution (not last found) + 8192 - always do a presolve in crossover + 16384 - costed slacks found - so whenUsed_ longer + 32768 - experimental 1 + 65536 - experimental 2 + 131072 - experimental 3 + 262144 - just values pass etc + 524288 - don't treat structural slacks as slacks */ + + int lightWeight_; // 0 - normal, 1 lightweight +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/IpAlgBuilder.hpp b/thirdparty/linux/include/coin/coin/IpAlgBuilder.hpp new file mode 100644 index 0000000..05692bb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpAlgBuilder.hpp @@ -0,0 +1,360 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgBuilder.hpp 2666 2016-07-20 16:02:55Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-29 + +#ifndef __IPALGBUILDER_HPP__ +#define __IPALGBUILDER_HPP__ + +#include "IpIpoptAlg.hpp" +#include "IpReferenced.hpp" +#include "IpAugSystemSolver.hpp" +#include "IpPDSystemSolver.hpp" + +namespace Ipopt +{ + + // forward declarations + class IterationOutput; + class HessianUpdater; + class ConvergenceCheck; + class SearchDirectionCalculator; + class EqMultiplierCalculator; + class IterateInitializer; + class LineSearch; + class MuUpdate; + + /** Builder for creating a complete IpoptAlg object. This object + * contains all subelements (such as line search objects etc). How + * the resulting IpoptAlg object is built can be influenced by the + * options. + * + * More advanced customization can be achieved by subclassing this + * class and overloading the virtual methods that build the + * individual parts. The advantage of doing this is that it allows + * one to reuse the extensive amount of options processing that + * takes place, for instance, when generating the symmetric linear + * system solver. Another method for customizing the algorithm is + * using the optional custom_solver argument, which allows the + * expert user to provide a specialized linear solver for the + * augmented system (e.g., type GenAugSystemSolver), possibly for + * user-defined matrix objects. The optional custom_solver constructor + * argument is likely obsolete, however, as more control over this + * this process can be achieved by implementing a subclass of this + * AlgBuilder (e.g., by overloading the AugSystemSolverFactory method). + */ + class AlgorithmBuilder : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + AlgorithmBuilder(SmartPtr<AugSystemSolver> custom_solver=NULL); + + /** Destructor */ + virtual ~AlgorithmBuilder() + {} + + //@} + + /** Methods for IpoptTypeInfo */ + //@{ + /** register the options used by the algorithm builder */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** @name Convenience methods for building solvers without having + * to duplicate the significant amount of preprocessor flag and + * option checking that takes place. These solvers are used to + * create a number of core algorithm components across the + * different Build* methods, but depending on what options are + * chosen, the first method requiring the solver to be used can + * vary. Therefore, each of the Factory methods below is paired + * with a Getter method, which is called by all parts of this + * algorithm builder to ensure the Factory is only called once. */ + //@{ + + /** Create a solver that can be used to solve a symmetric linear + * system. + * Dependencies: None + */ + virtual SmartPtr<SymLinearSolver> + SymLinearSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the symmetric linear system solver for this + * algorithm. This method will call the SymLinearSolverFactory + * exactly once (the first time it is used), and store its + * instance on SymSolver_ for use in subsequent calls. + */ + SmartPtr<SymLinearSolver> GetSymLinearSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve an + * augmented system. + * Dependencies: + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<AugSystemSolver> + AugSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the augmented system solver for this algorithm. This + * method will call the AugSystemSolverFactory exactly once (the + * first time it is used), and store its instance on AugSolver_ + * for use in subsequent calls. + */ + SmartPtr<AugSystemSolver> GetAugSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve a + * primal-dual system. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<PDSystemSolver> + PDSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the primal-dual system solver for this algorithm. This + * method will call the PDSystemSolverFactory exactly once (the + * first time it is used), and store its instance on PDSolver_ + * for use in subsequent calls. + */ + SmartPtr<PDSystemSolver> GetPDSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + /** @name Methods to build parts of the algorithm */ + //@{ + /** Allocates memory for the IpoptNLP, IpoptData, and + * IpoptCalculatedQuanties arguments. + * Dependencies: None + */ + virtual void BuildIpoptObjects(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix, + const SmartPtr<NLP>& nlp, + SmartPtr<IpoptNLP>& ip_nlp, + SmartPtr<IpoptData>& ip_data, + SmartPtr<IpoptCalculatedQuantities>& ip_cq); + + /** Creates an instance of the IpoptAlgorithm class by building + * each of its required constructor arguments piece-by-piece. The + * default algorithm can be customized by overloading this method + * or by overloading one or more of the Build* methods called in + * this method's default implementation. Additional control can + * be achieved by overloading any of the *SolverFactory methods. + * This method will call (in this order): + * -> BuildIterationOutput() + * -> BuildHessianUpdater() + * -> BuildConvergenceCheck() + * -> BuildSearchDirectionCalculator() + * -> BuildEqMultiplierCalculator() + * -> BuildIterateInitializer() + * -> BuildLineSearch() + * -> BuildMuUpdate() + */ + virtual SmartPtr<IpoptAlgorithm> BuildBasicAlgorithm(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterationOutput class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<IterationOutput> + BuildIterationOutput(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the HessianUpdater class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<HessianUpdater> + BuildHessianUpdater(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the ConvergenceCheck class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<ConvergenceCheck> + BuildConvergenceCheck(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the SearchDirectionCalculator + * class. This method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<SearchDirectionCalculator> + BuildSearchDirectionCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the EqMultiplierCalculator class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<EqMultiplierCalculator> + BuildEqMultiplierCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterateInitializer class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<IterateInitializer> + BuildIterateInitializer(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the LineSearch class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<LineSearch> BuildLineSearch(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the MuUpdate class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> LineSearch_ + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<MuUpdate> BuildMuUpdate(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmBuilder(); + + /** Copy Constructor */ + AlgorithmBuilder(const AlgorithmBuilder&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmBuilder&); + //@} + + /** @name IpoptAlgorithm constructor arguments. + * These components are built in separate Build + * methods in the order defined by BuildBasicAlgorithm. + * A single core component may require one or more + * other core components in its constructor, so the + * this class holds pointers to each component for use + * between the separate Build methods. */ + //@{ + SmartPtr<IterationOutput> IterOutput_; + SmartPtr<HessianUpdater> HessUpdater_; + SmartPtr<ConvergenceCheck> ConvCheck_; + SmartPtr<SearchDirectionCalculator> SearchDirCalc_; + SmartPtr<EqMultiplierCalculator> EqMultCalculator_; + SmartPtr<IterateInitializer> IterInitializer_; + SmartPtr<LineSearch> LineSearch_; + SmartPtr<MuUpdate> MuUpdate_; + //@} + + /** @name Commonly used solver components + * for building core algorithm components. Each + * of these members is paired with a Factory/Getter + * method. */ + //@{ + SmartPtr<SymLinearSolver> SymSolver_; + SmartPtr<AugSystemSolver> AugSolver_; + SmartPtr<PDSystemSolver> PDSolver_; + //@} + + /** Optional pointer to AugSystemSolver. If this is set in the + * contructor, we will use this to solve the linear systems. */ + SmartPtr<AugSystemSolver> custom_solver_; + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpAlgStrategy.hpp b/thirdparty/linux/include/coin/coin/IpAlgStrategy.hpp new file mode 100644 index 0000000..746a968 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpAlgStrategy.hpp @@ -0,0 +1,185 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgStrategy.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPALGSTRATEGY_HPP__ +#define __IPALGSTRATEGY_HPP__ + +#include "IpOptionsList.hpp" +#include "IpJournalist.hpp" +#include "IpIpoptCalculatedQuantities.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" + +namespace Ipopt +{ + + /** This is the base class for all algorithm strategy objects. The + * AlgorithmStrategyObject base class implements a common interface + * for all algorithm strategy objects. A strategy object is a + * component of the algorithm for which different alternatives or + * implementations exists. It allows to compose the algorithm + * before execution for a particular configuration, without the + * need to call alternatives based on enums. For example, the + * LineSearch object is a strategy object, since different line + * search options might be used for different runs. + * + * This interface is used for + * things that are done to all strategy objects, like + * initialization and setting options. + */ + class AlgorithmStrategyObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + AlgorithmStrategyObject() + : + initialize_called_(false) + {} + + /** Default Destructor */ + virtual ~AlgorithmStrategyObject() + {} + //@} + + /** This method is called every time the algorithm starts again - + * it is used to reset any internal state. The pointers to the + * Journalist, as well as to the IpoptNLP, IpoptData, and + * IpoptCalculatedQuantities objects should be stored in the + * instanciation of this base class. This method is also used to + * get all required user options from the OptionsList. Here, if + * prefix is given, each tag (identifying the options) is first + * looked for with the prefix in front, and if not found, without + * the prefix. Note: you should not cue off of the iteration + * count to indicate the "start" of an algorithm! + * + * Do not overload this method, since it does some general + * initialization that is common for all strategy objects. + * Overload the protected InitializeImpl method instead. + */ + bool Initialize(const Journalist& jnlst, + IpoptNLP& ip_nlp, + IpoptData& ip_data, + IpoptCalculatedQuantities& ip_cq, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = &ip_nlp; + ip_data_ = &ip_data; + ip_cq_ = &ip_cq; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + /** Reduced version of the Initialize method, which does not + * require special Ipopt information. This is useful for + * algorithm objects that could be used outside Ipopt, such as + * linear solvers. */ + bool ReducedInitialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = NULL; + ip_data_ = NULL; + ip_cq_ = NULL; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** @name Accessor methods for the problem defining objects. + * Those should be used by the derived classes. */ + //@{ + const Journalist& Jnlst() const + { + DBG_ASSERT(initialize_called_); + return *jnlst_; + } + IpoptNLP& IpNLP() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_nlp_)); + return *ip_nlp_; + } + IpoptData& IpData() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_data_)); + return *ip_data_; + } + IpoptCalculatedQuantities& IpCq() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_cq_)); + return *ip_cq_; + } + bool HaveIpData() const + { + return IsValid(ip_data_); + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmStrategyObject(); + + + /** Copy Constructor */ + AlgorithmStrategyObject(const AlgorithmStrategyObject&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmStrategyObject&); + //@} + + /** @name Pointers to objects defining a particular optimization + * problem */ + //@{ + SmartPtr<const Journalist> jnlst_; + SmartPtr<IpoptNLP> ip_nlp_; + SmartPtr<IpoptData> ip_data_; + SmartPtr<IpoptCalculatedQuantities> ip_cq_; + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpAlgTypes.hpp b/thirdparty/linux/include/coin/coin/IpAlgTypes.hpp new file mode 100644 index 0000000..53e8ea5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpAlgTypes.hpp @@ -0,0 +1,66 @@ +// Copyright (C) 2005, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgTypes.hpp 2551 2015-02-13 02:51:47Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-07-19 + +#ifndef __IPALGTYPES_HPP__ +#define __IPALGTYPES_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + /**@name Enumerations */ + //@{ + /** enum for the return from the optimize algorithm + * (obviously we need to add more) */ + enum SolverReturn { + SUCCESS, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + STOP_AT_TINY_STEP, + STOP_AT_ACCEPTABLE_POINT, + LOCAL_INFEASIBILITY, + USER_REQUESTED_STOP, + FEASIBLE_POINT_FOUND, + DIVERGING_ITERATES, + RESTORATION_FAILURE, + ERROR_IN_STEP_COMPUTATION, + INVALID_NUMBER_DETECTED, + TOO_FEW_DEGREES_OF_FREEDOM, + INVALID_OPTION, + OUT_OF_MEMORY, + INTERNAL_ERROR, + UNASSIGNED + }; + //@} + + /** @name Some exceptions used in multiple places */ + //@{ + DECLARE_STD_EXCEPTION(LOCALLY_INFEASIBLE); + DECLARE_STD_EXCEPTION(TOO_FEW_DOF); + DECLARE_STD_EXCEPTION(TINY_STEP_DETECTED); + DECLARE_STD_EXCEPTION(ACCEPTABLE_POINT_REACHED); + DECLARE_STD_EXCEPTION(FEASIBILITY_PROBLEM_SOLVED); + DECLARE_STD_EXCEPTION(INVALID_WARMSTART); + DECLARE_STD_EXCEPTION(INTERNAL_ABORT); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_BUT_FEASIBLE); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_AND_INFEASIBLE); + DECLARE_STD_EXCEPTION(INCONSISTENT_BOUNDS); + /** Exception FAILED_INITIALIZATION for problem during + * initialization of a strategy object (or other problems). This + * is thrown by a strategy object, if a problem arises during + * initialization, such as a value out of a feasible range. + */ + DECLARE_STD_EXCEPTION(FAILED_INITIALIZATION); + //@} + + +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpAugSystemSolver.hpp b/thirdparty/linux/include/coin/coin/IpAugSystemSolver.hpp new file mode 100644 index 0000000..1396ce4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpAugSystemSolver.hpp @@ -0,0 +1,200 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAugSystemSolver.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IP_AUGSYSTEMSOLVER_HPP__ +#define __IP_AUGSYSTEMSOLVER_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpSymLinearSolver.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(FATAL_ERROR_IN_LINEAR_SOLVER); + + /** Base class for Solver for the augmented system. This is the + * base class for linear solvers that solve the augmented system, + * which is defined as + * + * \f$\left[\begin{array}{cccc} + * W + D_x + \delta_xI & 0 & J_c^T & J_d^T\\ + * 0 & D_s + \delta_sI & 0 & -I \\ + * J_c & 0 & D_c - \delta_cI & 0\\ + * J_d & -I & 0 & D_d - \delta_dI + * \end{array}\right] + * \left(\begin{array}{c}sol_x\\sol_s\\sol_c\\sol_d\end{array}\right)= + * \left(\begin{array}{c}rhs_x\\rhs_s\\rhs_c\\rhs_d\end{array}\right)\f$ + * + * Since this system might be solved repeatedly for different right + * hand sides, it is desirable to step the factorization of a + * direct linear solver if possible. + */ + class AugSystemSolver: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + AugSystemSolver() + {} + /** Default destructor */ + virtual ~AugSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Set up the augmented system and solve it for a given right hand + * side. If desired (i.e. if check_NegEVals is true), then the + * solution is only computed if the number of negative eigenvalues + * matches numberOfNegEVals. + * + * The return value is the return value of the linear solver object. + */ + virtual ESymSolverStatus Solve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + const Vector& rhs_x, + const Vector& rhs_s, + const Vector& rhs_c, + const Vector& rhs_d, + Vector& sol_x, + Vector& sol_s, + Vector& sol_c, + Vector& sol_d, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector<SmartPtr<const Vector> > rhs_xV(1); + rhs_xV[0] = &rhs_x; + std::vector<SmartPtr<const Vector> > rhs_sV(1); + rhs_sV[0] = &rhs_s; + std::vector<SmartPtr<const Vector> > rhs_cV(1); + rhs_cV[0] = &rhs_c; + std::vector<SmartPtr<const Vector> > rhs_dV(1); + rhs_dV[0] = &rhs_d; + std::vector<SmartPtr<Vector> > sol_xV(1); + sol_xV[0] = &sol_x; + std::vector<SmartPtr<Vector> > sol_sV(1); + sol_sV[0] = &sol_s; + std::vector<SmartPtr<Vector> > sol_cV(1); + sol_cV[0] = &sol_c; + std::vector<SmartPtr<Vector> > sol_dV(1); + sol_dV[0] = &sol_d; + return MultiSolve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, + J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, + sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, + numberOfNegEVals); + } + + /** Like Solve, but for multiple right hand sides. The inheriting + * class has to be overload at least one of Solve and + * MultiSolve. */ + virtual ESymSolverStatus MultiSolve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + std::vector<SmartPtr<const Vector> >& rhs_xV, + std::vector<SmartPtr<const Vector> >& rhs_sV, + std::vector<SmartPtr<const Vector> >& rhs_cV, + std::vector<SmartPtr<const Vector> >& rhs_dV, + std::vector<SmartPtr<Vector> >& sol_xV, + std::vector<SmartPtr<Vector> >& sol_sV, + std::vector<SmartPtr<Vector> >& sol_cV, + std::vector<SmartPtr<Vector> >& sol_dV, + bool check_NegEVals, + Index numberOfNegEVals) + { + // Solve for one right hand side after the other + Index nrhs = (Index)rhs_xV.size(); + DBG_ASSERT(nrhs>0); + DBG_ASSERT(nrhs==(Index)rhs_sV.size()); + DBG_ASSERT(nrhs==(Index)rhs_cV.size()); + DBG_ASSERT(nrhs==(Index)rhs_dV.size()); + DBG_ASSERT(nrhs==(Index)sol_xV.size()); + DBG_ASSERT(nrhs==(Index)sol_sV.size()); + DBG_ASSERT(nrhs==(Index)sol_cV.size()); + DBG_ASSERT(nrhs==(Index)sol_dV.size()); + + ESymSolverStatus retval=SYMSOLVER_SUCCESS; + for (Index i=0; i<nrhs; i++) { + retval = Solve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, + J_d, D_d, delta_d, + *rhs_xV[i], *rhs_sV[i], *rhs_cV[i], *rhs_dV[i], + *sol_xV[i], *sol_sV[i], *sol_cV[i], *sol_dV[i], + check_NegEVals, numberOfNegEVals); + if (retval!=SYMSOLVER_SUCCESS) { + break; + } + } + return retval; + } + + /** Number of negative eigenvalues detected during last + * solve. Returns the number of negative eigenvalues of + * the most recent factorized matrix. This must not be called if + * the linear solver does not compute this quantities (see + * ProvidesInertia). + */ + virtual Index NumberOfNegEVals() const =0; + + /** Query whether inertia is computed by linear solver. + * Returns true, if linear solver provides inertia. + */ + virtual bool ProvidesInertia() const =0; + + /** Request to increase quality of solution for next solve. Ask + * underlying linear solver to increase quality of solution for + * the next solve (e.g. increase pivot tolerance). Returns + * false, if this is not possible (e.g. maximal pivot tolerance + * already used.) + */ + virtual bool IncreaseQuality() =0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + AugSystemSolver(const AugSystemSolver&); + + /** Overloaded Equals Operator */ + void operator=(const AugSystemSolver&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpBlas.hpp b/thirdparty/linux/include/coin/coin/IpBlas.hpp new file mode 100644 index 0000000..517057b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpBlas.hpp @@ -0,0 +1,78 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpBlas.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPBLAS_HPP__ +#define __IPBLAS_HPP__ + +#include "IpUtils.hpp" + +namespace Ipopt +{ + // If CBLAS is not available, this is our own interface to the Fortran + // implementation + + /** Wrapper for BLAS function DDOT. Compute dot product of vector x + and vector y */ + Number IpBlasDdot(Index size, const Number *x, Index incX, const Number *y, + Index incY); + + /** Wrapper for BLAS function DNRM2. Compute 2-norm of vector x*/ + Number IpBlasDnrm2(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS function DASUM. Compute 1-norm of vector x*/ + Number IpBlasDasum(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS function IDAMAX. Compute index for largest + absolute element of vector x */ + Index IpBlasIdamax(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS subroutine DCOPY. Copying vector x into vector + y */ + void IpBlasDcopy(Index size, const Number *x, Index incX, Number *y, + Index incY); + + /** Wrapper for BLAS subroutine DAXPY. Adding the alpha multiple of + vector x to vector y */ + void IpBlasDaxpy(Index size, Number alpha, const Number *x, Index incX, + Number *y, Index incY); + + /** Wrapper for BLAS subroutine DSCAL. Scaling vector x by scalar + alpha */ + void IpBlasDscal(Index size, Number alpha, Number *x, Index incX); + + /** Wrapper for BLAS subroutine DGEMV. Multiplying a matrix with a + vector. */ + void IpBlasDgemv(bool trans, Index nRows, Index nCols, Number alpha, + const Number* A, Index ldA, const Number* x, + Index incX, Number beta, Number* y, Index incY); + + /** Wrapper for BLAS subroutine DSYMV. Multiplying a symmetric + matrix with a vector. */ + void IpBlasDsymv(Index n, Number alpha, const Number* A, Index ldA, + const Number* x, Index incX, Number beta, Number* y, + Index incY); + + /** Wrapper for BLAS subroutine DGEMM. Multiplying two matrices */ + void IpBlasDgemm(bool transa, bool transb, Index m, Index n, Index k, + Number alpha, const Number* A, Index ldA, const Number* B, + Index ldB, Number beta, Number* C, Index ldC); + + /** Wrapper for BLAS subroutine DSYRK. Adding a high-rank update to + * a matrix */ + void IpBlasDsyrk(bool trans, Index ndim, Index nrank, + Number alpha, const Number* A, Index ldA, + Number beta, Number* C, Index ldC); + + /** Wrapper for BLAS subroutine DTRSM. Backsolve for a lower triangular + * matrix. */ + void IpBlasDtrsm(bool trans, Index ndim, Index nrhs, Number alpha, + const Number* A, Index ldA, Number* B, Index ldB); + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpCachedResults.hpp b/thirdparty/linux/include/coin/coin/IpCachedResults.hpp new file mode 100644 index 0000000..b9f5f15 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpCachedResults.hpp @@ -0,0 +1,779 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCachedResults.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCACHEDRESULTS_HPP__ +#define __IPCACHEDRESULTS_HPP__ + +#include "IpTaggedObject.hpp" +#include "IpObserver.hpp" +#include <algorithm> +#include <vector> +#include <list> + +namespace Ipopt +{ + +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_CACHE +#endif +#ifdef IP_DEBUG_CACHE +# include "IpDebug.hpp" +#endif + + // Forward Declarations + + template <class T> + class DependentResult; + + // AW: I'm taking this out, since this is by far the most used + // class. We should keep it as simple as possible. + // /** Cache Priority Enum */ + // enum CachePriority + // { + // CP_Lowest, + // CP_Standard, + // CP_Trial, + // CP_Iterate + // }; + + /** Templated class for Cached Results. This class stores up to a + * given number of "results", entities that are stored here + * together with identifiers, that can be used to later retrieve the + * information again. + * + * Typically, T is a SmartPtr for some calculated quantity that + * should be stored (such as a Vector). The identifiers (or + * dependencies) are a (possibly varying) number of Tags from + * TaggedObjects, and a number of Numbers. Results are added to + * the cache using the AddCachedResults methods, and the can be + * retrieved with the GetCachedResults methods. The second set of + * methods checks whether a result has been cached for the given + * identifiers. If a corresponding result is found, a copy of it + * is returned and the method evaluates to true, otherwise it + * evaluates to false. + * + * Note that cached results can become "stale", namely when a + * TaggedObject that is used to identify this CachedResult is + * changed. When this happens, the cached result can never be + * asked for again, so that there is no point in storing it any + * longer. For this purpose, a cached result, which is stored as a + * DependentResult, inherits off an Observer. This Observer + * retrieves notification whenever a TaggedObject dependency has + * changed. Stale results are later removed from the cache. + */ + template <class T> + class CachedResults + { + public: +#ifdef IP_DEBUG_CACHE + /** (Only if compiled in DEBUG mode): debug verbosity level */ + static const Index dbg_verbosity; +#endif + + /** @name Constructors and Destructors. */ + //@{ + /** Constructor, where max_cache_size is the maximal number of + * results that should be cached. If max_cache_size is negative, + * we allow an infinite amount of cache. + */ + CachedResults(Int max_cache_size); + + /** Destructor */ + virtual ~CachedResults(); + //@} + + /** @name Generic methods for adding and retrieving cached results. */ + //@{ + /** Generic method for adding a result to the cache, given a + * std::vector of TaggesObjects and a std::vector of Numbers. + */ + void AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Generic method for retrieving a cached results, given the + * dependencies as a std::vector of TaggesObjects and a + * std::vector of Numbers. + */ + bool GetCachedResult(T& retResult, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const; + + /** Method for adding a result, providing only a std::vector of + * TaggedObjects. + */ + void AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents); + + /** Method for retrieving a cached result, providing only a + * std::vector of TaggedObjects. + */ + bool GetCachedResult(T& retResult, + const std::vector<const TaggedObject*>& dependents) const; + //@} + + /** @name Pointer-based methods for adding and retrieving cached + * results, providing dependencies explicitly. + */ + //@{ + /** Method for adding a result to the cache, proving one + * dependency as a TaggedObject explicitly. + */ + void AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1); + + /** Method for retrieving a cached result, proving one dependency + * as a TaggedObject explicitly. + */ + bool GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1); + + /** Method for adding a result to the cache, proving two + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult2Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for retrieving a cached result, proving two + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult2Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for adding a result to the cache, proving three + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult3Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** Method for retrieving a cached result, proving three + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult3Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** @name Pointer-free version of the Add and Get methods */ + //@{ + bool GetCachedResult1Dep(T& retResult, const TaggedObject& dependent1) + { + return GetCachedResult1Dep(retResult, &dependent1); + } + bool GetCachedResult2Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + return GetCachedResult2Dep(retResult, &dependent1, &dependent2); + } + bool GetCachedResult3Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + return GetCachedResult3Dep(retResult, &dependent1, &dependent2, &dependent3); + } + void AddCachedResult1Dep(const T& result, + const TaggedObject& dependent1) + { + AddCachedResult1Dep(result, &dependent1); + } + void AddCachedResult2Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + AddCachedResult2Dep(result, &dependent1, &dependent2); + } + void AddCachedResult3Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + AddCachedResult3Dep(result, &dependent1, &dependent2, &dependent3); + } + //@} + + /** Invalidates the result for given dependencies. Sets the stale + * flag for the corresponding cached result to true if it is + * found. Returns true, if the result was found. */ + bool InvalidateResult(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Invalidates all cached results */ + void Clear(); + + /** Invalidate all cached results and changes max_cache_size */ + void Clear(Int max_cache_size); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CachedResults(); + + /** Copy Constructor */ + CachedResults(const CachedResults&); + + /** Overloaded Equals Operator */ + void operator=(const CachedResults&); + //@} + + /** maximum number of cached results */ + Int max_cache_size_; + + /** list of currently cached results. */ + mutable std::list<DependentResult<T>*>* cached_results_; + + /** internal method for removing stale DependentResults from the + * list. It is called at the beginning of every + * GetDependentResult method. + */ + void CleanupInvalidatedResults() const; + + /** Print list of currently cached results */ + void DebugPrintCachedResults() const; + }; + + /** Templated class which stores one entry for the CachedResult + * class. It stores the result (of type T), together with its + * dependencies (vector of TaggedObjects and vector of Numbers). + * It also stores a priority. + */ + template <class T> + class DependentResult : public Observer + { + public: + +#ifdef IP_DEBUG_CACHE + static const Index dbg_verbosity; +#endif + + /** @name Constructor, Destructors */ + //@{ + /** Constructor, given all information about the result. */ + DependentResult(const T& result, const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Destructor. */ + ~DependentResult(); + //@} + + /** @name Accessor method. */ + //@{ + /** This returns true, if the DependentResult is no longer valid. */ + bool IsStale() const; + + /** Invalidates the cached result. */ + void Invalidate(); + + /** Returns the cached result. */ + const T& GetResult() const; + //@} + + /** This method returns true if the dependencies provided to this + * function are identical to the ones stored with the + * DependentResult. + */ + bool DependentsIdentical(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const; + + /** Print information about this DependentResults. */ + void DebugPrint() const; + + protected: + /** This method is overloading the pure virtual method from the + * Observer base class. This method is called when a Subject + * registered for this Observer sends a notification. In this + * particular case, if this method is called with + * notify_type==NT_Changed or NT_BeingDeleted, then this results + * is marked as stale. + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DependentResult(); + + /** Copy Constructor */ + DependentResult(const DependentResult&); + + /** Overloaded Equals Operator */ + void operator=(const DependentResult&); + //@} + + /** Flag indicating, if the cached result is still valid. A + result becomes invalid, if the RecieveNotification method is + called with NT_Changed */ + bool stale_; + /** The value of the dependent results */ + const T result_; + /** Dependencies in form of TaggedObjects */ + std::vector<TaggedObject::Tag> dependent_tags_; + /** Dependencies in form a Numbers */ + std::vector<Number> scalar_dependents_; + }; + +#ifdef IP_DEBUG_CACHE + template <class T> + const Index CachedResults<T>::dbg_verbosity = 0; + + template <class T> + const Index DependentResult<T>::dbg_verbosity = 0; +#endif + + template <class T> + DependentResult<T>::DependentResult( + const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + : + stale_(false), + result_(result), + dependent_tags_(dependents.size()), + scalar_dependents_(scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DependentResult()", dbg_verbosity); +#endif + + for (Index i=0; i<(Index)dependents.size(); i++) { + if (dependents[i]) { + // Call the RequestAttach method of the Observer base class. + // This will add this dependent result in the Observer list + // for the Subject dependents[i]. As a consequence, the + // RecieveNotification method of this DependentResult will be + // called with notify_type=NT_Changed, whenever the + // TaggedResult dependents[i] is changed (i.e. its HasChanged + // method is called). + RequestAttach(NT_Changed, dependents[i]); + dependent_tags_[i] = dependents[i]->GetTag(); + } + else { + dependent_tags_[i] = 0; + } + } + } + + template <class T> + DependentResult<T>::~DependentResult() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::~DependentResult()", dbg_verbosity); + //DBG_ASSERT(stale_ == true); +#endif + // Nothing to be done here, destructor + // of T should sufficiently remove + // any memory, etc. + } + + template <class T> + bool DependentResult<T>::IsStale() const + { + return stale_; + } + + template <class T> + void DependentResult<T>::Invalidate() + { + stale_ = true; + } + + template <class T> + void DependentResult<T>::RecieveNotification(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::RecieveNotification", dbg_verbosity); +#endif + + if (notify_type == NT_Changed || notify_type==NT_BeingDestroyed) { + stale_ = true; + // technically, I could unregister the notifications here, but they + // aren't really hurting anything + } + } + + template <class T> + bool DependentResult<T>::DependentsIdentical(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DependentsIdentical", dbg_verbosity); + DBG_ASSERT(stale_ == false); + DBG_ASSERT(dependents.size() == dependent_tags_.size()); +#endif + + bool retVal = true; + + if (dependents.size() != dependent_tags_.size() + || scalar_dependents.size() != scalar_dependents_.size()) { + retVal = false; + } + else { + for (Index i=0; i<(Index)dependents.size(); i++) { + if ( (dependents[i] && dependents[i]->GetTag() != dependent_tags_[i]) + || (!dependents[i] && dependent_tags_[i] != 0) ) { + retVal = false; + break; + } + } + if (retVal) { + for (Index i=0; i<(Index)scalar_dependents.size(); i++) { + if (scalar_dependents[i] != scalar_dependents_[i]) { + retVal = false; + break; + } + } + } + } + + return retVal; + } + + template <class T> + const T& DependentResult<T>::GetResult() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::GetResult()", dbg_verbosity); + DBG_ASSERT(stale_ == false); +#endif + + return result_; + } + + template <class T> + void DependentResult<T>::DebugPrint() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DebugPrint", dbg_verbosity); +#endif + + } + + template <class T> + CachedResults<T>::CachedResults(Int max_cache_size) + : + max_cache_size_(max_cache_size), + cached_results_(NULL) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::CachedResults", dbg_verbosity); +#endif + + } + + template <class T> + CachedResults<T>::~CachedResults() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::!CachedResults()", dbg_verbosity); +#endif + + if (cached_results_) { + for (typename std::list< DependentResult<T>* >::iterator iter = cached_results_-> + begin(); + iter != cached_results_->end(); + iter++) { + delete *iter; + } + delete cached_results_; + } + /* + while (!cached_results_.empty()) { + DependentResult<T>* result = cached_results_.back(); + cached_results_.pop_back(); + delete result; + } + */ + } + + template <class T> + void CachedResults<T>::AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult", dbg_verbosity); +#endif + + CleanupInvalidatedResults(); + + // insert the new one here + DependentResult<T>* newResult = new DependentResult<T>(result, dependents, scalar_dependents); + if (!cached_results_) { + cached_results_ = new std::list<DependentResult<T>*>; + } + cached_results_->push_front(newResult); + + // keep the list small enough + if (max_cache_size_ >= 0) { // if negative, allow infinite cache + // non-negative - limit size of list to max_cache_size + DBG_ASSERT((Int)cached_results_->size()<=max_cache_size_+1); + if ((Int)cached_results_->size() > max_cache_size_) { + delete cached_results_->back(); + cached_results_->pop_back(); + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + } + + template <class T> + void CachedResults<T>::AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents) + { + std::vector<Number> scalar_dependents; + AddCachedResult(result, dependents, scalar_dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult(T& retResult, const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult", dbg_verbosity); +#endif + + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + retResult = (*iter)->GetResult(); + retValue = true; + break; + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + return retValue; + } + + template <class T> + bool CachedResults<T>::GetCachedResult( + T& retResult, const std::vector<const TaggedObject*>& dependents) const + { + std::vector<Number> scalar_dependents; + return GetCachedResult(retResult, dependents, scalar_dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult1Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(1); + dependents[0] = dependent1; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult1Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(1); + dependents[0] = dependent1; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult2Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult2Dep(T& retResult, const TaggedObject* dependent1, const TaggedObject* dependent2) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult3Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult3Dep(T& retResult, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + bool CachedResults<T>::InvalidateResult(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + { + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + (*iter)->Invalidate(); + retValue = true; + break; + } + } + + return retValue; + } + + template <class T> + void CachedResults<T>::Clear() + { + if (!cached_results_) + return; + + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + (*iter)->Invalidate(); + } + + CleanupInvalidatedResults(); + } + + template <class T> + void CachedResults<T>::Clear(Int max_cache_size) + { + Clear(); + max_cache_size_ = max_cache_size; + } + + template <class T> + void CachedResults<T>::CleanupInvalidatedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::CleanupInvalidatedResults", dbg_verbosity); +#endif + + if (!cached_results_) + return; + + typename std::list< DependentResult<T>* >::iterator iter; + iter = cached_results_->begin(); + while (iter != cached_results_->end()) { + if ((*iter)->IsStale()) { + typename std::list< DependentResult<T>* >::iterator + iter_to_remove = iter; + iter++; + DependentResult<T>* result_to_delete = (*iter_to_remove); + cached_results_->erase(iter_to_remove); + delete result_to_delete; + } + else { + iter++; + } + } + } + + template <class T> + void CachedResults<T>::DebugPrintCachedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::DebugPrintCachedResults", dbg_verbosity); + if (DBG_VERBOSITY()>=2 ) { + if (!cached_results_) { + DBG_PRINT((2,"Currentlt no cached results:\n")); + } + else { + typename std::list< DependentResult<T>* >::const_iterator iter; + DBG_PRINT((2,"Current set of cached results:\n")); + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + DBG_PRINT((2," DependentResult:0x%x\n", (*iter))); + } + } + } +#endif + + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpCompoundMatrix.hpp b/thirdparty/linux/include/coin/coin/IpCompoundMatrix.hpp new file mode 100644 index 0000000..03e2e2a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpCompoundMatrix.hpp @@ -0,0 +1,340 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDMATRIX_HPP__ +#define __IPCOMPOUNDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundMatrixSpace; + + /** Class for Matrices consisting of other matrices. This matrix is + * a matrix that consists of zero, one or more Matrices's which are + * arranged like this: \f$ M_{\rm compound} = + * \left(\begin{array}{cccc}M_{00} & M_{01} & \ldots & M_{0,{\rm + * ncomp\_cols}-1} \\ \dots &&&\dots \\ M_{{\rm ncomp\_rows}-1,0} & + * M_{{\rm ncomp\_rows}-1,1} & \dots & M_{{\rm ncomp\_rows}-1,{\rm + * ncomp\_cols}-1}\end{array}\right)\f$. The individual components + * can be associated to different MatrixSpaces. The individual + * components can also be const and non-const Matrices. If a + * component is not set (i.e., it's pointer is NULL), then this + * components is treated like a zero-matrix of appropriate + * dimensions. + */ + class CompoundMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. The owner_space has to + * be defined, so that at each block row and column contain at + * least one non-NULL component. The individual components can + * be set afterwards with the SeteComp and SetCompNonConst + * methods. + */ + CompoundMatrix(const CompoundMatrixSpace* owner_space); + + /** Destructor */ + virtual ~CompoundMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Method to set a non-const Matrix entry */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method to create a new matrix from the space for this block */ + void CreateBlockFromSpace(Index irow, Index jcol); + + /** Method for retrieving one block from the compound matrix as a + * const Matrix. + */ + SmartPtr<const Matrix> GetComp(Index irow, Index jcol) const + { + return ConstComp(irow, jcol); + } + + /** Method for retrieving one block from the compound matrix as a + * non-const Matrix. Note that calling this method with mark the + * CompoundMatrix as changed. Therefore, only use this method if + * you are intending to change the Matrix that you receive. */ + SmartPtr<Matrix> GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow, jcol); + } + + /** Number of block rows of this compound matrix. */ + inline Index NComps_Rows() const; + /** Number of block colmuns of this compound matrix. */ + inline Index NComps_Cols() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundMatrix(); + + /** Copy Constructor */ + CompoundMatrix(const CompoundMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundMatrix&); + //@} + + /** Matrix of matrix's containing the components */ + std::vector<std::vector<SmartPtr<Matrix> > > comps_; + + /** Matrix of const matrix's containing the components */ + std::vector<std::vector<SmartPtr<const Matrix> > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundMatrixSpace instead + * of MatrixSpace */ + const CompoundMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** Method to check whether or not the matrices are valid */ + bool MatricesValid() const; + + inline const Matrix* ConstComp(Index irow, Index jcol) const; + + inline Matrix* Comp(Index irow, Index jcol); + }; + + /** This is the matrix space for CompoundMatrix. Before a CompoundMatrix + * can be created, at least one MatrixSpace has to be set per block + * row and column. Individual component MatrixSpace's can be set + * with the SetComp method. + */ + class CompoundMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + CompoundMatrixSpace(Index ncomps_rows, + Index ncomps_cols, + Index total_nRows, + Index total_nCols); + + /** Destructor */ + ~CompoundMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the number nrows of rows in row-block number irow. */ + void SetBlockRows(Index irow, Index nrows); + + /** Set the number ncols of columns in column-block number jcol. */ + void SetBlockCols(Index jcol, Index ncols); + + /** Get the number nrows of rows in row-block number irow. */ + Index GetBlockRows(Index irow) const; + + /** Set the number ncols of columns in column-block number jcol. */ + Index GetBlockCols(Index jcol) const; + + /** Set the component MatrixSpace. If auto_allocate is true, then + * a new CompoundMatrix created later with MakeNew will have this + * component automatically created with the Matrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr<const MatrixSpace> GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow<NComps_Rows()); + DBG_ASSERT(jcol<NComps_Cols()); + return comp_spaces_[irow][jcol]; + } + + /** @name Accessor methods */ + //@{ + /** Number of block rows */ + Index NComps_Rows() const + { + return ncomps_rows_; + } + /** Number of block columns */ + Index NComps_Cols() const + { + return ncomps_cols_; + } + + /** True if the blocks lie on the diagonal - can make some operations faster */ + bool Diagonal() const + { + return diagonal_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + CompoundMatrix* MakeNewCompoundMatrix() const; + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewCompoundMatrix(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundMatrixSpace(); + + /** Copy Constructor */ + CompoundMatrixSpace(const CompoundMatrixSpace&); + + /** Overloaded Equals Operator */ + CompoundMatrixSpace& operator=(const CompoundMatrixSpace&); + //@} + + /** Number of block rows */ + Index ncomps_rows_; + + /** Number of block columns */ + Index ncomps_cols_; + + /** Store whether or not the dimensions are valid */ + mutable bool dimensions_set_; + + /** 2-dim std::vector of matrix spaces for the components */ + std::vector<std::vector<SmartPtr<const MatrixSpace> > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector<std::vector< bool > > allocate_block_; + + /** Vector of the number of rows in each comp column */ + std::vector<Index> block_rows_; + + /** Vector of the number of cols in each comp row */ + std::vector<Index> block_cols_; + + /** true if the CompoundMatrixSpace only has Matrix spaces along the diagonal. + * this means that the CompoundMatrix will only have matrices along the + * diagonal and it could make some operations more efficient + */ + bool diagonal_; + + /** Auxilliary function for debugging to set if all block + * dimensions have been set. */ + bool DimensionsSet() const; + }; + + /* inline methods */ + inline + Index CompoundMatrix::NComps_Rows() const + { + return owner_space_->NComps_Rows(); + } + + inline + Index CompoundMatrix::NComps_Cols() const + { + return owner_space_->NComps_Cols(); + } + + inline + const Matrix* CompoundMatrix::ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + inline + Matrix* CompoundMatrix::Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + return GetRawPtr(comps_[irow][jcol]); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpCompoundSymMatrix.hpp b/thirdparty/linux/include/coin/coin/IpCompoundSymMatrix.hpp new file mode 100644 index 0000000..4ca18fe --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpCompoundSymMatrix.hpp @@ -0,0 +1,283 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDSYMMATRIX_HPP__ +#define __IPCOMPOUNDSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundSymMatrixSpace; + + /** Class for symmetric matrices consisting of other matrices. + * Here, the lower left block of the matrix is stored. + */ + class CompoundSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking only the number for block components into the + * row and column direction. The owner_space has to be defined, so + * that at each block row and column contain at least one non-NULL + * component. + */ + CompoundSymMatrix(const CompoundSymMatrixSpace* owner_space); + + /** Destructor */ + ~CompoundSymMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. Since this only the lower left components are stored, we need + * to have jcol<=irow, and if irow==jcol, the matrix must be a SymMatrix */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Non const version of the same method */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method for retrieving one block from the compound matrix. + * Since this only the lower left components are stored, we need + * to have jcol<=irow */ + SmartPtr<const Matrix> GetComp(Index irow, Index jcol) const + { + return ConstComp(irow,jcol); + } + + /** Non const version of GetComp. You should only use this method + * if you are intending to change the matrix you receive, since + * this CompoundSymMatrix will be marked as changed. */ + SmartPtr<Matrix> GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow,jcol); + } + + /** Method for creating a new matrix of this specific type. */ + SmartPtr<CompoundSymMatrix> MakeNewCompoundSymMatrix() const; + + // The following don't seem to be necessary + /* Number of block rows of this compound matrix. */ + // Index NComps_NRows() const { return NComps_Dim(); } + + /* Number of block colmuns of this compound matrix. */ + // Index NComps_NCols() const { return NComps_Dim(); } + + /** Number of block rows and columns */ + Index NComps_Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundSymMatrix(); + + /** Copy Constructor */ + CompoundSymMatrix(const CompoundSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundSymMatrix&); + //@} + + /** Vector of vectors containing the components */ + std::vector<std::vector<SmartPtr<Matrix> > > comps_; + + /** Vector of vectors containing the const components */ + std::vector<std::vector<SmartPtr<const Matrix> > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundSymMatrixSpace */ + const CompoundSymMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** method to check wether or not the matrices are valid */ + bool MatricesValid() const; + + /** Internal method to return a const pointer to one of the comps */ + const Matrix* ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + /** Internal method to return a non-const pointer to one of the comps */ + Matrix* Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + // We shouldn't be asking for a non-const if this entry holds a + // const one... + DBG_ASSERT(IsNull(const_comps_[irow][jcol])); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + + return NULL; + } + }; + + /** This is the matrix space for CompoundSymMatrix. Before a + * CompoundSymMatrix can be created, at least one SymMatrixSpace has + * to be set per block row and column. Individual component + * SymMatrixSpace's can be set with the SetComp method. + */ + class CompoundSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of blocks (same for rows and + * columns), as well as the total dimension of the matrix. + */ + CompoundSymMatrixSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundSymMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the dimension dim for block row (or column) irow_jcol */ + void SetBlockDim(Index irow_jcol, Index dim); + + /** Get the dimension dim for block row (or column) irow_jcol */ + Index GetBlockDim(Index irow_jcol) const; + + /** Set the component SymMatrixSpace. If auto_allocate is true, then + * a new CompoundSymMatrix created later with MakeNew will have this + * component automatically created with the SymMatrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundSymMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr<const MatrixSpace> GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow<ncomp_spaces_); + DBG_ASSERT(jcol<=irow); + return comp_spaces_[irow][jcol]; + } + + /** @name Accessor methods */ + //@{ + Index NComps_Dim() const + { + return ncomp_spaces_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + CompoundSymMatrix* MakeNewCompoundSymMatrix() const; + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewCompoundSymMatrix(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundSymMatrixSpace(); + + /** Copy Constructor */ + CompoundSymMatrixSpace(const CompoundSymMatrix&); + + /** Overloaded Equals Operator */ + CompoundSymMatrixSpace& operator=(const CompoundSymMatrixSpace&); + //@} + + /** Number of components per row and column */ + Index ncomp_spaces_; + + /** Vector of the number of rows in each comp column, + * Since this is symmetric, this is also the number + * of columns in each row, hence, it is the dimension + * each of the diagonals */ + std::vector<Index> block_dim_; + + /** 2-dim std::vector of matrix spaces for the components. Only + * the lower right part is stored. */ + std::vector<std::vector<SmartPtr<const MatrixSpace> > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector<std::vector< bool > > allocate_block_; + + /** boolean indicating if the compound matrix space is in a "valid" state */ + mutable bool dimensions_set_; + + /** Method to check whether or not the spaces are valid */ + bool DimensionsSet() const; + }; + + inline + SmartPtr<CompoundSymMatrix> CompoundSymMatrix::MakeNewCompoundSymMatrix() const + { + return owner_space_->MakeNewCompoundSymMatrix(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpCompoundVector.hpp b/thirdparty/linux/include/coin/coin/IpCompoundVector.hpp new file mode 100644 index 0000000..a4c52ab --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpCompoundVector.hpp @@ -0,0 +1,339 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDVECTOR_HPP__ +#define __IPCOMPOUNDVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include <vector> + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundVectorSpace; + + /** Class of Vectors consisting of other vectors. This vector is a + * vector that consists of zero, one or more Vector's which are + * stacked on each others: \f$ x_{\rm compound} = + * \left(\begin{array}{c}x_0\\\dots\\x_{{\rm + * ncomps} - 1}\end{array}\right)\f$. The individual components can be + * associated to different VectorSpaces. The individual components + * can also be const and non-const Vectors. + */ + class CompoundVector : public Vector + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor, given the corresponding CompoundVectorSpace. + * Before this constructor can be called, all components of the + * CompoundVectorSpace have to be set, so that the constructors + * for the individual components can be called. If the flag + * create_new is true, then the individual components of the new + * CompoundVector are initialized with the MakeNew methods of + * each VectorSpace (and are non-const). Otherwise, the + * individual components can later be set using the SetComp and + * SetCompNonConst method. + */ + CompoundVector(const CompoundVectorSpace* owner_space, bool create_new); + + /** Default destructor */ + virtual ~CompoundVector(); + //@} + + /** Method for setting the pointer for a component that is a const + * Vector + */ + void SetComp(Index icomp, const Vector& vec); + + /** Method for setting the pointer for a component that is a + * non-const Vector + */ + void SetCompNonConst(Index icomp, Vector& vec); + + /** Number of components of this compound vector */ + inline Index NComps() const; + + /** Check if a particular component is const or not */ + bool IsCompConst(Index i) const + { + DBG_ASSERT(i > 0 && i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(const_comps_[i])) { + return true; + } + return false; + } + + /** Check if a particular component is null or not */ + bool IsCompNull(Index i) const + { + DBG_ASSERT(i >= 0 && i < NComps()); + if (IsValid(comps_[i]) || IsValid(const_comps_[i])) { + return false; + } + return true; + } + + /** Return a particular component (const version) */ + SmartPtr<const Vector> GetComp(Index i) const + { + return ConstComp(i); + } + + /** Return a particular component (non-const version). Note that + * calling this method with mark the CompoundVector as changed. + * Therefore, only use this method if you are intending to change + * the Vector that you receive. + */ + SmartPtr<Vector> GetCompNonConst(Index i) + { + ObjectChanged(); + return Comp(i); + } + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** Element-wise reciprocal */ + virtual void ElementWiseReciprocalImpl(); + + /** Element-wise absolute values */ + virtual void ElementWiseAbsImpl(); + + /** Element-wise square-root */ + virtual void ElementWiseSqrtImpl(); + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + CompoundVector(); + + /** Copy Constructor */ + CompoundVector(const CompoundVector&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundVector&); + //@} + + /** Components of the compound vector. The components + * are stored by SmartPtrs in a std::vector + */ + std::vector< SmartPtr<Vector> > comps_; + std::vector< SmartPtr<const Vector> > const_comps_; + + const CompoundVectorSpace* owner_space_; + + bool vectors_valid_; + + bool VectorsValid(); + + inline const Vector* ConstComp(Index i) const; + + inline Vector* Comp(Index i); + }; + + /** This vectors space is the vector space for CompoundVector. + * Before a CompoundVector can be created, all components of this + * CompoundVectorSpace have to be set. When calling the constructor, + * the number of component has to be specified. The individual + * VectorSpaces can be set with the SetComp method. + */ + class CompoundVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, has to be given the number of components and the + * total dimension of all components combined. */ + CompoundVectorSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundVectorSpace() + {} + //@} + + /** Method for setting the individual component VectorSpaces */ + virtual void SetCompSpace(Index icomp /** Number of the component to be set */ , + const VectorSpace& vec_space /** VectorSpace for component icomp */ + ); + + /** Method for obtaining an individual component VectorSpace */ + SmartPtr<const VectorSpace> GetCompSpace(Index icomp) const; + + /** Accessor method to obtain the number of components */ + Index NCompSpaces() const + { + return ncomp_spaces_; + } + + /** Method for creating a new vector of this specific type. */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return new CompoundVector(this, create_new); + } + + /** Overloaded MakeNew method for the VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewCompoundVector(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundVectorSpace(); + + /** Copy Constructor */ + CompoundVectorSpace(const CompoundVectorSpace&); + + /** Overloaded Equals Operator */ + CompoundVectorSpace& operator=(const CompoundVectorSpace&); + //@} + + /** Number of components */ + const Index ncomp_spaces_; + + /** std::vector of vector spaces for the components */ + std::vector< SmartPtr<const VectorSpace> > comp_spaces_; + }; + + /* inline methods */ + inline + Index CompoundVector::NComps() const + { + return owner_space_->NCompSpaces(); + } + + inline + const Vector* CompoundVector::ConstComp(Index i) const + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(comps_[i])) { + return GetRawPtr(comps_[i]); + } + else if (IsValid(const_comps_[i])) { + return GetRawPtr(const_comps_[i]); + } + + DBG_ASSERT(false && "shouldn't be here"); + return NULL; + } + + inline + Vector* CompoundVector::Comp(Index i) + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i])); + return GetRawPtr(comps_[i]); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpConvCheck.hpp b/thirdparty/linux/include/coin/coin/IpConvCheck.hpp new file mode 100644 index 0000000..033fce4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpConvCheck.hpp @@ -0,0 +1,87 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpConvCheck.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCONVCHECK_HPP__ +#define __IPCONVCHECK_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for checking the algorithm + * termination criteria. + */ + class ConvergenceCheck : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + ConvergenceCheck() + {} + + /** Default destructor */ + virtual ~ConvergenceCheck() + {} + //@} + + /** Convergence return enum */ + enum ConvergenceStatus { + CONTINUE, + CONVERGED, + CONVERGED_TO_ACCEPTABLE_POINT, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + DIVERGING, + USER_STOP, + FAILED + }; + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for performing the convergence test. If + * call_intermediate_callback is true, the user callback method + * in the NLP should be called in order to see if the user + * requests an early termination. */ + virtual ConvergenceStatus + CheckConvergence(bool call_intermediate_callback = true) = 0; + + /** Method for testing if the current iterate is considered to + * satisfy the "accptable level" of accuracy. The idea is that + * if the desired convergence tolerance cannot be achieved, the + * algorithm might stop after a number of acceptable points have + * been encountered. */ + virtual bool CurrentIsAcceptable()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // ConvergenceCheck(); + + /** Copy Constructor */ + ConvergenceCheck(const ConvergenceCheck&); + + /** Overloaded Equals Operator */ + void operator=(const ConvergenceCheck&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpDebug.hpp b/thirdparty/linux/include/coin/coin/IpDebug.hpp new file mode 100644 index 0000000..b8aae13 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpDebug.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDebug.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDEBUG_HPP__ +#define __IPDEBUG_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" + +#ifdef COIN_IPOPT_CHECKLEVEL +#ifdef HAVE_CASSERT +# include <cassert> +#else +# ifdef HAVE_ASSERT_H +# include <assert.h> +# else +# error "don't have header file for assert" +# endif +#endif +#else +#define COIN_IPOPT_CHECKLEVEL 0 +#endif + +#if COIN_IPOPT_CHECKLEVEL > 0 +# ifdef NDEBUG +# undef NDEBUG +# endif +# define DBG_ASSERT(test) assert(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + ASSERT_EXCEPTION( (__condition), __except_type, __msg); +# define DBG_DO(__cmd) __cmd +#else +# define DBG_ASSERT(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) +# define DBG_DO(__cmd) +#endif + +#ifndef COIN_IPOPT_VERBOSITY +#define COIN_IPOPT_VERBOSITY 0 +#endif + +#if COIN_IPOPT_VERBOSITY < 1 +# define DBG_START_FUN(__func_name, __verbose_level) +# define DBG_START_METH(__func_name, __verbose_level) +# define DBG_PRINT(__printf_args) +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +# define DBG_EXEC(__verbosity, __cmd) +# define DBG_VERBOSITY() 0 +#else +#include <string> + +namespace Ipopt +{ + // forward definition + class Journalist; + + /** Class that lives throughout the execution of a method or + * function for which debug output is to be generated. The output + * is sent to the unique debug journalist that is set with + * SetJournalist at the beginning of program execution. */ + class DebugJournalistWrapper + { + public: + /** @name Constructors/Destructors. */ + //@{ + DebugJournalistWrapper(std::string func_name, Index verbose_level); + DebugJournalistWrapper(std::string func_name, Index verbose_level, + const void* const method_owner); + ~DebugJournalistWrapper(); + //@} + + /** @name accessor methods */ + //@{ + Index Verbosity() + { + return verbose_level_; + } + const Journalist* Jnlst() + { + return jrnl_; + } + Index IndentationLevel() + { + return indentation_level_; + } + //@} + + /** Printing */ + void DebugPrintf(Index verbosity, const char* pformat, ...); + + /* Method for initialization of the static GLOBAL journalist, + * through with all debug printout is to be written. This needs + * to be set before any debug printout can be done. */ + static void SetJournalist(Journalist* jrnl); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + DebugJournalistWrapper(); + + /** copy contructor */ + DebugJournalistWrapper(const DebugJournalistWrapper&); + + /** Overloaded Equals Operator */ + DebugJournalistWrapper& operator=(const DebugJournalistWrapper&); + //@} + + static Index indentation_level_; + std::string func_name_; + Index verbose_level_; + const void* method_owner_; + + static Journalist* jrnl_; + }; +} + +# define DBG_START_FUN(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level)); \ + +# define DBG_START_METH(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level), this); + +# define DBG_PRINT(__args) \ + dbg_jrnl.DebugPrintf __args; + +# define DBG_EXEC(__verbose_level, __cmd) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + (__cmd); \ + } + +# define DBG_VERBOSITY() \ + dbg_jrnl.Verbosity() + +#endif + + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpDenseVector.hpp b/thirdparty/linux/include/coin/coin/IpDenseVector.hpp new file mode 100644 index 0000000..380a06c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpDenseVector.hpp @@ -0,0 +1,550 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDenseVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDENSEVECTOR_HPP__ +#define __IPDENSEVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include <map> + +namespace Ipopt +{ + + /* forward declarations */ + class DenseVectorSpace; + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(METADATA_ERROR); + //@} + + /** Dense Vector Implementation. This is the default Vector class + * in Ipopt. It stores vectors in contiguous Number arrays, unless + * the vector has the same value in all entires. In the latter + * case, we call the vector "homogeneous", and we store only the + * values that is repeated in all elements. If you want to obtain + * the values of vector, use the IsHomogeneous() method to find out + * what status the vector is in, and then use either Values() const + * or Scalar() const methods to get the values. To set the values + * of a homogeneous method, use the Set method. To set the values + * of a non-homogeneous vector, use the SetValues method, or use + * the non-const Values method to get an array that you can + * overwrite. In the latter case, storage is ensured. + */ + class DenseVector : public Vector + { + public: + + /**@name Constructors / Destructors */ + //@{ + /** Default Constructor + */ + DenseVector(const DenseVectorSpace* owner_space); + + /** Destructor + */ + virtual ~DenseVector(); + //@} + + /** @name Additional public methods not in Vector base class. */ + //@{ + /** Create a new DenseVector from same VectorSpace */ + SmartPtr<DenseVector> MakeNewDenseVector() const; + + /** Set elements in the vector to the Number array x. */ + void SetValues(const Number *x); + + /** Obtain pointer to the internal Number array with vector + * elements with the indention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed!. + */ + inline Number* Values(); + + /** Obtain pointer to the internal Number array with vector + * elements without the intention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed! IMPORTANT: If this method is currently + * homogeneous (i.e. IsHomogeneous returns true), then you cannot + * call this method. Instead, you need to use the Scalar() + * method. + */ + inline const Number* Values() const; + + /** The same as the const version of Values, but we ensure that we + * always return a valid array, even if IsHomogeneous returns + * true. */ + const Number* ExpandedValues() const; + + /** This is the same as Values, but we add it here so that + * ExpandedValues can also be used for the non-const case. */ + inline Number* ExpandedValues() + { + return Values(); + } + + /** Indicates if the vector is homogeneous (i.e., all entries have + * the value Scalar() */ + bool IsHomogeneous() const + { + return homogeneous_; + } + + /** Scalar value of all entries in a homogeneous vector */ + Number Scalar() const + { + DBG_ASSERT(homogeneous_); + return scalar_; + } + //@} + + /** @name Modifying subranges of the vector. */ + //@{ + /** Copy the data in x into the subrange of this vector starting + * at position Pos in this vector. Position count starts at 0. + */ + void CopyToPos(Index Pos, const Vector& x); + /** Copy a subrange of x, starting at Pos, into the full data of + * this vector. Position count starts at 0. + */ + void CopyFromPos(Index Pos, const Vector& x); + //@} + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Set entry to max of itself and the corresponding element in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Set entry to min of itself and the corresponding element in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl(); + + /** take abs of the elements of the vector */ + virtual void ElementWiseAbsImpl(); + + /** take square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl(); + + /** Changes each entry in the vector to its sgn value */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1); + } + /* Print the entire vector with padding, and start counting with + an offset. */ + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + //@} + friend class ParVector; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DenseVector(); + + /** Copy Constructor */ + DenseVector(const DenseVector&); + + /** Overloaded Equals Operator */ + void operator=(const DenseVector&); + //@} + + /** Copy of the owner_space ptr as a DenseVectorSpace instead + * of a VectorSpace + */ + const DenseVectorSpace* owner_space_; + + /** Dense Number array of vector values. */ + Number* values_; + + /** Dense Number array pointer that is used for ExpandedValues */ + mutable Number* expanded_values_; + + /** Method of getting the internal values array, making sure that + * memory has been allocated */ + inline + Number* values_allocated(); + + /** Flag for Initialization. This flag is false, if the data has + not yet been initialized. */ + bool initialized_; + + /** Flag indicating whether the vector is currently homogeneous + * (that is, all elements have the same value). This flag is used + * to determine whether the elements of the vector are stored in + * values_ or in scalar_ */ + bool homogeneous_; + + /** Homogeneous value of all elements if the vector is currently + * homogenous */ + Number scalar_; + + /** Auxilliary method for setting explicitly all elements in + * values_ to the current scalar value. */ + void set_values_from_scalar(); + }; + + /** typedefs for the map variables that define meta data for the + * DenseVectorSpace + */ + typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType; + typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType; + typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType; + + /** This vectors space is the vector space for DenseVector. + */ + class DenseVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, requires dimension of all vector for this + * VectorSpace + */ + DenseVectorSpace(Index dim) + : + VectorSpace(dim) + {} + + /** Destructor */ + ~DenseVectorSpace() + {} + //@} + + /** Method for creating a new vector of this specific type. */ + inline + DenseVector* MakeNewDenseVector() const + { + return new DenseVector(this); + } + + /** Instantiation of the generate MakeNew method for the + * VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewDenseVector(); + } + + /**@name Methods called by DenseVector for memory management. + * This could allow to have sophisticated memory management in the + * VectorSpace. + */ + //@{ + /** Allocate internal storage for the DenseVector */ + inline + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the DenseVector */ + inline + void FreeInternalStorage(Number* values) const; + //@} + + /**@name Methods for dealing with meta data on the vector + */ + //@{ + /** Check if string meta exists for tag */ + inline + bool HasStringMetaData(const std::string tag) const; + + /** Check if Integer meta exists for tag */ + inline + bool HasIntegerMetaData(const std::string tag) const; + + /** Check if Numeric meta exists for tag */ + inline + bool HasNumericMetaData(const std::string tag) const; + + /** Get meta data of type std::string by tag */ + inline + const std::vector<std::string>& GetStringMetaData(const std::string& tag) const; + + /** Get meta data of type Index by tag */ + inline + const std::vector<Index>& GetIntegerMetaData(const std::string& tag) const; + + /** Get meta data of type Number by tag */ + inline + const std::vector<Number>& GetNumericMetaData(const std::string& tag) const; + + /** Set meta data of type std::string by tag */ + inline + void SetStringMetaData(std::string tag, std::vector<std::string> meta_data); + + /** Set meta data of type Index by tag */ + inline + void SetIntegerMetaData(std::string tag, std::vector<Index> meta_data); + + /** Set meta data of type Number by tag */ + inline + void SetNumericMetaData(std::string tag, std::vector<Number> meta_data); + + /** Get map of meta data of type Number */ + inline + const StringMetaDataMapType& GetStringMetaData() const; + + /** Get map of meta data of type Number */ + inline + const IntegerMetaDataMapType& GetIntegerMetaData() const; + + /** Get map of meta data of type Number */ + inline + const NumericMetaDataMapType& GetNumericMetaData() const; + //@} + + private: + // variables to store vector meta data + StringMetaDataMapType string_meta_data_; + IntegerMetaDataMapType integer_meta_data_; + NumericMetaDataMapType numeric_meta_data_; + + }; + + // inline functions + inline Number* DenseVector::Values() + { + // Here we assume that every time someone requests this direct raw + // pointer, the data is going to change and the Tag for this + // vector has to be updated. + + if (initialized_ && homogeneous_) { + // If currently the vector is a homogeneous vector, set all elements + // explicitly to this value + set_values_from_scalar(); + } + ObjectChanged(); + initialized_= true; + homogeneous_ = false; + return values_allocated(); + } + + inline const Number* DenseVector::Values() const + { + DBG_ASSERT(initialized_ && (Dim()==0 || values_)); + return values_; + } + + inline Number* DenseVector::values_allocated() + { + if (values_==NULL) { + values_ = owner_space_->AllocateInternalStorage(); + } + return values_; + } + + inline + Number* DenseVectorSpace::AllocateInternalStorage() const + { + if (Dim()>0) { + return new Number[Dim()]; + } + else { + return NULL; + } + } + + inline + void DenseVectorSpace::FreeInternalStorage(Number* values) const + { + delete [] values; + } + + inline + SmartPtr<DenseVector> DenseVector::MakeNewDenseVector() const + { + return owner_space_->MakeNewDenseVector(); + } + + inline + bool DenseVectorSpace::HasStringMetaData(const std::string tag) const + { + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + + if (iter != string_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasIntegerMetaData(const std::string tag) const + { + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + + if (iter != integer_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasNumericMetaData(const std::string tag) const + { + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + + if (iter != numeric_meta_data_.end()) { + return true; + } + + return false; + } + + inline + const std::vector<std::string>& DenseVectorSpace::GetStringMetaData(const std::string& tag) const + { + DBG_ASSERT(HasStringMetaData(tag)); + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector<Index>& DenseVectorSpace::GetIntegerMetaData(const std::string& tag) const + { + DBG_ASSERT(HasIntegerMetaData(tag)); + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector<Number>& DenseVectorSpace::GetNumericMetaData(const std::string& tag) const + { + DBG_ASSERT(HasNumericMetaData(tag)); + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + return iter->second; + } + + inline + void DenseVectorSpace::SetStringMetaData(std::string tag, std::vector<std::string> meta_data) + { + string_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetIntegerMetaData(std::string tag, std::vector<Index> meta_data) + { + integer_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetNumericMetaData(std::string tag, std::vector<Number> meta_data) + { + numeric_meta_data_[tag] = meta_data; + } + + inline + const StringMetaDataMapType& DenseVectorSpace::GetStringMetaData() const + { + return string_meta_data_; + } + + inline + const IntegerMetaDataMapType& DenseVectorSpace::GetIntegerMetaData() const + { + return integer_meta_data_; + } + + inline + const NumericMetaDataMapType& DenseVectorSpace::GetNumericMetaData() const + { + return numeric_meta_data_; + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpDiagMatrix.hpp b/thirdparty/linux/include/coin/coin/IpDiagMatrix.hpp new file mode 100644 index 0000000..d912e77 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpDiagMatrix.hpp @@ -0,0 +1,141 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDiagMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDIAGMATRIX_HPP__ +#define __IPDIAGMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for diagonal matrices. The diagonal is stored as a + * Vector. */ + class DiagMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, given the corresponding matrix space. */ + DiagMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~DiagMatrix(); + //@} + + /** Method for setting the diagonal elements (as a Vector). */ + void SetDiag(const Vector& diag) + { + diag_ = &diag; + } + + /** Method for setting the diagonal elements. */ + SmartPtr<const Vector> GetDiag() const + { + return diag_; + } + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrix(); + + /** Copy Constructor */ + DiagMatrix(const DiagMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrix&); + //@} + + /** Vector storing the diagonal elements */ + SmartPtr<const Vector> diag_; + }; + + /** This is the matrix space for DiagMatrix. */ + class DiagMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + DiagMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~DiagMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewDiagMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + DiagMatrix* MakeNewDiagMatrix() const + { + return new DiagMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrixSpace(); + + /** Copy Constructor */ + DiagMatrixSpace(const DiagMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrixSpace&); + //@} + + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpEqMultCalculator.hpp b/thirdparty/linux/include/coin/coin/IpEqMultCalculator.hpp new file mode 100644 index 0000000..7c3cb20 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpEqMultCalculator.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpEqMultCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-23 + +#ifndef __IPEQMULTCALCULATOR_HPP__ +#define __IPEQMULTCALCULATOR_HPP__ + +#include "IpUtils.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Base Class for objects that compute estimates for the equality + * constraint multipliers y_c and y_d. For example, this is the + * base class for objects for computing least square multipliers or + * coordinate multipliers. */ + class EqMultiplierCalculator: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor. */ + EqMultiplierCalculator() + {} + /** Default destructor */ + virtual ~EqMultiplierCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** This method computes the estimates for y_c and y_d at the + * current point. If the estimates cannot be computed (e.g. some + * linear system is singular), the return value of this method is + * false. */ + virtual bool CalculateMultipliers(Vector& y_c, + Vector& y_d) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + EqMultiplierCalculator(const EqMultiplierCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const EqMultiplierCalculator&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpException.hpp b/thirdparty/linux/include/coin/coin/IpException.hpp new file mode 100644 index 0000000..e64226f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpException.hpp @@ -0,0 +1,147 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpException.hpp 2023 2011-06-18 18:49:49Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXCEPTION_HPP__ +#define __IPEXCEPTION_HPP__ + +#include "IpUtils.hpp" +#include "IpJournalist.hpp" + +/* This file contains a base class for all exceptions + * and a set of macros to help with exceptions + */ + +namespace Ipopt +{ + + /** This is the base class for all exceptions. The easiest way to + * use this class is by means of the following macros: + * + * \verbatim + + DECLARE_STD_EXCEPTION(ExceptionType); + \endverbatim + * + * This macro defines a new class with the name ExceptionType, + * inherited from the base class IpoptException. After this, + * exceptions of this type can be thrown using + * + * \verbatim + + THROW_EXCEPTION(ExceptionType, Message); + \endverbatim + * + * where Message is a std::string with a message that gives an + * indication of what caused the exception. Exceptions can also be + * thrown using the macro + * + * \verbatim + + ASSERT_EXCEPTION(Condition, ExceptionType, Message); + \endverbatim + * + * where Conditions is an expression. If Condition evaluates to + * false, then the exception of the type ExceptionType is thrown + * with Message. + * + * When an exception is caught, the method ReportException can be + * used to write the information about the exception to the + * Journalist, using the level J_ERROR and the category J_MAIN. + * + */ + class IpoptException + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptException(std::string msg, std::string file_name, Index line_number, std::string type="IpoptException") + : + msg_(msg), + file_name_(file_name), + line_number_(line_number), + type_(type) + {} + + /** Copy Constructor */ + IpoptException(const IpoptException& copy) + : + msg_(copy.msg_), + file_name_(copy.file_name_), + line_number_(copy.line_number_), + type_(copy.type_) + {} + + /** Default destructor */ + virtual ~IpoptException() + {} + //@} + + /** Method to report the exception to a journalist */ + void ReportException(const Journalist& jnlst, + EJournalLevel level = J_ERROR) const + { + jnlst.Printf(level, J_MAIN, + "Exception of type: %s in file \"%s\" at line %d:\n Exception message: %s\n", + type_.c_str(), file_name_.c_str(), line_number_, msg_.c_str()); + } + + const std::string& Message() const + { + return msg_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptException(); + + /** Overloaded Equals Operator */ + void operator=(const IpoptException&); + //@} + + std::string msg_; + std::string file_name_; + Index line_number_; + std::string type_; + }; + +} // namespace Ipopt + +#define THROW_EXCEPTION(__except_type, __msg) \ + throw __except_type( (__msg), (__FILE__), (__LINE__) ); + +#define ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + if (! (__condition) ) { \ + std::string newmsg = #__condition; \ + newmsg += " evaluated false: "; \ + newmsg += __msg; \ + throw __except_type( (newmsg), (__FILE__), (__LINE__) ); \ + } + +#define DECLARE_STD_EXCEPTION(__except_type) \ + class __except_type : public Ipopt::IpoptException \ + { \ + public: \ + __except_type(std::string msg, std::string fname, Ipopt::Index line) \ + : Ipopt::IpoptException(msg,fname,line, #__except_type) {} \ + __except_type(const __except_type& copy) \ + : Ipopt::IpoptException(copy) {} \ + private: \ + __except_type(); \ + void operator=(const __except_type&); \ + } + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpExpansionMatrix.hpp b/thirdparty/linux/include/coin/coin/IpExpansionMatrix.hpp new file mode 100644 index 0000000..cbb9a99 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpExpansionMatrix.hpp @@ -0,0 +1,212 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpExpansionMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXPANSIONMATRIX_HPP__ +#define __IPEXPANSIONMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /** forward declarations */ + class ExpansionMatrixSpace; + + /** Class for expansion/projection matrices. These matrices allow + * to lift a vector to a vector with larger dimension, keeping + * some elements of the larger vector zero. This operation is achieved + * by the MultVector operation. The transpose operation then + * filters some elements from a large vector into a smaller vector. + */ + class ExpansionMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ExpansionMatrix(const ExpansionMatrixSpace* owner_space); + + /** Destructor */ + ~ExpansionMatrix(); + //@} + + /** Return the vector of indices marking the expanded position. + * The result is the Index array (of length NSmallVec=NCols()) + * that stores the mapping from the small vector to the large + * vector. For each element i=0,..,NSmallVec in the small + * vector, ExpandedPosIndices()[i] give the corresponding index + * in the large vector. + */ + const Index* ExpandedPosIndices() const; + + /** Return the vector of indices marking the compressed position. + * The result is the Index array (of length NLargeVec=NRows()) + * that stores the mapping from the large vector to the small + * vector. For each element i=0,..,NLargeVec in the large + * vector, CompressedPosIndices()[i] gives the corresponding + * index in the small vector, unless CompressedPosIndices()[i] is + * negative. + */ + const Index* CompressedPosIndices() const; + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1, 1); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index row_offset, + Index col_offset) const; + + friend class ParExpansionMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ExpansionMatrix(); + + /** Copy Constructor */ + ExpansionMatrix(const ExpansionMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ExpansionMatrix&); + //@} + + const ExpansionMatrixSpace* owner_space_; + + }; + + /** This is the matrix space for ExpansionMatrix. + */ + class ExpansionMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the list of elements of the large vector + * (of size NLargeVec) to be filtered into the small vector (of + * size NSmallVec). For each i=0..NSmallVec-1 the i-th element + * of the small vector will be put into the ExpPos[i] position of + * the large vector. The position counting in the vector is + * assumed to start at 0 (C-like array notation). + */ + ExpansionMatrixSpace(Index NLargeVec, + Index NSmallVec, + const Index *ExpPos, + const int offset = 0); + + /** Destructor */ + ~ExpansionMatrixSpace() + { + delete [] compressed_pos_; + delete [] expanded_pos_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + ExpansionMatrix* MakeNewExpansionMatrix() const + { + return new ExpansionMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewExpansionMatrix(); + } + + /** Accessor Method to obtain the Index array (of length + * NSmallVec=NCols()) that stores the mapping from the small + * vector to the large vector. For each element i=0,..,NSmallVec + * in the small vector, ExpandedPosIndices()[i] give the + * corresponding index in the large vector. + */ + const Index* ExpandedPosIndices() const + { + return expanded_pos_; + } + + /** Accessor Method to obtain the Index array (of length + * NLargeVec=NRows()) that stores the mapping from the large + * vector to the small vector. For each element i=0,..,NLargeVec + * in the large vector, CompressedPosIndices()[i] gives the + * corresponding index in the small vector, unless + * CompressedPosIndices()[i] is negative. + */ + const Index* CompressedPosIndices() const + { + return compressed_pos_; + } + + private: + Index *expanded_pos_; + Index *compressed_pos_; + }; + + /* inline methods */ + inline + const Index* ExpansionMatrix::ExpandedPosIndices() const + { + return owner_space_->ExpandedPosIndices(); + } + + inline + const Index* ExpansionMatrix::CompressedPosIndices() const + { + return owner_space_->CompressedPosIndices(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpGenTMatrix.hpp b/thirdparty/linux/include/coin/coin/IpGenTMatrix.hpp new file mode 100644 index 0000000..059bfea --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpGenTMatrix.hpp @@ -0,0 +1,264 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpGenTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPGENTMATRIX_HPP__ +#define __IPGENTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class GenTMatrixSpace; + + /** Class for general matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a general matrix is + * stored in three arrays, Irow, Jcol, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (row and column indices), and the last array + * stores the value at that location. If nonzero elements are + * listed more than once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irow and Jcol) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + */ + class GenTMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + GenTMatrix(const GenTMatrixSpace* owner_space); + + /** Destructor */ + ~GenTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements are copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to one of the + * constructors above. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Array with Row indices (counting starts at 1) */ + const Index* Irows() const; + + /** Array with Column indices (counting starts at 1) */ + const Index* Jcols() const; + + /** Array with nonzero values (const version). */ + const Number* Values() const + { + return values_; + } + + /** Array with the nonzero values of this matrix (non-const + * version). Use this method only if you are intending to change + * the values, because the GenTMatrix will be marked as changed. + */ + Number* Values() + { + ObjectChanged(); + initialized_ = true; + return values_; + } + //@} + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 0); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + + friend class ParGenMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + GenTMatrix(); + + /** Copy Constructor */ + GenTMatrix(const GenTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const GenTMatrix&); + //@} + + /** Copy of the owner space as a GenTMatrixSpace instead of + * a MatrixSpace + */ + const GenTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a GenTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class GenTMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns, as well as + * the number of nonzeros and the position of the nonzero + * elements. Note that the counting of the nonzeros starts a 1, + * i.e., iRows[i]==1 and jCols[i]==1 refers to the first element + * in the first row. This is in accordance with the HSL data + * structure. + */ + GenTMatrixSpace(Index nRows, Index nCols, + Index nonZeros, + const Index* iRows, const Index* jCols); + + /** Destructor */ + ~GenTMatrixSpace() + { + delete [] iRows_; + delete [] jCols_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + GenTMatrix* MakeNewGenTMatrix() const + { + return new GenTMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewGenTMatrix(); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element (counting starts at 1) */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element (counting starts at 1) */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /** @name Sparsity structure of matrices generated by this matrix + * space. + */ + //@{ + const Index nonZeros_; + Index* jCols_; + Index* iRows_; + //@} + + /** This method is only for the GenTMatrix to call in order + * to allocate internal storage */ + Number* AllocateInternalStorage() const; + + /** This method is only for the GenTMatrix to call in order + * to de-allocate internal storage */ + void FreeInternalStorage(Number* values) const; + + friend class GenTMatrix; + }; + + /* inline methods */ + inline + Index GenTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* GenTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* GenTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpHessianUpdater.hpp b/thirdparty/linux/include/coin/coin/IpHessianUpdater.hpp new file mode 100644 index 0000000..a3912d6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpHessianUpdater.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpHessianUpdater.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-12-26 + +#ifndef __IPHESSIANUPDATER_HPP__ +#define __IPHESSIANUPDATER_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Abstract base class for objects responsible for updating the + * Hessian information. This can be done using exact second + * derivatives from the NLP, or by a quasi-Newton Option. The + * result is put into the W field in IpData. + */ + class HessianUpdater : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + HessianUpdater() + {} + + /** Default destructor */ + virtual ~HessianUpdater() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Update the Hessian based on the current information in IpData, + * and possibly on information from previous calls. + */ + virtual void UpdateHessian() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + HessianUpdater(const HessianUpdater&); + + /** Overloaded Equals Operator */ + void operator=(const HessianUpdater&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIdentityMatrix.hpp b/thirdparty/linux/include/coin/coin/IpIdentityMatrix.hpp new file mode 100644 index 0000000..8032306 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIdentityMatrix.hpp @@ -0,0 +1,149 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIdentityMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIDENTITYMATRIX_HPP__ +#define __IPIDENTITYMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Matrices which are multiples of the identity matrix. + * + */ + class IdentityMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix + * (true identity matrix). + */ + IdentityMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~IdentityMatrix(); + //@} + + /** Method for setting the factor for the identity matrix. */ + void SetFactor(Number factor) + { + factor_ = factor; + } + + /** Method for getting the factor for the identity matrix. */ + Number GetFactor() const + { + return factor_; + } + + /** Method for obtaining the dimention of the matrix. */ + Index Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void AddMSinvZImpl(Number alpha, const Vector& S, + const Vector& Z, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrix(); + + /** Copy Constructor */ + IdentityMatrix(const IdentityMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrix&); + //@} + + /** Scaling factor for this identity matrix */ + Number factor_; + }; + + /** This is the matrix space for IdentityMatrix. */ + class IdentityMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + IdentityMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~IdentityMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewIdentityMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + IdentityMatrix* MakeNewIdentityMatrix() const + { + return new IdentityMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrixSpace(); + + /** Copy Constructor */ + IdentityMatrixSpace(const IdentityMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrixSpace&); + //@} + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIpoptAlg.hpp b/thirdparty/linux/include/coin/coin/IpIpoptAlg.hpp new file mode 100644 index 0000000..60e3147 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIpoptAlg.hpp @@ -0,0 +1,224 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptAlg.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTALG_HPP__ +#define __IPIPOPTALG_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpAlgStrategy.hpp" +#include "IpSearchDirCalculator.hpp" +#include "IpLineSearch.hpp" +#include "IpMuUpdate.hpp" +#include "IpConvCheck.hpp" +#include "IpOptionsList.hpp" +#include "IpIterateInitializer.hpp" +#include "IpIterationOutput.hpp" +#include "IpAlgTypes.hpp" +#include "IpHessianUpdater.hpp" +#include "IpEqMultCalculator.hpp" + +namespace Ipopt +{ + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(STEP_COMPUTATION_FAILED); + //@} + + /** The main ipopt algorithm class. + * Main Ipopt algorithm class, contains the main optimize method, + * handles the execution of the optimization. + * The constructor initializes the data structures through the nlp, + * and the Optimize method then assumes that everything is + * initialized and ready to go. + * After an optimization is complete, the user can access the + * solution through the passed in ip_data structure. + * Multiple calls to the Optimize method are allowed as long as the + * structure of the problem remains the same (i.e. starting point + * or nlp parameter changes only). + */ + class IpoptAlgorithm : public AlgorithmStrategyObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor. (The IpoptAlgorithm uses smart pointers for these + * passed-in pieces to make sure that a user of IpoptAlgoroithm + * cannot pass in an object created on the stack!) + */ + IpoptAlgorithm(const SmartPtr<SearchDirectionCalculator>& search_dir_calculator, + const SmartPtr<LineSearch>& line_search, + const SmartPtr<MuUpdate>& mu_update, + const SmartPtr<ConvergenceCheck>& conv_check, + const SmartPtr<IterateInitializer>& iterate_initializer, + const SmartPtr<IterationOutput>& iter_output, + const SmartPtr<HessianUpdater>& hessian_updater, + const SmartPtr<EqMultiplierCalculator>& eq_multiplier_calculator = NULL); + + /** Default destructor */ + virtual ~IpoptAlgorithm(); + //@} + + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** Main solve method. */ + SolverReturn Optimize(bool isResto = false); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /**@name Access to internal strategy objects */ + //@{ + SmartPtr<SearchDirectionCalculator> SearchDirCalc() + { + return search_dir_calculator_; + } + //@} + + static void print_copyright_message(const Journalist& jnlst); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptAlgorithm(); + + /** Copy Constructor */ + IpoptAlgorithm(const IpoptAlgorithm&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAlgorithm&); + //@} + + /** @name Strategy objects */ + //@{ + SmartPtr<SearchDirectionCalculator> search_dir_calculator_; + SmartPtr<LineSearch> line_search_; + SmartPtr<MuUpdate> mu_update_; + SmartPtr<ConvergenceCheck> conv_check_; + SmartPtr<IterateInitializer> iterate_initializer_; + SmartPtr<IterationOutput> iter_output_; + SmartPtr<HessianUpdater> hessian_updater_; + /** The multipler calculator (for y_c and y_d) has to be set only + * if option recalc_y is set to true */ + SmartPtr<EqMultiplierCalculator> eq_multiplier_calculator_; + //@} + + /** @name Main steps of the algorthim */ + //@{ + /** Method for updating the current Hessian. This can either just + * evaluate the exact Hessian (based on the current iterate), or + * perform a quasi-Newton update. + */ + void UpdateHessian(); + + /** Method to update the barrier parameter. Returns false, if the + * algorithm can't continue with the regular procedure and needs + * to revert to a fallback mechanism in the line search (such as + * restoration phase) */ + bool UpdateBarrierParameter(); + + /** Method to setup the call to the PDSystemSolver. Returns + * false, if the algorithm can't continue with the regular + * procedure and needs to revert to a fallback mechanism in the + * line search (such as restoration phase) */ + bool ComputeSearchDirection(); + + /** Method computing the new iterate (usually vialine search). + * The acceptable point is the one in trial after return. + */ + void ComputeAcceptableTrialPoint(); + + /** Method for accepting the trial point as the new iteration, + * possibly after adjusting the variable bounds in the NLP. */ + void AcceptTrialPoint(); + + /** Do all the output for one iteration */ + void OutputIteration(); + + /** Sets up initial values for the iterates, + * Corrects the initial values for x and s (force in bounds) + */ + void InitializeIterates(); + + /** Print the problem size statistics */ + void PrintProblemStatistics(); + + /** Compute the Lagrangian multipliers for a feasibility problem*/ + void ComputeFeasibilityMultipliers(); + //@} + + /** @name internal flags */ + //@{ + /** Flag indicating if the statistic should not be printed */ + bool skip_print_problem_stats_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** safeguard factor for bound multipliers. If value >= 1, then + * the dual variables will never deviate from the primal estimate + * by more than the factors kappa_sigma and 1./kappa_sigma. + */ + Number kappa_sigma_; + /** Flag indicating whether the y multipliers should be + * recalculated with the eq_mutliplier_calculator object for each + * new point. */ + bool recalc_y_; + /** Feasibility threshold for recalc_y */ + Number recalc_y_feas_tol_; + /** Flag indicating if we want to do Mehrotras's algorithm. This + * means that a number of options are ignored, or have to be set + * (or are automatically set) to certain values. */ + bool mehrotra_algorithm_; + /** String specifying linear solver */ + std::string linear_solver_; + //@} + + /** @name auxiliary functions */ + //@{ + void calc_number_of_bounds( + const Vector& x, + const Vector& x_L, + const Vector& x_U, + const Matrix& Px_L, + const Matrix& Px_U, + Index& n_tot, + Index& n_only_lower, + Index& n_both, + Index& n_only_upper); + + /** Method for ensuring that the trial multipliers are not too far + * from the primal estime. If a correction is made, new_trial_z + * is a pointer to the corrected multiplier, and the return value + * of this method give the magnitutde of the largest correction + * that we done. If no correction was made, new_trial_z is just + * a pointer to trial_z, and the return value is zero. + */ + Number correct_bound_multiplier(const Vector& trial_z, + const Vector& trial_slack, + const Vector& trial_compl, + SmartPtr<const Vector>& new_trial_z); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIpoptApplication.hpp b/thirdparty/linux/include/coin/coin/IpIpoptApplication.hpp new file mode 100644 index 0000000..0febc94 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIpoptApplication.hpp @@ -0,0 +1,296 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptApplication.hpp 2617 2015-11-26 16:00:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTAPPLICATION_HPP__ +#define __IPIPOPTAPPLICATION_HPP__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#include <iostream> + +#include "IpJournalist.hpp" +#include "IpTNLP.hpp" +#include "IpNLP.hpp" +/* Return codes for the Optimize call for an application */ +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(IPOPT_APPLICATION_ERROR); + + /* forward declarations */ + class IpoptAlgorithm; + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + class AlgorithmBuilder; + class RegisteredOptions; + class OptionsList; + class SolveStatistics; + + /** This is the main application class for making calls to Ipopt. */ + class IpoptApplication : public ReferencedObject + { + public: + IpoptApplication(bool create_console_out = true, + bool create_empty = false); + + /** Another constructor that assumes that the code in the + * (default) constructor has already been executed */ + IpoptApplication(SmartPtr<RegisteredOptions> reg_options, + SmartPtr<OptionsList> options, + SmartPtr<Journalist> jnlst); + + virtual ~IpoptApplication(); + + /** Method for creating a new IpoptApplication that uses the same + * journalist and registered options, and a copy of the options + list. */ + virtual SmartPtr<IpoptApplication> clone(); + + /** Initialization method. This method reads options from the + * input stream and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the input stream. + */ + virtual ApplicationReturnStatus Initialize(std::istream& is, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(std::string params_file, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(const char* params_file, bool allow_clobber = false) + { + return Initialize(std::string(params_file), allow_clobber); + } + /** Initialize method. This method reads the options file specified + * by the option_file_name option and initializes the journalists. + * You should call this method at some point before the first optimize + * call. + * It returns something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the options file. + */ + virtual ApplicationReturnStatus Initialize(bool allow_clobber = false); + + /**@name Solve methods */ + //@{ + /** Solve a problem that inherits from TNLP */ + virtual ApplicationReturnStatus OptimizeTNLP(const SmartPtr<TNLP>& tnlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr<NLP>& nlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr<NLP>& nlp, SmartPtr<AlgorithmBuilder>& alg_builder); + + /** Solve a problem (that inherits from TNLP) for a repeated time. + * The OptimizeTNLP method must have been called before. The + * TNLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeTNLP(const SmartPtr<TNLP>& tnlp); + + /** Solve a problem (that inherits from NLP) for a repeated time. + * The OptimizeNLP method must have been called before. The + * NLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeNLP(const SmartPtr<NLP>& nlp); + //@} + + /** Method for opening an output file with given print_level. + * Returns false if there was a problem. */ + virtual bool OpenOutputFile(std::string file_name, EJournalLevel print_level); + + /**@name Accessor methods */ + //@{ + /** Get the Journalist for printing output */ + virtual SmartPtr<Journalist> Jnlst() + { + return jnlst_; + } + + /** Get a pointer to RegisteredOptions object to + * add new options */ + virtual SmartPtr<RegisteredOptions> RegOptions() + { + return reg_options_; + } + + /** Get the options list for setting options */ + virtual SmartPtr<OptionsList> Options() + { + return options_; + } + + /** Get the options list for setting options (const version) */ + virtual SmartPtr<const OptionsList> Options() const + { + return ConstPtr(options_); + } + + /** Get the object with the statistics about the most recent + * optimization run. */ + virtual SmartPtr<SolveStatistics> Statistics(); + + /** Get the IpoptNLP Object */ + virtual SmartPtr<IpoptNLP> IpoptNLPObject(); + + /** Get the IpoptData Object */ + SmartPtr<IpoptData> IpoptDataObject(); + + /** Get the IpoptCQ Object */ + virtual SmartPtr<IpoptCalculatedQuantities> IpoptCQObject(); + + /** Get the Algorithm Object */ + SmartPtr<IpoptAlgorithm> AlgorithmObject(); + //@} + + /** Method for printing Ipopt copyright message now instead of + * just before the optimization. If you want to have the copy + * right message printed earlier than by default, call this + * method at the convenient time. */ + void PrintCopyrightMessage(); + + /** Method to set whether non-ipopt non-bad_alloc exceptions + * are rethrown by Ipopt. + * By default, non-Ipopt and non-std::bad_alloc exceptions are + * caught by Ipopts initialization and optimization methods + * and the status NonIpopt_Exception_Thrown is returned. + * This function allows to enable rethrowing of such exceptions. + */ + void RethrowNonIpoptException(bool dorethrow) + { + rethrow_nonipoptexception_ = dorethrow; + } + + /** @name Methods for IpoptTypeInfo */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Method to registering all Ipopt options. */ + static void + RegisterAllIpoptOptions(const SmartPtr<RegisteredOptions>& roptions); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // IpoptApplication(); + + /** Copy Constructor */ + IpoptApplication(const IpoptApplication&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptApplication&); + //@} + + /** Method for the actual optimize call of the Ipopt algorithm. + * This is used both for Optimize and ReOptimize */ + ApplicationReturnStatus call_optimize(); + + /**@name Variables that customize the application behavior */ + //@{ + /** Decide whether or not the ipopt.opt file should be read */ + bool read_params_dat_; + + /** Decide whether non-ipopt non-bad_alloc exceptions should be rethrown */ + bool rethrow_nonipoptexception_; + //@} + + /** Journalist for reporting output */ + SmartPtr<Journalist> jnlst_; + + /** RegisteredOptions */ + SmartPtr<RegisteredOptions> reg_options_; + + /** OptionsList used for the application */ + SmartPtr<OptionsList> options_; + + /** Object for storing statistics about the most recent + * optimization run. */ + SmartPtr<SolveStatistics> statistics_; + + /** Object with the algorithm sceleton. + */ + SmartPtr<IpoptAlgorithm> alg_; + + /** IpoptNLP Object for the NLP. We keep this around for a + * ReOptimize warm start. */ + SmartPtr<IpoptNLP> ip_nlp_; + + /** IpoptData Object for the NLP. We keep this around for a + * ReOptimize warm start. + */ + SmartPtr<IpoptData> ip_data_; + + /** IpoptCalculatedQuantities Object for the NLP. We keep this + * around for a ReOptimize warm start. + */ + SmartPtr<IpoptCalculatedQuantities> ip_cq_; + + /** Pointer to the TNLPAdapter used to convert the TNLP to an NLP. + * We keep this around for the ReOptimizerTNLP call. */ + SmartPtr<NLP> nlp_adapter_; + + /** @name Algorithmic parameters */ + //@{ + /** Flag indicating if we are to use the inexact linear solver option */ + bool inexact_algorithm_; + /** Flag indicating if all bounds should be replaced by inequality + * constraints. This is necessary for the inexact algorithm. */ + bool replace_bounds_; + //@} + }; + +} // namespace Ipopt + +extern "C" IPOPT_EXPORT(class Ipopt::IpoptApplication *) IpoptApplicationFactory(); + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIpoptCalculatedQuantities.hpp b/thirdparty/linux/include/coin/coin/IpIpoptCalculatedQuantities.hpp new file mode 100644 index 0000000..3b60b16 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIpoptCalculatedQuantities.hpp @@ -0,0 +1,751 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptCalculatedQuantities.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTCALCULATEDQUANTITIES_HPP__ +#define __IPIPOPTCALCULATEDQUANTITIES_HPP__ + +#include "IpSmartPtr.hpp" +#include "IpCachedResults.hpp" + +#include <string> + +namespace Ipopt +{ + class IpoptNLP; + class IpoptData; + class Vector; + class Matrix; + class SymMatrix; + class Journalist; + class OptionsList; + class RegisteredOptions; + + /** Norm types */ + enum ENormType { + NORM_1=0, + NORM_2, + NORM_MAX + }; + + /** Base class for additional calculated quantities that is special + * to a particular type of algorithm, such as the CG penalty + * function, or using iterative linear solvers. The regular + * IpoptCalculatedQuantities object should be given a derivation of + * this base class when it is created. */ + class IpoptAdditionalCq : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalCq() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalCq() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalCq(const IpoptAdditionalCq&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalCq&); + //@} + }; + + /** Class for all IPOPT specific calculated quantities. + * + */ + class IpoptCalculatedQuantities : public ReferencedObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptCalculatedQuantities(const SmartPtr<IpoptNLP>& ip_nlp, + const SmartPtr<IpoptData>& ip_data); + /** Default destructor */ + virtual ~IpoptCalculatedQuantities(); + //@} + + /** Method for setting pointer for additional calculated + * quantities. This needs to be called before Initialized. */ + void SetAddCq(SmartPtr<IpoptAdditionalCq> add_cq) + { + DBG_ASSERT(!HaveAddCq()); + add_cq_ = add_cq; + } + + /** Method detecting if additional object for calculated + * quantities has already been set */ + bool HaveAddCq() + { + return IsValid(add_cq_); + } + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Slacks */ + //@{ + /** Slacks for x_L (at current iterate) */ + SmartPtr<const Vector> curr_slack_x_L(); + /** Slacks for x_U (at current iterate) */ + SmartPtr<const Vector> curr_slack_x_U(); + /** Slacks for s_L (at current iterate) */ + SmartPtr<const Vector> curr_slack_s_L(); + /** Slacks for s_U (at current iterate) */ + SmartPtr<const Vector> curr_slack_s_U(); + /** Slacks for x_L (at trial point) */ + SmartPtr<const Vector> trial_slack_x_L(); + /** Slacks for x_U (at trial point) */ + SmartPtr<const Vector> trial_slack_x_U(); + /** Slacks for s_L (at trial point) */ + SmartPtr<const Vector> trial_slack_s_L(); + /** Slacks for s_U (at trial point) */ + SmartPtr<const Vector> trial_slack_s_U(); + /** Indicating whether or not we "fudged" the slacks */ + Index AdjustedTrialSlacks(); + /** Reset the flags for "fudged" slacks */ + void ResetAdjustedTrialSlacks(); + //@} + + /** @name Objective function */ + //@{ + /** Value of objective function (at current point) */ + virtual Number curr_f(); + /** Unscaled value of the objective function (at the current point) */ + virtual Number unscaled_curr_f(); + /** Value of objective function (at trial point) */ + virtual Number trial_f(); + /** Unscaled value of the objective function (at the trial point) */ + virtual Number unscaled_trial_f(); + /** Gradient of objective function (at current point) */ + SmartPtr<const Vector> curr_grad_f(); + /** Gradient of objective function (at trial point) */ + SmartPtr<const Vector> trial_grad_f(); + //@} + + /** @name Barrier Objective Function */ + //@{ + /** Barrier Objective Function Value + * (at current iterate with current mu) + */ + virtual Number curr_barrier_obj(); + /** Barrier Objective Function Value + * (at trial point with current mu) + */ + virtual Number trial_barrier_obj(); + + /** Gradient of barrier objective function with respect to x + * (at current point with current mu) */ + SmartPtr<const Vector> curr_grad_barrier_obj_x(); + /** Gradient of barrier objective function with respect to s + * (at current point with current mu) */ + SmartPtr<const Vector> curr_grad_barrier_obj_s(); + + /** Gradient of the damping term with respect to x (times + * kappa_d) */ + SmartPtr<const Vector> grad_kappa_times_damping_x(); + /** Gradient of the damping term with respect to s (times + * kappa_d) */ + SmartPtr<const Vector> grad_kappa_times_damping_s(); + //@} + + /** @name Constraints */ + //@{ + /** c(x) (at current point) */ + SmartPtr<const Vector> curr_c(); + /** unscaled c(x) (at current point) */ + SmartPtr<const Vector> unscaled_curr_c(); + /** c(x) (at trial point) */ + SmartPtr<const Vector> trial_c(); + /** unscaled c(x) (at trial point) */ + SmartPtr<const Vector> unscaled_trial_c(); + /** d(x) (at current point) */ + SmartPtr<const Vector> curr_d(); + /** unscaled d(x) (at current point) */ + SmartPtr<const Vector> unscaled_curr_d(); + /** d(x) (at trial point) */ + SmartPtr<const Vector> trial_d(); + /** d(x) - s (at current point) */ + SmartPtr<const Vector> curr_d_minus_s(); + /** d(x) - s (at trial point) */ + SmartPtr<const Vector> trial_d_minus_s(); + /** Jacobian of c (at current point) */ + SmartPtr<const Matrix> curr_jac_c(); + /** Jacobian of c (at trial point) */ + SmartPtr<const Matrix> trial_jac_c(); + /** Jacobian of d (at current point) */ + SmartPtr<const Matrix> curr_jac_d(); + /** Jacobian of d (at trial point) */ + SmartPtr<const Matrix> trial_jac_d(); + /** Product of Jacobian (evaluated at current point) of C + * transpose with general vector */ + SmartPtr<const Vector> curr_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with general vector */ + SmartPtr<const Vector> trial_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * transpose with general vector */ + SmartPtr<const Vector> curr_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with general vector */ + SmartPtr<const Vector> trial_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of C + * transpose with current y_c */ + SmartPtr<const Vector> curr_jac_cT_times_curr_y_c(); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with trial y_c */ + SmartPtr<const Vector> trial_jac_cT_times_trial_y_c(); + /** Product of Jacobian (evaluated at current point) of D + * transpose with current y_d */ + SmartPtr<const Vector> curr_jac_dT_times_curr_y_d(); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with trial y_d */ + SmartPtr<const Vector> trial_jac_dT_times_trial_y_d(); + /** Product of Jacobian (evaluated at current point) of C + * with general vector */ + SmartPtr<const Vector> curr_jac_c_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * with general vector */ + SmartPtr<const Vector> curr_jac_d_times_vec(const Vector& vec); + /** Constraint Violation (at current iterate). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number curr_constraint_violation(); + /** Constraint Violation (at trial point). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number trial_constraint_violation(); + /** Real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at trial + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_trial_nlp_constraint_violation(ENormType NormType); + //@} + + /** @name Hessian matrices */ + //@{ + /** exact Hessian at current iterate (uncached) */ + SmartPtr<const SymMatrix> curr_exact_hessian(); + //@} + + /** @name primal-dual error and its components */ + //@{ + /** x-part of gradient of Lagrangian function (at current point) */ + SmartPtr<const Vector> curr_grad_lag_x(); + /** x-part of gradient of Lagrangian function (at trial point) */ + SmartPtr<const Vector> trial_grad_lag_x(); + /** s-part of gradient of Lagrangian function (at current point) */ + SmartPtr<const Vector> curr_grad_lag_s(); + /** s-part of gradient of Lagrangian function (at trial point) */ + SmartPtr<const Vector> trial_grad_lag_s(); + /** x-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr<const Vector> curr_grad_lag_with_damping_x(); + /** s-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr<const Vector> curr_grad_lag_with_damping_s(); + /** Complementarity for x_L (for current iterate) */ + SmartPtr<const Vector> curr_compl_x_L(); + /** Complementarity for x_U (for current iterate) */ + SmartPtr<const Vector> curr_compl_x_U(); + /** Complementarity for s_L (for current iterate) */ + SmartPtr<const Vector> curr_compl_s_L(); + /** Complementarity for s_U (for current iterate) */ + SmartPtr<const Vector> curr_compl_s_U(); + /** Complementarity for x_L (for trial iterate) */ + SmartPtr<const Vector> trial_compl_x_L(); + /** Complementarity for x_U (for trial iterate) */ + SmartPtr<const Vector> trial_compl_x_U(); + /** Complementarity for s_L (for trial iterate) */ + SmartPtr<const Vector> trial_compl_s_L(); + /** Complementarity for s_U (for trial iterate) */ + SmartPtr<const Vector> trial_compl_s_U(); + /** Relaxed complementarity for x_L (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_x_L(); + /** Relaxed complementarity for x_U (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_x_U(); + /** Relaxed complementarity for s_L (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_s_L(); + /** Relaxed complementarity for s_U (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_s_U(); + + /** Primal infeasibility in a given norm (at current iterate). */ + virtual Number curr_primal_infeasibility(ENormType NormType); + /** Primal infeasibility in a given norm (at trial point) */ + virtual Number trial_primal_infeasibility(ENormType NormType); + + /** Dual infeasibility in a given norm (at current iterate) */ + virtual Number curr_dual_infeasibility(ENormType NormType); + /** Dual infeasibility in a given norm (at trial iterate) */ + virtual Number trial_dual_infeasibility(ENormType NormType); + /** Unscaled dual infeasibility in a given norm (at current iterate) */ + virtual Number unscaled_curr_dual_infeasibility(ENormType NormType); + + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) */ + virtual Number curr_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at trial iterate) */ + virtual Number trial_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) without NLP scaling. */ + virtual Number unscaled_curr_complementarity(Number mu, ENormType NormType); + + /** Centrality measure (in spirit of the -infinity-neighborhood. */ + Number CalcCentralityMeasure(const Vector& compl_x_L, + const Vector& compl_x_U, + const Vector& compl_s_L, + const Vector& compl_s_U); + /** Centrality measure at current point */ + virtual Number curr_centrality_measure(); + + /** Total optimality error for the original NLP at the current + * iterate, using scaling factors based on multipliers. Note + * that here the constraint violation is measured without slacks + * (nlp_constraint_violation) */ + virtual Number curr_nlp_error(); + /** Total optimality error for the original NLP at the current + * iterate, but using no scaling based on multipliers, and no + * scaling for the NLP. Note that here the constraint violation + * is measured without slacks (nlp_constraint_violation) */ + virtual Number unscaled_curr_nlp_error(); + + /** Total optimality error for the barrier problem at the + * current iterate, using scaling factors based on multipliers. */ + virtual Number curr_barrier_error(); + + /** Norm of the primal-dual system for a given mu (at current + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number curr_primal_dual_system_error(Number mu); + /** Norm of the primal-dual system for a given mu (at trial + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number trial_primal_dual_system_error(Number mu); + //@} + + /** @name Computing fraction-to-the-boundary step sizes */ + //@{ + /** Fraction to the boundary from (current) primal variables x and s + * for a given step */ + Number primal_frac_to_the_bound(Number tau, + const Vector& delta_x, + const Vector& delta_s); + /** Fraction to the boundary from (current) primal variables x and s + * for internal (current) step */ + Number curr_primal_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step */ + Number dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step, without caching */ + Number uncached_dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for internal (current) step */ + Number curr_dual_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) slacks for a given + * step in the slacks. Usually, one will use the + * primal_frac_to_the_bound method to compute the primal fraction + * to the boundary step size, but if it is cheaper to provide the + * steps in the slacks directly (e.g. when the primal step sizes + * are only temporary), the this method is more efficient. This + * method does not cache computations. */ + Number uncached_slack_frac_to_the_bound(Number tau, + const Vector& delta_x_L, + const Vector& delta_x_U, + const Vector& delta_s_L, + const Vector& delta_s_U); + //@} + + /** @name Sigma matrices */ + //@{ + SmartPtr<const Vector> curr_sigma_x(); + SmartPtr<const Vector> curr_sigma_s(); + //@} + + /** average of current values of the complementarities */ + Number curr_avrg_compl(); + /** average of trial values of the complementarities */ + Number trial_avrg_compl(); + + /** inner_product of current barrier obj. fn. gradient with + * current search direction */ + Number curr_gradBarrTDelta(); + + /** Compute the norm of a specific type of a set of vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + std::vector<SmartPtr<const Vector> > vecs); + + /** Compute the norm of a specific type of two vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + const Vector& vec1, const Vector& vec2); + + /** Norm type used for calculating constraint violation */ + ENormType constr_viol_normtype() const + { + return constr_viol_normtype_; + } + + /** Method returning true if this is a square problem */ + bool IsSquareProblem() const; + + /** Method returning the IpoptNLP object. This should only be + * used with care! */ + SmartPtr<IpoptNLP>& GetIpoptNLP() + { + return ip_nlp_; + } + + IpoptAdditionalCq& AdditionalCq() + { + DBG_ASSERT(IsValid(add_cq_)); + return *add_cq_; + } + + /** Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptCalculatedQuantities(); + + /** Copy Constructor */ + IpoptCalculatedQuantities(const IpoptCalculatedQuantities&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptCalculatedQuantities&); + //@} + + /** @name Pointers for easy access to data and NLP information */ + //@{ + /** Ipopt NLP object */ + SmartPtr<IpoptNLP> ip_nlp_; + /** Ipopt Data object */ + SmartPtr<IpoptData> ip_data_; + /** Chen-Goldfarb specific calculated quantities */ + SmartPtr<IpoptAdditionalCq> add_cq_; + //@} + + /** @name Algorithmic Parameters that can be set throught the + * options list. Those parameters are initialize by calling the + * Initialize method.*/ + //@{ + /** Parameter in formula for computing overall primal-dual + * optimality error */ + Number s_max_; + /** Weighting factor for the linear damping term added to the + * barrier objective funciton. */ + Number kappa_d_; + /** fractional movement allowed in bounds */ + Number slack_move_; + /** Norm type to be used when calculating the constraint violation */ + ENormType constr_viol_normtype_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Desired value of the barrier parameter */ + Number mu_target_; + //@} + + /** @name Caches for slacks */ + //@{ + CachedResults< SmartPtr<Vector> > curr_slack_x_L_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_x_U_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_s_L_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_s_U_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_x_L_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_x_U_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_s_L_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_s_U_cache_; + Index num_adjusted_slack_x_L_; + Index num_adjusted_slack_x_U_; + Index num_adjusted_slack_s_L_; + Index num_adjusted_slack_s_U_; + //@} + + /** @name Cached for objective function stuff */ + //@{ + CachedResults<Number> curr_f_cache_; + CachedResults<Number> trial_f_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_f_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_f_cache_; + //@} + + /** @name Caches for barrier function stuff */ + //@{ + CachedResults<Number> curr_barrier_obj_cache_; + CachedResults<Number> trial_barrier_obj_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_barrier_obj_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_barrier_obj_s_cache_; + CachedResults< SmartPtr<const Vector> > grad_kappa_times_damping_x_cache_; + CachedResults< SmartPtr<const Vector> > grad_kappa_times_damping_s_cache_; + //@} + + /** @name Caches for constraint stuff */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_c_cache_; + CachedResults< SmartPtr<const Vector> > trial_c_cache_; + CachedResults< SmartPtr<const Vector> > curr_d_cache_; + CachedResults< SmartPtr<const Vector> > trial_d_cache_; + CachedResults< SmartPtr<const Vector> > curr_d_minus_s_cache_; + CachedResults< SmartPtr<const Vector> > trial_d_minus_s_cache_; + CachedResults< SmartPtr<const Matrix> > curr_jac_c_cache_; + CachedResults< SmartPtr<const Matrix> > trial_jac_c_cache_; + CachedResults< SmartPtr<const Matrix> > curr_jac_d_cache_; + CachedResults< SmartPtr<const Matrix> > trial_jac_d_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_cT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > trial_jac_cT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_dT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > trial_jac_dT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_c_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_d_times_vec_cache_; + CachedResults<Number> curr_constraint_violation_cache_; + CachedResults<Number> trial_constraint_violation_cache_; + CachedResults<Number> curr_nlp_constraint_violation_cache_; + CachedResults<Number> unscaled_curr_nlp_constraint_violation_cache_; + CachedResults<Number> unscaled_trial_nlp_constraint_violation_cache_; + //@} + + /** Cache for the exact Hessian */ + CachedResults< SmartPtr<const SymMatrix> > curr_exact_hessian_cache_; + + /** @name Components of primal-dual error */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_grad_lag_x_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_lag_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_s_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_lag_s_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_with_damping_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_with_damping_s_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_s_U_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_s_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_s_U_cache_; + CachedResults<Number> curr_primal_infeasibility_cache_; + CachedResults<Number> trial_primal_infeasibility_cache_; + CachedResults<Number> curr_dual_infeasibility_cache_; + CachedResults<Number> trial_dual_infeasibility_cache_; + CachedResults<Number> unscaled_curr_dual_infeasibility_cache_; + CachedResults<Number> curr_complementarity_cache_; + CachedResults<Number> trial_complementarity_cache_; + CachedResults<Number> curr_centrality_measure_cache_; + CachedResults<Number> curr_nlp_error_cache_; + CachedResults<Number> unscaled_curr_nlp_error_cache_; + CachedResults<Number> curr_barrier_error_cache_; + CachedResults<Number> curr_primal_dual_system_error_cache_; + CachedResults<Number> trial_primal_dual_system_error_cache_; + //@} + + /** @name Caches for fraction to the boundary step sizes */ + //@{ + CachedResults<Number> primal_frac_to_the_bound_cache_; + CachedResults<Number> dual_frac_to_the_bound_cache_; + //@} + + /** @name Caches for sigma matrices */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_sigma_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_sigma_s_cache_; + //@} + + /** Cache for average of current complementarity */ + CachedResults<Number> curr_avrg_compl_cache_; + /** Cache for average of trial complementarity */ + CachedResults<Number> trial_avrg_compl_cache_; + + /** Cache for grad barrier obj. fn inner product with step */ + CachedResults<Number> curr_gradBarrTDelta_cache_; + + /** @name Indicator vectors required for the linear damping terms + * to handle unbounded solution sets. */ + //@{ + /** Indicator vector for selecting the elements in x that have + * only lower bounds. */ + SmartPtr<Vector> dampind_x_L_; + /** Indicator vector for selecting the elements in x that have + * only upper bounds. */ + SmartPtr<Vector> dampind_x_U_; + /** Indicator vector for selecting the elements in s that have + * only lower bounds. */ + SmartPtr<Vector> dampind_s_L_; + /** Indicator vector for selecting the elements in s that have + * only upper bounds. */ + SmartPtr<Vector> dampind_s_U_; + //@} + + /** @name Temporary vectors for intermediate calcuations. We keep + * these around to avoid unnecessarily many new allocations of + * Vectors. */ + //@{ + SmartPtr<Vector> tmp_x_; + SmartPtr<Vector> tmp_s_; + SmartPtr<Vector> tmp_c_; + SmartPtr<Vector> tmp_d_; + SmartPtr<Vector> tmp_x_L_; + SmartPtr<Vector> tmp_x_U_; + SmartPtr<Vector> tmp_s_L_; + SmartPtr<Vector> tmp_s_U_; + + /** Accessor methods for the temporary vectors */ + Vector& Tmp_x(); + Vector& Tmp_s(); + Vector& Tmp_c(); + Vector& Tmp_d(); + Vector& Tmp_x_L(); + Vector& Tmp_x_U(); + Vector& Tmp_s_L(); + Vector& Tmp_s_U(); + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** @name Auxiliary functions */ + //@{ + /** Compute new vector containing the slack to a lower bound + * (uncached) + */ + SmartPtr<Vector> CalcSlack_L(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute new vector containing the slack to a upper bound + * (uncached) + */ + SmartPtr<Vector> CalcSlack_U(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute barrier term at given point + * (uncached) + */ + Number CalcBarrierTerm(Number mu, + const Vector& slack_x_L, + const Vector& slack_x_U, + const Vector& slack_s_L, + const Vector& slack_s_U); + + /** Compute complementarity for slack / multiplier pair */ + SmartPtr<const Vector> CalcCompl(const Vector& slack, + const Vector& mult); + + /** Compute fraction to the boundary parameter for lower and upper bounds */ + Number CalcFracToBound(const Vector& slack_L, + Vector& tmp_L, + const Matrix& P_L, + const Vector& slack_U, + Vector& tmp_U, + const Matrix& P_U, + const Vector& delta, + Number tau); + + /** Compute the scaling factors for the optimality error. */ + void ComputeOptimalityErrorScaling(const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U, + Number s_max, + Number& s_d, Number& s_c); + + /** Check if slacks are becoming too small. If slacks are + * becoming too small, they are change. The return value is the + * number of corrected slacks. */ + Index CalculateSafeSlack(SmartPtr<Vector>& slack, + const SmartPtr<const Vector>& bound, + const SmartPtr<const Vector>& curr_point, + const SmartPtr<const Vector>& multiplier); + + /** Computes the indicator vectors that can be used to filter out + * those entries in the slack_... variables, that correspond to + * variables with only lower and upper bounds. This is required + * for the linear damping term in the barrier objective function + * to handle unbounded solution sets. */ + void ComputeDampingIndicators(SmartPtr<const Vector>& dampind_x_L, + SmartPtr<const Vector>& dampind_x_U, + SmartPtr<const Vector>& dampind_s_L, + SmartPtr<const Vector>& dampind_s_U); + + /** Check if we are in the restoration phase. Returns true, if the + * ip_nlp is of the type RestoIpoptNLP. ToDo: We probably want to + * handle this more elegant and don't have an explicit dependency + * here. Now I added this because otherwise the caching doesn't + * work properly since the restoration phase objective function + * depends on the current barrier parameter. */ + bool in_restoration_phase(); + + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIpoptData.hpp b/thirdparty/linux/include/coin/coin/IpIpoptData.hpp new file mode 100644 index 0000000..6973bab --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIpoptData.hpp @@ -0,0 +1,819 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptData.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTDATA_HPP__ +#define __IPIPOPTDATA_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpIteratesVector.hpp" +#include "IpRegOptions.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /* Forward declaration */ + class IpoptNLP; + + /** Base class for additional data that is special to a particular + * type of algorithm, such as the CG penalty function, or using + * iterative linear solvers. The regular IpoptData object should + * be given a derivation of this base class when it is created. */ + class IpoptAdditionalData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalData() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalData() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + /** Initialize Data Structures at the beginning. */ + virtual bool InitializeDataStructures() = 0; + + /** Do whatever is necessary to accept a trial point as current + * iterate. This is also used to finish an iteration, i.e., to + * release memory, and to reset any flags for a new iteration. */ + virtual void AcceptTrialPoint() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalData(const IpoptAdditionalData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalData&); + //@} + }; + + /** Class to organize all the data required by the algorithm. + * Internally, once this Data object has been initialized, all + * internal curr_ vectors must always be set (so that prototyes are + * available). The current values can only be set from the trial + * values. The trial values can be set by copying from a vector or + * by adding some fraction of a step to the current values. This + * object also stores steps, which allows to easily communicate the + * step from the step computation object to the line search object. + */ + class IpoptData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptData(SmartPtr<IpoptAdditionalData> add_data = NULL, + Number cpu_time_start = -1.); + + /** Default destructor */ + virtual ~IpoptData(); + //@} + + /** Initialize Data Structures */ + bool InitializeDataStructures(IpoptNLP& ip_nlp, + bool want_x, + bool want_y_c, + bool want_y_d, + bool want_z_L, + bool want_z_U); + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Get Methods for Iterates */ + //@{ + /** Current point */ + inline + SmartPtr<const IteratesVector> curr() const; + + /** Get the current point in a copied container that is non-const. + The entries in the container cannot be modified, but + the container can be modified to point to new entries. + */ + // SmartPtr<IteratesVector> curr_container() const; + + /** Get Trial point */ + inline + SmartPtr<const IteratesVector> trial() const; + + /** Get Trial point in a copied container that is non-const. + * The entries in the container can not be modified, but + * the container can be modified to point to new entries. + */ + //SmartPtr<IteratesVector> trial_container() const; + + /** Set the trial point - this method copies the pointer for + * efficiency (no copy and to keep cache tags the same) so + * after you call set you cannot modify the data again + */ + inline + void set_trial(SmartPtr<IteratesVector>& trial); + + /** Set the values of the primal trial variables (x and s) from + * provided Step with step length alpha. + */ + void SetTrialPrimalVariablesFromStep(Number alpha, + const Vector& delta_x, + const Vector& delta_s); + /** Set the values of the trial values for the equality constraint + * multipliers (y_c and y_d) from provided step with step length + * alpha. + */ + void SetTrialEqMultipliersFromStep(Number alpha, + const Vector& delta_y_c, + const Vector& delta_y_d); + /** Set the value of the trial values for the bound multipliers + * (z_L, z_U, v_L, v_U) from provided step with step length + * alpha. + */ + void SetTrialBoundMultipliersFromStep(Number alpha, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + + /** ToDo: I may need to add versions of set_trial like the + * following, but I am not sure + */ + // void set_trial(const SmartPtr<IteratesVector>& trial_iterates); + // void set_trial(SmartPtr<const IteratesVector>& trial_iterates); + + /** get the current delta */ + inline + SmartPtr<const IteratesVector> delta() const; + + /** Set the current delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta(SmartPtr<IteratesVector>& delta); + + /** Set the current delta - like the trial point, this method + * copies the pointer for efficiency (no copy and to keep cache + * tags the same) so after you call set, you cannot modify the + * data. This is the version that is happy with a pointer to + * const IteratesVector. + */ + inline + void set_delta(SmartPtr<const IteratesVector>& delta); + + /** Affine Delta */ + inline + SmartPtr<const IteratesVector> delta_aff() const; + + /** Set the affine delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta_aff(SmartPtr<IteratesVector>& delta_aff); + + /** Hessian or Hessian approximation (do not hold on to it, it might be changed) */ + SmartPtr<const SymMatrix> W() + { + DBG_ASSERT(IsValid(W_)); + return W_; + } + + /** Set Hessian approximation */ + void Set_W(SmartPtr<const SymMatrix> W) + { + W_ = W; + } + + /** @name ("Main") Primal-dual search direction. Those fields are + * used to store the search directions computed from solving the + * primal-dual system, and can be used in the line search. They + * are overwritten in every iteration, so do not hold on to the + * pointers (make copies instead) */ + //@{ + + /** Returns true, if the primal-dual step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the IpoptAlgorithm object that it + * doesn't need to recompute the primal-dual step. */ + bool HaveDeltas() const + { + return have_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveDeltas(bool have_deltas) + { + have_deltas_ = have_deltas; + } + //@} + + /** @name Affine-scaling step. Those fields can be used to store + * the affine scaling step. For example, if the method for + * computing the current barrier parameter computes the affine + * scaling steps, then the corrector step in the line search does + * not have to recompute those solutions of the linear system. */ + //@{ + + /** Returns true, if the affine-scaling step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the line search does not have to + * recompute them in case it wants to do a corrector step. */ + bool HaveAffineDeltas() const + { + return have_affine_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveAffineDeltas(bool have_affine_deltas) + { + have_affine_deltas_ = have_affine_deltas; + } + //@} + + /** @name Public Methods for updating iterates */ + //@{ + /** Copy the trial values to the current values */ + inline + void CopyTrialToCurrent(); + + /** Set the current iterate values from the + * trial values. */ + void AcceptTrialPoint(); + //@} + + /** @name General algorithmic data */ + //@{ + Index iter_count() const + { + return iter_count_; + } + void Set_iter_count(Index iter_count) + { + iter_count_ = iter_count; + } + + Number curr_mu() const + { + DBG_ASSERT(mu_initialized_); + return curr_mu_; + } + void Set_mu(Number mu) + { + curr_mu_ = mu; + mu_initialized_ = true; + } + bool MuInitialized() const + { + return mu_initialized_; + } + + Number curr_tau() const + { + DBG_ASSERT(tau_initialized_); + return curr_tau_; + } + void Set_tau(Number tau) + { + curr_tau_ = tau; + tau_initialized_ = true; + } + bool TauInitialized() const + { + return tau_initialized_; + } + + void SetFreeMuMode(bool free_mu_mode) + { + free_mu_mode_ = free_mu_mode; + } + bool FreeMuMode() const + { + return free_mu_mode_; + } + + /** Setting the flag that indicates if a tiny step (below machine + * precision) has been detected */ + void Set_tiny_step_flag(bool flag) + { + tiny_step_flag_ = flag; + } + bool tiny_step_flag() + { + return tiny_step_flag_; + } + //@} + + /** Overall convergence tolerance. It is used in the convergence + * test, but also in some other parts of the algorithm that + * depend on the specified tolerance, such as the minimum value + * for the barrier parameter. */ + //@{ + /** Obtain the tolerance. */ + Number tol() const + { + DBG_ASSERT(initialize_called_); + return tol_; + } + /** Set a new value for the tolerance. One should be very careful + * when using this, since changing the predefined tolerance might + * have unexpected consequences. This method is for example used + * in the restoration convergence checker to tighten the + * restoration phase convergence tolerance, if the restoration + * phase converged to a point that has not a large value for the + * constraint violation. */ + void Set_tol(Number tol) + { + tol_ = tol; + } + //@} + + /** Cpu time counter at the beginning of the optimization. This + * is useful to see how much CPU time has been spent in this + * optimization run. */ + Number cpu_time_start() const + { + return cpu_time_start_; + } + + /** @name Information gathered for iteration output */ + //@{ + Number info_regu_x() const + { + return info_regu_x_; + } + void Set_info_regu_x(Number regu_x) + { + info_regu_x_ = regu_x; + } + Number info_alpha_primal() const + { + return info_alpha_primal_; + } + void Set_info_alpha_primal(Number alpha_primal) + { + info_alpha_primal_ = alpha_primal; + } + char info_alpha_primal_char() const + { + return info_alpha_primal_char_; + } + void Set_info_alpha_primal_char(char info_alpha_primal_char) + { + info_alpha_primal_char_ = info_alpha_primal_char; + } + Number info_alpha_dual() const + { + return info_alpha_dual_; + } + void Set_info_alpha_dual(Number alpha_dual) + { + info_alpha_dual_ = alpha_dual; + } + Index info_ls_count() const + { + return info_ls_count_; + } + void Set_info_ls_count(Index ls_count) + { + info_ls_count_ = ls_count; + } + bool info_skip_output() const + { + return info_skip_output_; + } + void Append_info_string(const std::string& add_str) + { + info_string_ += add_str; + } + const std::string& info_string() const + { + return info_string_; + } + /** Set this to true, if the next time when output is written, the + * summary line should not be printed. */ + void Set_info_skip_output(bool info_skip_output) + { + info_skip_output_ = info_skip_output; + } + + /** gives time when the last summary output line was printed */ + Number info_last_output() + { + return info_last_output_; + } + /** sets time when the last summary output line was printed */ + void Set_info_last_output(Number info_last_output) + { + info_last_output_ = info_last_output; + } + + /** gives number of iteration summaries actually printed + * since last summary header was printed */ + int info_iters_since_header() + { + return info_iters_since_header_; + } + /** increases number of iteration summaries actually printed + * since last summary header was printed */ + void Inc_info_iters_since_header() + { + info_iters_since_header_++; + } + /** sets number of iteration summaries actually printed + * since last summary header was printed */ + void Set_info_iters_since_header(int info_iters_since_header) + { + info_iters_since_header_ = info_iters_since_header; + } + + /** Reset all info fields */ + void ResetInfo() + { + info_regu_x_ = 0; + info_alpha_primal_ = 0; + info_alpha_dual_ = 0.; + info_alpha_primal_char_ = ' '; + info_skip_output_ = false; + info_string_.erase(); + } + //@} + + /** Return Timing Statistics Object */ + TimingStatistics& TimingStats() + { + return timing_statistics_; + } + + /** Check if additional data has been set */ + bool HaveAddData() + { + return IsValid(add_data_); + } + + /** Get access to additional data object */ + IpoptAdditionalData& AdditionalData() + { + return *add_data_; + } + + /** Set a new pointer for additional Ipopt data */ + void SetAddData(SmartPtr<IpoptAdditionalData> add_data) + { + DBG_ASSERT(!HaveAddData()); + add_data_ = add_data; + } + + /** Set the perturbation of the primal-dual system */ + void setPDPert(Number pd_pert_x, Number pd_pert_s, + Number pd_pert_c, Number pd_pert_d) + { + pd_pert_x_ = pd_pert_x; + pd_pert_s_ = pd_pert_s; + pd_pert_c_ = pd_pert_c; + pd_pert_d_ = pd_pert_d; + } + + /** Get the current perturbation of the primal-dual system */ + void getPDPert(Number& pd_pert_x, Number& pd_pert_s, + Number& pd_pert_c, Number& pd_pert_d) + { + pd_pert_x = pd_pert_x_; + pd_pert_s = pd_pert_s_; + pd_pert_c = pd_pert_c_; + pd_pert_d = pd_pert_d_; + } + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(const SmartPtr<RegisteredOptions>& roptions); + //@} + + private: + /** @name Iterates */ + //@{ + /** Main iteration variables + * (current iteration) */ + SmartPtr<const IteratesVector> curr_; + + /** Main iteration variables + * (trial calculations) */ + SmartPtr<const IteratesVector> trial_; + + /** Hessian (approximation) - might be changed elsewhere! */ + SmartPtr<const SymMatrix> W_; + + /** @name Primal-dual Step */ + //@{ + SmartPtr<const IteratesVector> delta_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the primal-dual search + * direction. This flag is reset when the AcceptTrialPoint + * method is called. + * ToDo: we could cue off of a null delta_; + */ + bool have_deltas_; + //@} + + /** @name Affine-scaling step. This used to transfer the + * information about the affine-scaling step from the computation + * of the barrier parameter to the corrector (in the line + * search). */ + //@{ + SmartPtr<const IteratesVector> delta_aff_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the affine-scaling step. This + * flag is reset when the AcceptTrialPoint method is called. + * ToDo: we could cue off of a null delta_aff_; + */ + bool have_affine_deltas_; + //@} + + /** iteration count */ + Index iter_count_; + + /** current barrier parameter */ + Number curr_mu_; + bool mu_initialized_; + + /** current fraction to the boundary parameter */ + Number curr_tau_; + bool tau_initialized_; + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** flag for debugging whether we have already curr_ values + * available (from which new Vectors can be generated */ + bool have_prototypes_; + + /** @name Global algorithm parameters. Those are options that can + * be modified by the user and appear at different places in the + * algorithm. They are set using an OptionsList object in the + * Initialize method. */ + //@{ + /** Overall convergence tolerance */ + Number tol_; + //@} + + /** @name Status data **/ + //@{ + /** flag indicating whether the algorithm is in the free mu mode */ + bool free_mu_mode_; + /** flag indicating if a tiny step has been detected */ + bool tiny_step_flag_; + //@} + + /** @name Gathered information for iteration output */ + //@{ + /** Size of regularization for the Hessian */ + Number info_regu_x_; + /** Primal step size */ + Number info_alpha_primal_; + /** Info character for primal step size */ + char info_alpha_primal_char_; + /** Dual step size */ + Number info_alpha_dual_; + /** Number of backtracking trial steps */ + Index info_ls_count_; + /** true, if next summary output line should not be printed (eg + * after restoration phase. */ + bool info_skip_output_; + /** any string of characters for the end of the output line */ + std::string info_string_; + /** time when the last summary output line was printed */ + Number info_last_output_; + /** number of iteration summaries actually printed since last + * summary header was printed */ + int info_iters_since_header_; + //@} + + /** VectorSpace for all the iterates */ + SmartPtr<IteratesVectorSpace> iterates_space_; + + /** TimingStatistics object collecting all Ipopt timing + * statistics */ + TimingStatistics timing_statistics_; + + /** CPU time counter at initialization. */ + Number cpu_time_start_; + + /** Object for the data specific for the Chen-Goldfarb penalty + * method algorithm */ + SmartPtr<IpoptAdditionalData> add_data_; + + /** @name Information about the perturbation of the primal-dual + * system */ + //@{ + Number pd_pert_x_; + Number pd_pert_s_; + Number pd_pert_c_; + Number pd_pert_d_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptData(const IpoptData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptData&); + //@} + +#if COIN_IPOPT_CHECKLEVEL > 0 + /** Some debug flags to make sure vectors are not changed + * behind the IpoptData's back + */ + //@{ + TaggedObject::Tag debug_curr_tag_; + TaggedObject::Tag debug_trial_tag_; + TaggedObject::Tag debug_delta_tag_; + TaggedObject::Tag debug_delta_aff_tag_; + TaggedObject::Tag debug_curr_tag_sum_; + TaggedObject::Tag debug_trial_tag_sum_; + TaggedObject::Tag debug_delta_tag_sum_; + TaggedObject::Tag debug_delta_aff_tag_sum_; + //@} +#endif + + }; + + inline + SmartPtr<const IteratesVector> IpoptData::curr() const + { + DBG_ASSERT(IsNull(curr_) || (curr_->GetTag() == debug_curr_tag_ && curr_->GetTagSum() == debug_curr_tag_sum_) ); + + return curr_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::trial() const + { + DBG_ASSERT(IsNull(trial_) || (trial_->GetTag() == debug_trial_tag_ && trial_->GetTagSum() == debug_trial_tag_sum_) ); + + return trial_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::delta() const + { + DBG_ASSERT(IsNull(delta_) || (delta_->GetTag() == debug_delta_tag_ && delta_->GetTagSum() == debug_delta_tag_sum_) ); + + return delta_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::delta_aff() const + { + DBG_ASSERT(IsNull(delta_aff_) || (delta_aff_->GetTag() == debug_delta_aff_tag_ && delta_aff_->GetTagSum() == debug_delta_aff_tag_sum_) ); + + return delta_aff_; + } + + inline + void IpoptData::CopyTrialToCurrent() + { + curr_ = trial_; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(curr_)) { + debug_curr_tag_ = curr_->GetTag(); + debug_curr_tag_sum_ = curr_->GetTagSum(); + } + else { + debug_curr_tag_ = 0; + debug_curr_tag_sum_ = 0; + } +#endif + + } + + inline + void IpoptData::set_trial(SmartPtr<IteratesVector>& trial) + { + trial_ = ConstPtr(trial); + +#if COIN_IPOPT_CHECKLEVEL > 0 + // verify the correct space + DBG_ASSERT(trial_->OwnerSpace() == (VectorSpace*)GetRawPtr(iterates_space_)); + if (IsValid(trial)) { + debug_trial_tag_ = trial->GetTag(); + debug_trial_tag_sum_ = trial->GetTagSum(); + } + else { + debug_trial_tag_ = 0; + debug_trial_tag_sum_ = 0; + } +#endif + + trial = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr<IteratesVector>& delta) + { + delta_ = ConstPtr(delta); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr<const IteratesVector>& delta) + { + delta_ = delta; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta_aff(SmartPtr<IteratesVector>& delta_aff) + { + delta_aff_ = ConstPtr(delta_aff); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta_aff)) { + debug_delta_aff_tag_ = delta_aff->GetTag(); + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } + else { + debug_delta_aff_tag_ = 0; + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } +#endif + + delta_aff = NULL; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIpoptNLP.hpp b/thirdparty/linux/include/coin/coin/IpIpoptNLP.hpp new file mode 100644 index 0000000..21951c3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIpoptNLP.hpp @@ -0,0 +1,261 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTNLP_HPP__ +#define __IPIPOPTNLP_HPP__ + +#include "IpNLP.hpp" +#include "IpJournalist.hpp" +#include "IpNLPScaling.hpp" + +namespace Ipopt +{ + // forward declarations + class IteratesVector; + + /** This is the abstract base class for classes that map + * the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles cacheing, + * and (some day) takes care of addition of slacks. + */ + class IpoptNLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + IpoptNLP(const SmartPtr<NLPScalingObject> nlp_scaling) + : + nlp_scaling_(nlp_scaling) + {} + + /** Default destructor */ + virtual ~IpoptNLP() + {} + //@} + + /** Initialization method. Set the internal options and + * initialize internal data structures. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + bool ret = true; + if (IsValid(nlp_scaling_)) { + ret = nlp_scaling_->Initialize(jnlst, options, prefix); + } + return ret; + } + + /**@name Possible Exceptions */ + //@{ + /** thrown if there is any error evaluating values from the nlp */ + DECLARE_STD_EXCEPTION(Eval_Error); + //@} + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr<Vector>& x, + bool init_x, + SmartPtr<Vector>& y_c, + bool init_y_c, + SmartPtr<Vector>& y_d, + bool init_y_d, + SmartPtr<Vector>& z_L, + bool init_z_L, + SmartPtr<Vector>& z_U, + bool init_z_U, + SmartPtr<Vector>& v_L, + SmartPtr<Vector>& v_U + ) = 0; + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate)=0; + + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x) = 0; + + /** Gradient of the objective */ + virtual SmartPtr<const Vector> grad_f(const Vector& x) = 0; + + /** Equality constraint residual */ + virtual SmartPtr<const Vector> c(const Vector& x) = 0; + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr<const Matrix> jac_c(const Vector& x) = 0; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr<const Vector> d(const Vector& x) = 0; + + /** Jacobian Matrix for inequality constraints */ + virtual SmartPtr<const Matrix> jac_d(const Vector& x) = 0; + + /** Hessian of the Lagrangian */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ) = 0; + + /** Lower bounds on x */ + virtual SmartPtr<const Vector> x_L() const = 0; + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr<const Matrix> Px_L() const = 0; + + /** Upper bounds on x */ + virtual SmartPtr<const Vector> x_U() const = 0; + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr<const Matrix> Px_U() const = 0; + + /** Lower bounds on d */ + virtual SmartPtr<const Vector> d_L() const = 0; + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr<const Matrix> Pd_L() const = 0; + + /** Upper bounds on d */ + virtual SmartPtr<const Vector> d_U() const = 0; + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr<const Matrix> Pd_U() const = 0; + + /** x_space */ + virtual SmartPtr<const VectorSpace> x_space() const = 0; + + /** Accessor method to obtain the MatrixSpace for the Hessian + * matrix (or it's approximation) */ + virtual SmartPtr<const SymMatrixSpace> HessianMatrixSpace() const = 0; + //@} + + /** Accessor method for vector/matrix spaces pointers. */ + virtual void GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space) = 0; + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U)=0; + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const = 0; + virtual Index grad_f_evals() const = 0; + virtual Index c_evals() const = 0; + virtual Index jac_c_evals() const = 0; + virtual Index d_evals() const = 0; + virtual Index jac_d_evals() const = 0; + virtual Index h_evals() const = 0; + //@} + + /** @name Special method for dealing with the fact that the + * restoration phase objective function depends on the barrier + * parameter */ + //@{ + /** Method for telling the IpoptCalculatedQuantities class whether + * the objective function depends on the barrier function. This + * is only used for the restoration phase NLP + * formulation. Probably only RestoIpoptNLP should overwrite + * this. */ + virtual bool objective_depends_on_mu() const + { + return false; + } + + /** Replacement for the default objective function method which + * knows about the barrier parameter */ + virtual Number f(const Vector& x, Number mu) = 0; + + /** Replacement for the default objective gradient method which + * knows about the barrier parameter */ + virtual SmartPtr<const Vector> grad_f(const Vector& x, Number mu) = 0; + + /** Replacement for the default Lagrangian Hessian method which + * knows about the barrier parameter */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu) = 0; + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr<const SymMatrix> uninitialized_h() = 0; + //@} + + /**@name solution routines */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq)=0; + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr<const IpoptData> ip_data, + SmartPtr<IpoptCalculatedQuantities> ip_cq)=0; + //@} + + /** Returns the scaling strategy object */ + SmartPtr<NLPScalingObject> NLP_scaling() const + { + DBG_ASSERT(IsValid(nlp_scaling_)); + return nlp_scaling_; + } + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + IpoptNLP(const IpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptNLP&); + //@} + + SmartPtr<NLPScalingObject> nlp_scaling_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIterateInitializer.hpp b/thirdparty/linux/include/coin/coin/IpIterateInitializer.hpp new file mode 100644 index 0000000..d179651 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIterateInitializer.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterateInitializer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-24 + +#ifndef __IPITERATEINITIALIZER_HPP__ +#define __IPITERATEINITIALIZER_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for all methods for initializing the iterates. + */ + class IterateInitializer: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterateInitializer() + {} + + /** Default destructor */ + virtual ~IterateInitializer() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Compute the initial iterates and set the into the curr field + * of the ip_data object. */ + virtual bool SetInitialIterates() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterateInitializer(const IterateInitializer&); + + /** Overloaded Equals Operator */ + void operator=(const IterateInitializer&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIteratesVector.hpp b/thirdparty/linux/include/coin/coin/IpIteratesVector.hpp new file mode 100644 index 0000000..2ed7580 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIteratesVector.hpp @@ -0,0 +1,689 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIteratesVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-06-06 + +#ifndef __IPITERATESVECTOR_HPP__ +#define __IPITERATESVECTOR_HPP__ + +#include "IpCompoundVector.hpp" + +namespace Ipopt +{ + /* forward declarations */ + class IteratesVectorSpace; + + /** Specialized CompoundVector class specifically for the algorithm + * iterates. This class inherits from CompoundVector and is a + * specialized class for handling the iterates of the Ipopt + * Algorithm, that is, x, s, y_c, y_d, z_L, z_U, v_L, and v_U. It + * inherits from CompoundVector so it can behave like a CV in most + * calculations, but it has fixed dimensions and cannot be + * customized + */ + class IteratesVector : public CompoundVector + { + public: + /** Constructors / Destructors */ + //@{ + IteratesVector(const IteratesVectorSpace* owner_space, bool create_new); + + virtual ~IteratesVector(); + //@} + + /** Make New methods */ + //@{ + /** Use this method to create a new iterates vector. The MakeNew + * method on the Vector class also works, but it does not give + * the create_new option. + */ + SmartPtr<IteratesVector> MakeNewIteratesVector(bool create_new = true) const; + + /** Use this method to create a new iterates vector with a copy of + * all the data. + */ + SmartPtr<IteratesVector> MakeNewIteratesVectorCopy() const + { + SmartPtr<IteratesVector> ret = MakeNewIteratesVector(true); + ret->Copy(*this); + return ret; + } + + /** Use this method to create a new iterates vector + * container. This creates a new NonConst container, but the + * elements inside the iterates vector may be const. Therefore, + * the container can be modified to point to new entries, but the + * existing entries may or may not be modifiable. + */ + SmartPtr<IteratesVector> MakeNewContainer() const; + //@} + + /** Iterates Set/Get Methods */ + //@{ + /** Get the x iterate (const) */ + SmartPtr<const Vector> x() const + { + return GetIterateFromComp(0); + } + + /** Get the x iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_x_NonConst method was + * used. */ + SmartPtr<Vector> x_NonConst() + { + return GetNonConstIterateFromComp(0); + } + + /** Create a new vector in the x entry */ + inline + SmartPtr<Vector> create_new_x(); + + /** Create a new vector in the x entry and copy the current values + * into it. */ + SmartPtr<Vector> create_new_x_copy() + { + SmartPtr<const Vector> curr_x = GetComp(0); + Set_x_NonConst(*curr_x->MakeNew()); + x_NonConst()->Copy(*curr_x); + return x_NonConst(); + } + + /** Set the x iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_x(const Vector& vec) + { + SetComp(0, vec); + } + + /** Set the x iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_x_NonConst(Vector& vec) + { + SetCompNonConst(0, vec); + } + + /** Get the s iterate (const) */ + SmartPtr<const Vector> s() const + { + return GetIterateFromComp(1); + } + + /** Get the s iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_s_NonConst method was + * used. */ + SmartPtr<Vector> s_NonConst() + { + return GetNonConstIterateFromComp(1); + } + + /** Create a new vector in the s entry */ + inline + SmartPtr<Vector> create_new_s(); + + /** Create a new vector in the s entry and copy the current values + * into it. */ + SmartPtr<Vector> create_new_s_copy() + { + SmartPtr<const Vector> curr_s = GetComp(1); + Set_s_NonConst(*curr_s->MakeNew()); + s_NonConst()->Copy(*curr_s); + return s_NonConst(); + } + + /** Set the s iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_s(const Vector& vec) + { + SetComp(1, vec); + } + + /** Set the s iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_s_NonConst(Vector& vec) + { + SetCompNonConst(1, vec); + } + + /** Get the y_c iterate (const) */ + SmartPtr<const Vector> y_c() const + { + return GetIterateFromComp(2); + } + + /** Get the y_c iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_c_NonConst + * method was used. */ + SmartPtr<Vector> y_c_NonConst() + { + return GetNonConstIterateFromComp(2); + } + + /** Create a new vector in the y_c entry */ + inline + SmartPtr<Vector> create_new_y_c(); + + /** Create a new vector in the y_c entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_y_c_copy() + { + SmartPtr<const Vector> curr_y_c = GetComp(2); + Set_y_c_NonConst(*curr_y_c->MakeNew()); + y_c_NonConst()->Copy(*curr_y_c); + return y_c_NonConst(); + } + + /** Set the y_c iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_c(const Vector& vec) + { + SetComp(2, vec); + } + + /** Set the y_c iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_c_NonConst(Vector& vec) + { + SetCompNonConst(2, vec); + } + + /** Get the y_d iterate (const) */ + SmartPtr<const Vector> y_d() const + { + return GetIterateFromComp(3); + } + + /** Get the y_d iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_d_NonConst + * method was used. */ + SmartPtr<Vector> y_d_NonConst() + { + return GetNonConstIterateFromComp(3); + } + + /** Create a new vector in the y_d entry */ + inline + SmartPtr<Vector> create_new_y_d(); + + /** Create a new vector in the y_d entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_y_d_copy() + { + SmartPtr<const Vector> curr_y_d = GetComp(3); + Set_y_d_NonConst(*curr_y_d->MakeNew()); + y_d_NonConst()->Copy(*curr_y_d); + return y_d_NonConst(); + } + + /** Set the y_d iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_d(const Vector& vec) + { + SetComp(3, vec); + } + + /** Set the y_d iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_d_NonConst(Vector& vec) + { + SetCompNonConst(3, vec); + } + + /** Get the z_L iterate (const) */ + SmartPtr<const Vector> z_L() const + { + return GetIterateFromComp(4); + } + + /** Get the z_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_L_NonConst + * method was used. */ + SmartPtr<Vector> z_L_NonConst() + { + return GetNonConstIterateFromComp(4); + } + + /** Create a new vector in the z_L entry */ + inline + SmartPtr<Vector> create_new_z_L(); + + /** Create a new vector in the z_L entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_z_L_copy() + { + SmartPtr<const Vector> curr_z_L = GetComp(4); + Set_z_L_NonConst(*curr_z_L->MakeNew()); + z_L_NonConst()->Copy(*curr_z_L); + return z_L_NonConst(); + } + + /** Set the z_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_L(const Vector& vec) + { + SetComp(4, vec); + } + + /** Set the z_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_L_NonConst(Vector& vec) + { + SetCompNonConst(4, vec); + } + + /** Get the z_U iterate (const) */ + SmartPtr<const Vector> z_U() const + { + return GetIterateFromComp(5); + } + + /** Get the z_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_U_NonConst + * method was used. */ + SmartPtr<Vector> z_U_NonConst() + { + return GetNonConstIterateFromComp(5); + } + + /** Create a new vector in the z_U entry */ + inline + SmartPtr<Vector> create_new_z_U(); + + /** Create a new vector in the z_U entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_z_U_copy() + { + SmartPtr<const Vector> curr_z_U = GetComp(5); + Set_z_U_NonConst(*curr_z_U->MakeNew()); + z_U_NonConst()->Copy(*curr_z_U); + return z_U_NonConst(); + } + + /** Set the z_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_U(const Vector& vec) + { + SetComp(5, vec); + } + + /** Set the z_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_U_NonConst(Vector& vec) + { + SetCompNonConst(5, vec); + } + + /** Get the v_L iterate (const) */ + SmartPtr<const Vector> v_L() const + { + return GetIterateFromComp(6); + } + + /** Get the v_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_L_NonConst + * method was used. */ + SmartPtr<Vector> v_L_NonConst() + { + return GetNonConstIterateFromComp(6); + } + + /** Create a new vector in the v_L entry */ + inline + SmartPtr<Vector> create_new_v_L(); + + /** Create a new vector in the v_L entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_v_L_copy() + { + SmartPtr<const Vector> curr_v_L = GetComp(6); + Set_v_L_NonConst(*curr_v_L->MakeNew()); + v_L_NonConst()->Copy(*curr_v_L); + return v_L_NonConst(); + } + + /** Set the v_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_L(const Vector& vec) + { + SetComp(6, vec); + } + + /** Set the v_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_L_NonConst(Vector& vec) + { + SetCompNonConst(6, vec); + } + + /** Get the v_U iterate (const) */ + SmartPtr<const Vector> v_U() const + { + return GetIterateFromComp(7); + } + + /** Get the v_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_U_NonConst + * method was used. */ + SmartPtr<Vector> v_U_NonConst() + { + return GetNonConstIterateFromComp(7); + } + + /** Create a new vector in the v_U entry */ + inline + SmartPtr<Vector> create_new_v_U(); + + /** Create a new vector in the v_U entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_v_U_copy() + { + SmartPtr<const Vector> curr_v_U = GetComp(7); + Set_v_U_NonConst(*curr_v_U->MakeNew()); + v_U_NonConst()->Copy(*curr_v_U); + return v_U_NonConst(); + } + + /** Set the v_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_U(const Vector& vec) + { + SetComp(7, vec); + } + + /** Set the v_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_U_NonConst(Vector& vec) + { + SetCompNonConst(7, vec); + } + + /** Set the primal variables all in one shot. Sets the pointers, + * does NOT copy data */ + void Set_primal(const Vector& x, const Vector& s) + { + SetComp(0, x); + SetComp(1, s); + } + void Set_primal_NonConst(Vector& x, Vector& s) + { + SetCompNonConst(0, x); + SetCompNonConst(1, s); + } + + /** Set the eq multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_eq_mult(const Vector& y_c, const Vector& y_d) + { + SetComp(2, y_c); + SetComp(3, y_d); + } + void Set_eq_mult_NonConst(Vector& y_c, Vector& y_d) + { + SetCompNonConst(2, y_c); + SetCompNonConst(3, y_d); + } + + /** Set the bound multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_bound_mult(const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U) + { + SetComp(4, z_L); + SetComp(5, z_U); + SetComp(6, v_L); + SetComp(7, v_U); + } + void Set_bound_mult_NonConst(Vector& z_L, Vector& z_U, Vector& v_L, Vector& v_U) + { + SetCompNonConst(4, z_L); + SetCompNonConst(5, z_U); + SetCompNonConst(6, v_L); + SetCompNonConst(7, v_U); + } + + /** Get a sum of the tags of the contained items. There is no + * guarantee that this is unique, but there is a high chance it + * is unique and it can be used for debug checks relatively + * reliably. + */ + TaggedObject::Tag GetTagSum() const + { + TaggedObject::Tag tag = 0; + + if (IsValid(x())) { + tag += x()->GetTag(); + } + if (IsValid(s())) { + tag += s()->GetTag(); + } + if (IsValid(y_c())) { + tag += y_c()->GetTag(); + } + if (IsValid(y_d())) { + tag += y_d()->GetTag(); + } + if (IsValid(z_L())) { + tag += z_L()->GetTag(); + } + if (IsValid(z_U())) { + tag += z_U()->GetTag(); + } + if (IsValid(v_L())) { + tag += v_L()->GetTag(); + } + if (IsValid(v_U())) { + tag += v_U()->GetTag(); + } + + return tag; + } + //@} + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + IteratesVector(); + + /** Copy Constructor */ + IteratesVector(const IteratesVector&); + + /** Overloaded Equals Operator */ + void operator=(const IteratesVector&); + //@} + + const IteratesVectorSpace* owner_space_; + + /** private method to return the const element from the compound + * vector. This method will return NULL if none is currently + * set. + */ + SmartPtr<const Vector> GetIterateFromComp(Index i) const + { + if (IsCompNull(i)) { + return NULL; + } + return GetComp(i); + } + + /** private method to return the non-const element from the + * compound vector. This method will return NULL if none is + * currently set. + */ + SmartPtr<Vector> GetNonConstIterateFromComp(Index i) + { + if (IsCompNull(i)) { + return NULL; + } + return GetCompNonConst(i); + } + + }; + + /** Vector Space for the IteratesVector class. This is a + * specialized vector space for the IteratesVector class. + */ + class IteratesVectorSpace : public CompoundVectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor that takes the spaces for each of the iterates. + * Warning! None of these can be NULL ! + */ + IteratesVectorSpace(const VectorSpace& x_space, const VectorSpace& s_space, + const VectorSpace& y_c_space, const VectorSpace& y_d_space, + const VectorSpace& z_L_space, const VectorSpace& z_U_space, + const VectorSpace& v_L_space, const VectorSpace& v_U_space + ); + + virtual ~IteratesVectorSpace(); + //@} + + /** Method for creating vectors . */ + //@{ + /** Use this to create a new IteratesVector. You can pass-in + * create_new = false if you only want a container and do not + * want vectors allocated. + */ + virtual IteratesVector* MakeNewIteratesVector(bool create_new = true) const + { + return new IteratesVector(this, create_new); + } + + /** Use this method to create a new const IteratesVector. You must pass in + * valid pointers for all of the entries. + */ + const SmartPtr<const IteratesVector> MakeNewIteratesVector(const Vector& x, const Vector& s, + const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U) + { + SmartPtr<IteratesVector> newvec = MakeNewIteratesVector(false); + newvec->Set_x(x); + newvec->Set_s(s); + newvec->Set_y_c(y_c); + newvec->Set_y_d(y_d); + newvec->Set_z_L(z_L); + newvec->Set_z_U(z_U); + newvec->Set_v_L(v_L); + newvec->Set_v_U(v_U); + return ConstPtr(newvec); + } + + + /** This method overloads + * ComooundVectorSpace::MakeNewCompoundVector to make sure that + * we get a vector of the correct type + */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return MakeNewIteratesVector(create_new); + } + + /** This method creates a new vector (and allocates space in all + * the contained vectors. This is really only used for code that + * does not know what type of vector it is dealing with - for + * example, this method is called from Vector::MakeNew() + */ + virtual Vector* MakeNew() const + { + return MakeNewIteratesVector(); + } + //@} + + /** This method hides the CompoundVectorSpace::SetCompSpace method + * since the components of the Iterates are fixed at + * construction. + */ + virtual void SetCompSpace(Index icomp, const VectorSpace& vec_space) + { + DBG_ASSERT(false && "This is an IteratesVectorSpace - a special compound vector for Ipopt iterates. The contained spaces should not be modified."); + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + IteratesVectorSpace(); + + /** Copy Constructor */ + IteratesVectorSpace(const IteratesVectorSpace&); + + /** Overloaded Equals Operator */ + IteratesVectorSpace& operator=(const IteratesVectorSpace&); + //@} + + /** Contained Spaces */ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> s_space_; + SmartPtr<const VectorSpace> y_c_space_; + SmartPtr<const VectorSpace> y_d_space_; + SmartPtr<const VectorSpace> z_L_space_; + SmartPtr<const VectorSpace> z_U_space_; + SmartPtr<const VectorSpace> v_L_space_; + SmartPtr<const VectorSpace> v_U_space_; + }; + + + inline + SmartPtr<Vector> IteratesVector::create_new_x() + { + Set_x_NonConst(*owner_space_->GetCompSpace(0)->MakeNew()); + return x_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_s() + { + Set_s_NonConst(*owner_space_->GetCompSpace(1)->MakeNew()); + return s_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_y_c() + { + Set_y_c_NonConst(*owner_space_->GetCompSpace(2)->MakeNew()); + return y_c_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_y_d() + { + Set_y_d_NonConst(*owner_space_->GetCompSpace(3)->MakeNew()); + return y_d_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_z_L() + { + Set_z_L_NonConst(*owner_space_->GetCompSpace(4)->MakeNew()); + return z_L_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_z_U() + { + Set_z_U_NonConst(*owner_space_->GetCompSpace(5)->MakeNew()); + return z_U_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_v_L() + { + Set_v_L_NonConst(*owner_space_->GetCompSpace(6)->MakeNew()); + return v_L_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_v_U() + { + Set_v_U_NonConst(*owner_space_->GetCompSpace(7)->MakeNew()); + return v_U_NonConst(); + } +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpIterationOutput.hpp b/thirdparty/linux/include/coin/coin/IpIterationOutput.hpp new file mode 100644 index 0000000..95fd650 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpIterationOutput.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterationOutput.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Andreas Waechter, Carl Laird IBM 2004-09-27 + +#ifndef __IPITERATIONOUTPUT_HPP__ +#define __IPITERATIONOUTPUT_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for objects that do the output summary per iteration. + */ + class IterationOutput: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterationOutput() + {} + + /** Default destructor */ + virtual ~IterationOutput() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method to do all the summary output per iteration. This + * include the one-line summary output as well as writing the + * details about the iterates if desired */ + virtual void WriteOutput() = 0; + + protected: + /** enumeration for different inf_pr output options */ + enum InfPrOutput + { + INTERNAL=0, + ORIGINAL + }; + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterationOutput(const IterationOutput&); + + /** Overloaded Equals Operator */ + void operator=(const IterationOutput&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpJournalist.hpp b/thirdparty/linux/include/coin/coin/IpJournalist.hpp new file mode 100644 index 0000000..266130a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpJournalist.hpp @@ -0,0 +1,497 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpJournalist.hpp 2204 2013-04-13 13:49:26Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPJOURNALIST_HPP__ +#define __IPJOURNALIST_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +#ifdef HAVE_CSTDARG +# include <cstdarg> +#else +# ifdef HAVE_STDARG_H +# include <stdarg.h> +# else +# include <cstdarg> // if this header is included by someone who does not define HAVE_CSTDARG or HAVE_STDARG, let's hope that cstdarg is available +# endif +#endif + +#ifdef HAVE_CSTDIO +# include <cstdio> +#else +# ifdef HAVE_STDIO_H +# include <stdio.h> +# else +# include <cstdio> // if this header is included by someone who does not define HAVE_CSTDIO or HAVE_STDIO, let's hope that cstdio is available +# endif +#endif + +#include <string> +#include <vector> +#include <ostream> + +namespace Ipopt +{ + + // forward declarations + class Journal; + class FileJournal; + + /**@name Journalist Enumerations. */ + //@{ + /** Print Level Enum. */ + enum EJournalLevel { + J_INSUPPRESSIBLE=-1, + J_NONE=0, + J_ERROR, + J_STRONGWARNING, + J_SUMMARY, + J_WARNING, + J_ITERSUMMARY, + J_DETAILED, + J_MOREDETAILED, + J_VECTOR, + J_MOREVECTOR, + J_MATRIX, + J_MOREMATRIX, + J_ALL, + J_LAST_LEVEL + }; + + /** Category Selection Enum. */ + enum EJournalCategory { + J_DBG=0, + J_STATISTICS, + J_MAIN, + J_INITIALIZATION, + J_BARRIER_UPDATE, + J_SOLVE_PD_SYSTEM, + J_FRAC_TO_BOUND, + J_LINEAR_ALGEBRA, + J_LINE_SEARCH, + J_HESSIAN_APPROXIMATION, + J_SOLUTION, + J_DOCUMENTATION, + J_NLP, + J_TIMING_STATISTICS, + J_USER_APPLICATION /** This can be used by the user's application*/ , + J_USER1 /** This can be used by the user's application*/ , + J_USER2 /** This can be used by the user's application*/ , + J_USER3 /** This can be used by the user's application*/ , + J_USER4 /** This can be used by the user's application*/ , + J_USER5 /** This can be used by the user's application*/ , + J_USER6 /** This can be used by the user's application*/ , + J_USER7 /** This can be used by the user's application*/ , + J_USER8 /** This can be used by the user's application*/ , + J_USER9 /** This can be used by the user's application*/ , + J_USER10 /** This can be used by the user's application*/ , + J_USER11 /** This can be used by the user's application*/ , + J_USER12 /** This can be used by the user's application*/ , + J_USER13 /** This can be used by the user's application*/ , + J_USER14 /** This can be used by the user's application*/ , + J_USER15 /** This can be used by the user's application*/ , + J_USER16 /** This can be used by the user's application*/ , + J_USER17 /** This can be used by the user's application*/ , + J_LAST_CATEGORY + }; + //@} + + /** Class responsible for all message output. + * This class is responsible for all messaging and output. + * The "printing" code or "author" should send ALL messages to the + * Journalist, indicating an appropriate category and print level. + * The journalist then decides, based on reader specified + * acceptance criteria, which message is actually printed in which + * journals. + * This allows the printing code to send everything, while the + * "reader" can decide what they really want to see. + * + * Authors: + * Authors use the + * Journals: You can add as many Journals as you like to the + * Journalist with the AddJournal or the AddFileJournal methods. + * Each one represents a different printing location (or file). + * Then, you can call the "print" methods of the Journalist to output + * information to each of the journals. + * + * Acceptance Criteria: Each print message should be flagged + * appropriately with an EJournalCategory and EJournalLevel. + * + * The AddFileJournal + * method returns a pointer to the newly created Journal object + * (if successful) so you can set Acceptance criteria for that + * particular location. + * + */ + class Journalist : public ReferencedObject + { + public: + /**@name Constructor / Desructor. */ + //@{ + /** Constructor. */ + Journalist(); + + /** Destructor... */ + virtual ~Journalist(); + //@} + + /**@name Author Methods. + * These methods are used by authoring code, or code that wants + * to report some information. + */ + //@{ + /** Method to print a formatted string */ + virtual void Printf(EJournalLevel level, EJournalCategory category, + const char* format, ...) const; + + /** Method to print a long string including indentation. The + * string is printed starting at the current position. If the + * position (counting started at the current position) exceeds + * max_length, a new line is inserted, and indent_spaces many + * spaces are printed before the string is continued. This is + * for example used during the printing of the option + * documentation. */ + virtual void PrintStringOverLines(EJournalLevel level, EJournalCategory category, + Index indent_spaces, Index max_length, + const std::string& line) const; + + /** Method to print a formatted string with indentation */ + virtual void PrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* format, ...) const; + + /** Method to print a formatted string + * using the va_list argument. */ + virtual void VPrintf(EJournalLevel level, + EJournalCategory category, + const char* pformat, + va_list ap) const; + + /** Method to print a formatted string with indentation, + * using the va_list argument. */ + virtual void VPrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* pformat, + va_list ap) const; + + /** Method that returns true if there is a Journal that would + * write output for the given JournalLevel and JournalCategory. + * This is useful if expensive computation would be required for + * a particular output. The author code can check with this + * method if the computations are indeed required. + */ + virtual bool ProduceOutput(EJournalLevel level, + EJournalCategory category) const; + + + /** Method that flushes the current buffer for all Journalists. + Calling this method after one optimization run helps to avoid + cluttering output with that produced by other parts of the + program (e.g. written in Fortran) */ + virtual void FlushBuffer() const; + //@} + + /**@name Reader Methods. + * These methods are used by the reader. The reader will setup the + * journalist with each output file and the acceptance + * criteria for that file. + * + * Use these methods to setup the journals (files or other output). + * These are the internal objects that keep track of the print levels + * for each category. Then use the internal Journal objects to + * set specific print levels for each category (or keep defaults). + * + */ + //@{ + /** Add a new journal. The location_name is a string identifier, + * which can be used to obtain the pointer to the new Journal at + * a later point using the GetJournal method. + * The default_level is + * used to initialize the * printing level for all categories. + */ + virtual bool AddJournal(const SmartPtr<Journal> jrnl); + + /** Add a new FileJournal. fname is the name + * of the * file to which this Journal corresponds. Use + * fname="stdout" * for stdout, and use fname="stderr" for + * stderr. This method * returns the Journal pointer so you can + * set specific acceptance criteria. It returns NULL if there + * was a problem creating a new Journal. + */ + virtual SmartPtr<Journal> AddFileJournal( + const std::string& location_name, /**< journal identifier */ + const std::string& fname, /**< file name */ + EJournalLevel default_level = J_WARNING /**< default journal level */ + ); + + /** Get an existing journal. You can use this method to change + * the acceptance criteria at runtime. + */ + virtual SmartPtr<Journal> GetJournal(const std::string& location_name); + + /** Delete all journals curently known by the journalist. */ + virtual void DeleteAllJournals(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Journalist(const Journalist&); + + /** Overloaded Equals Operator */ + void operator=(const Journalist&); + //@} + + //** Private Data Members. */ + //@{ + std::vector< SmartPtr<Journal> > journals_; + //@} + }; + + /** Journal class (part of the Journalist implementation.). This + * class is the base class for all Journals. It controls the + * acceptance criteria for print statements etc. Derived classes + * like the FileJournal - output those messages to specific locations + */ + class Journal : public ReferencedObject + { + public: + /** Constructor. */ + Journal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~Journal(); + + /** Get the name of the Journal */ + virtual std::string Name(); + + /** Set the print level for a particular category. */ + virtual void SetPrintLevel( + EJournalCategory category, EJournalLevel level + ); + + /** Set the print level for all category. */ + virtual void SetAllPrintLevels( + EJournalLevel level + ); + + /**@name Journal Output Methods. These methods are called by the + * Journalist who first checks if the output print level and category + * are acceptable. + * Calling the Print methods explicitly (instead of through the + * Journalist will output the message regardless of print level + * and category. You should use the Journalist to print & flush instead + */ + //@{ + /** Ask if a particular print level/category is accepted by the + * journal. + */ + virtual bool IsAccepted( + EJournalCategory category, EJournalLevel level + ) const; + + /** Print to the designated output location */ + virtual void Print(EJournalCategory category, EJournalLevel level, + const char* str) + { + PrintImpl(category, level, str); + } + + /** Printf to the designated output location */ + virtual void Printf(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap) + { + PrintfImpl(category, level, pformat, ap); + } + + /** Flush output buffer.*/ + virtual void FlushBuffer() + { + FlushBufferImpl(); + } + //@} + + protected: + /**@name Implementation version of Print methods. Derived classes + * should overload the Impl methods. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str)=0; + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap)=0; + + /** Flush output buffer.*/ + virtual void FlushBufferImpl()=0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + Journal(); + + /** Copy Constructor */ + Journal(const Journal&); + + /** Overloaded Equals Operator */ + void operator=(const Journal&); + //@} + + /** Name of the output location */ + std::string name_; + + /** vector of integers indicating the level for each category */ + Index print_levels_[J_LAST_CATEGORY]; + }; + + + /** FileJournal class. This is a particular Journal implementation that + * writes to a file for output. It can write to (stdout, stderr, or disk) + * by using "stdout" and "stderr" as filenames. + */ + class FileJournal : public Journal + { + public: + /** Constructor. */ + FileJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~FileJournal(); + + /** Open a new file for the output location. + * Special Names: stdout means stdout, + * : stderr means stderr. + * + * Return code is false only if the file with the given name + * could not be opened. + */ + virtual bool Open(const char* fname); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + FileJournal(); + + /** Copy Constructor */ + FileJournal(const FileJournal&); + + /** Overloaded Equals Operator */ + void operator=(const FileJournal&); + //@} + + /** FILE pointer for the output destination */ + FILE* file_; + }; + + /** StreamJournal class. This is a particular Journal implementation that + * writes to a stream for output. + */ + class StreamJournal : public Journal + { + public: + /** Constructor. */ + StreamJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~StreamJournal() + {} + + /** Setting the output stream pointer */ + void SetOutputStream(std::ostream* os); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + StreamJournal(); + + /** Copy Constructor */ + StreamJournal(const StreamJournal&); + + /** Overloaded Equals Operator */ + void operator=(const StreamJournal&); + //@} + + /** pointer to output stream for the output destination */ + std::ostream* os_; + + /** buffer for sprintf. Being generous in size here... */ + char buffer_[32768]; + }; +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpLapack.hpp b/thirdparty/linux/include/coin/coin/IpLapack.hpp new file mode 100644 index 0000000..ef8883c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpLapack.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLapack.hpp 2449 2013-12-16 00:25:42Z ghackebeil $ +// +// Authors: Andreas Waechter IBM 2005-12-25 + +#ifndef __IPLAPACK_HPP__ +#define __IPLAPACK_HPP__ + +#include "IpUtils.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(LAPACK_NOT_INCLUDED); + + /** Wrapper for LAPACK subroutine DPOTRS. Solving a linear system + * given a Cholesky factorization. We assume that the Cholesky + * factor is lower traiangular. */ + void IpLapackDpotrs(Index ndim, Index nrhs, const Number *a, Index lda, + Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPOTRF. Compute Cholesky + * factorization (lower triangular factor). info is the return + * value from the LAPACK routine. */ + void IpLapackDpotrf(Index ndim, Number *a, Index lda, Index& info); + + /** Wrapper for LAPACK subroutine DSYEV. Compute the Eigenvalue + * decomposition for a given matrix. If compute_eigenvectors is + * true, a will contain the eigenvectors in its columns on + * return. */ + void IpLapackDsyev(bool compute_eigenvectors, Index ndim, Number *a, + Index lda, Number *w, Index& info); + + /** Wrapper for LAPACK subroutine DGETRF. Compute LU factorization. + * info is the return value from the LAPACK routine. */ + void IpLapackDgetrf(Index ndim, Number *a, Index* pivot, Index lda, + Index& info); + + /** Wrapper for LAPACK subroutine DGETRS. Solving a linear system + * given a LU factorization. */ + void IpLapackDgetrs(Index ndim, Index nrhs, const Number *a, Index lda, + Index* ipiv, Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPPSV. Solves a symmetric positive + * definite linear system in packed storage format (upper triangular). + * info is the return value from the LAPACK routine. */ + void IpLapackDppsv(Index ndim, Index nrhs, const Number *a, + Number *b, Index ldb, Index& info); + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpLineSearch.hpp b/thirdparty/linux/include/coin/coin/IpLineSearch.hpp new file mode 100644 index 0000000..70c11f1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpLineSearch.hpp @@ -0,0 +1,96 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLineSearch.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPLINESEARCH_HPP__ +#define __IPLINESEARCH_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for line search objects. + */ + class LineSearch : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + LineSearch() + {} + + /** Default destructor */ + virtual ~LineSearch() + {} + //@} + + /** Perform the line search. As search direction the delta + * in the data object is used + */ + virtual void FindAcceptableTrialPoint() = 0; + + /** Reset the line search. + * This function should be called if all previous information + * should be discarded when the line search is performed the + * next time. For example, this method should be called after + * the barrier parameter is changed. + */ + virtual void Reset() = 0; + + /** Set flag indicating whether a very rigorous line search should + * be performed. If this flag is set to true, the line search + * algorithm might decide to abort the line search and not to + * accept a new iterate. If the line search decided not to + * accept a new iterate, the return value of + * CheckSkippedLineSearch() is true at the next call. For + * example, in the non-monotone barrier parameter update + * procedure, the filter algorithm should not switch to the + * restoration phase in the free mode; instead, the algorithm + * should swtich to the fixed mode. + */ + virtual void SetRigorousLineSearch(bool rigorous) = 0; + + /** Check if the line search procedure didn't accept a new iterate + * during the last call of FindAcceptableTrialPoint(). + * + */ + virtual bool CheckSkippedLineSearch() = 0; + + /** This method should be called if the optimization process + * requires the line search object to switch to some fallback + * mechanism (like the restoration phase), when the regular + * optimization procedure cannot be continued (for example, + * because the search direction could not be computed). This + * will cause the line search object to immediately proceed with + * this mechanism when FindAcceptableTrialPoint() is call. This + * method returns false if no fallback mechanism is available. */ + virtual bool ActivateFallbackMechanism() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + LineSearch(const LineSearch&); + + /** Overloaded Equals Operator */ + void operator=(const LineSearch&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpMatrix.hpp b/thirdparty/linux/include/coin/coin/IpMatrix.hpp new file mode 100644 index 0000000..79018da --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpMatrix.hpp @@ -0,0 +1,345 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMatrix.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMATRIX_HPP__ +#define __IPMATRIX_HPP__ + +#include "IpVector.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class MatrixSpace; + + /** Matrix Base Class. This is the base class for all derived matrix + * types. All Matrices, such as Jacobian and Hessian matrices, as + * well as possibly the iteration matrices needed for the step + * computation, are of this type. + * + * Deriving from Matrix: Overload the protected XXX_Impl method. + */ + class Matrix : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding MatrixSpace. + */ + Matrix(const MatrixSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + valid_cache_tag_(0) + {} + + /** Destructor */ + virtual ~Matrix() + {} + //@} + + /**@name Operations of the Matrix on a Vector */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y. Do not overload. Overload MultVectorImpl instead. + */ + void MultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + MultVectorImpl(alpha, x, beta, y); + } + + /** Matrix(transpose) vector multiply. Computes y = alpha * + * Matrix^T * x + beta * y. Do not overload. Overload + * TransMultVectorImpl instead. + */ + void TransMultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + TransMultVectorImpl(alpha, x, beta, y); + } + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** X = X + alpha*(Matrix S^{-1} Z). Should be implemented + * efficiently for the ExansionMatrix + */ + void AddMSinvZ(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExansionMatrix + */ + void SinvBlrmZMTdBr(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + bool HasValidNumbers() const; + + /** @name Information about the size of the matrix */ + //@{ + /** Number of rows */ + inline + Index NRows() const; + + /** Number of columns */ + inline + Index NCols() const; + //@} + + /** @name Norms of the individual rows and columns */ + //@{ + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be initialized + * of init is false. */ + void ComputeRowAMax(Vector& rows_norms, bool init=true) const + { + DBG_ASSERT(NRows() == rows_norms.Dim()); + if (init) rows_norms.Set(0.); + ComputeRowAMaxImpl(rows_norms, init); + } + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms The vector is assumed to be initialized + * of init is false. */ + void ComputeColAMax(Vector& cols_norms, bool init=true) const + { + DBG_ASSERT(NCols() == cols_norms.Dim()); + if (init) cols_norms.Set(0.); + ComputeColAMaxImpl(cols_norms, init); + } + //@} + + /** Print detailed information about the matrix. Do not overload. + * Overload PrintImpl instead. + */ + //@{ + virtual void Print(SmartPtr<const Journalist> jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + virtual void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + /** Return the owner MatrixSpace*/ + inline + SmartPtr<const MatrixSpace> OwnerSpace() const; + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods. + */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y + */ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** Matrix(transpose) vector multiply. + * Computes y = alpha * Matrix^T * x + beta * y + */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** X = X + alpha*(Matrix S^{-1} Z). Prototype for this + * specialize method is provided, but for efficient + * implementation it should be overloaded for the expansion matrix. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExpansionMatrix. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation always returning true + * is provided, but if possible it should be implemented. */ + virtual bool HasValidNumbersImpl() const + { + return true; + } + + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const = 0; + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const = 0; + + /** Print detailed information about the matrix. */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + Matrix(); + + /** Copy constructor */ + Matrix(const Matrix&); + + /** Overloaded Equals Operator */ + Matrix& operator=(const Matrix&); + //@} + + const SmartPtr<const MatrixSpace> owner_space_; + + /**@name CachedResults data members */ + //@{ + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + //@} + }; + + + /** MatrixSpace base class, corresponding to the Matrix base class. + * For each Matrix implementation, a corresponding MatrixSpace has + * to be implemented. A MatrixSpace is able to create new Matrices + * of a specific type. The MatrixSpace should also store + * information that is common to all Matrices of that type. For + * example, the dimensions of a Matrix is stored in the MatrixSpace + * base class. + */ + class MatrixSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the number rows and columns of all matrices + * generated by this MatrixSpace. + */ + MatrixSpace(Index nRows, Index nCols) + : + nRows_(nRows), + nCols_(nCols) + {} + + /** Destructor */ + virtual ~MatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new Matrix of the + * corresponding type. + */ + virtual Matrix* MakeNew() const=0; + + /** Accessor function for the number of rows. */ + Index NRows() const + { + return nRows_; + } + /** Accessor function for the number of columns. */ + Index NCols() const + { + return nCols_; + } + + /** Method to test if a given matrix belongs to a particular + * matrix space. + */ + bool IsMatrixFromSpace(const Matrix& matrix) const + { + return (matrix.OwnerSpace() == this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + MatrixSpace(); + + /** Copy constructor */ + MatrixSpace(const MatrixSpace&); + + /** Overloaded Equals Operator */ + MatrixSpace& operator=(const MatrixSpace&); + //@} + + /** Number of rows for all matrices of this type. */ + const Index nRows_; + /** Number of columns for all matrices of this type. */ + const Index nCols_; + }; + + + /* Inline Methods */ + inline + Index Matrix::NRows() const + { + return owner_space_->NRows(); + } + + inline + Index Matrix::NCols() const + { + return owner_space_->NCols(); + } + + inline + SmartPtr<const MatrixSpace> Matrix::OwnerSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +// Macro definitions for debugging matrices +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +#else +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__mat).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __mat_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif // #if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpMuUpdate.hpp b/thirdparty/linux/include/coin/coin/IpMuUpdate.hpp new file mode 100644 index 0000000..b6c1d9c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpMuUpdate.hpp @@ -0,0 +1,69 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMuUpdate.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMUUPDATE_HPP__ +#define __IPMUUPDATE_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Abstract Base Class for classes that implement methods for computing + * the barrier and fraction-to-the-boundary rule parameter for the + * current iteration. + */ + class MuUpdate : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + MuUpdate() + {} + + /** Default destructor */ + virtual ~MuUpdate() + {} + //@} + + /** Initialize method - overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method for determining the barrier parameter for the next + * iteration. A LineSearch object is passed, so that this method + * can call the Reset method in the LineSearch object, for + * example when then barrier parameter is changed. This method is + * also responsible for setting the fraction-to-the-boundary + * parameter tau. This method returns false if the update could + * not be performed and the algorithm should revert to an + * emergency fallback mechanism. */ + virtual bool UpdateBarrierParameter() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + MuUpdate(const MuUpdate&); + + /** Overloaded Equals Operator */ + void operator=(const MuUpdate&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpNLP.hpp b/thirdparty/linux/include/coin/coin/IpNLP.hpp new file mode 100644 index 0000000..1063c01 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpNLP.hpp @@ -0,0 +1,243 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLP.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLP_HPP__ +#define __IPNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include "IpSmartPtr.hpp" +#include "IpMatrix.hpp" +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Brief Class Description. + * Detailed Class Description. + */ + class NLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + NLP() + {} + + /** Default destructor */ + virtual ~NLP() + {} + //@} + + /** Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED); + DECLARE_STD_EXCEPTION(INVALID_NLP); + //@} + + /** @name NLP Initialization (overload in + * derived classes).*/ + //@{ + /** Overload if you want the chance to process options or parameters that + * may be specific to the NLP */ + virtual bool ProcessOptions(const OptionsList& options, + const std::string& prefix) + { + return true; + } + + /** Method for creating the derived vector / matrix types. The + * Hess_lagrangian_space pointer can be NULL if a quasi-Newton + * options is chosen. */ + virtual bool GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space)=0; + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& Px_L, + Vector& x_L, + const Matrix& Px_U, + Vector& x_U, + const Matrix& Pd_L, + Vector& d_L, + const Matrix& Pd_U, + Vector& d_U)=0; + + /** Method for obtaining the starting point for all the + * iterates. ToDo it might not make sense to ask for initial + * values for v_L and v_U? */ + virtual bool GetStartingPoint( + SmartPtr<Vector> x, + bool need_x, + SmartPtr<Vector> y_c, + bool need_y_c, + SmartPtr<Vector> y_d, + bool need_y_d, + SmartPtr<Vector> z_L, + bool need_z_L, + SmartPtr<Vector> z_U, + bool need_z_U + )=0; + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. The default + * dummy implementation returns false. */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate) + { + return false; + } + //@} + + /** @name NLP evaluation routines (overload + * in derived classes. */ + //@{ + virtual bool Eval_f(const Vector& x, Number& f) = 0; + + virtual bool Eval_grad_f(const Vector& x, Vector& g_f) = 0; + + virtual bool Eval_c(const Vector& x, Vector& c) = 0; + + virtual bool Eval_jac_c(const Vector& x, Matrix& jac_c) = 0; + + virtual bool Eval_d(const Vector& x, Vector& d) = 0; + + virtual bool Eval_jac_d(const Vector& x, Matrix& jac_d) = 0; + + virtual bool Eval_h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + SymMatrix& h) = 0; + //@} + + /** @name NLP solution routines. Have default dummy + * implementations that can be overloaded. */ + //@{ + /** This method is called at the very end of the optimization. It + * provides the final iterate to the user, so that it can be + * stored as the solution. The status flag indicates the outcome + * of the optimization, where SolverReturn is defined in + * IpAlgTypes.hpp. */ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, + const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + {} + + /** This method is called once per iteration, after the iteration + * summary output has been printed. It provides the current + * information to the user to do with it anything she wants. It + * also allows the user to ask for a premature termination of the + * optimization by returning false, in which case Ipopt will + * terminate with a corresponding return status. The basic + * information provided in the argument list has the quantities + * values printed in the iteration summary line. If more + * information is required, a user can obtain it from the IpData + * and IpCalculatedQuantities objects. However, note that the + * provided quantities are all for the problem that Ipopt sees, + * i.e., the quantities might be scaled, fixed variables might be + * sorted out, etc. The status indicates things like whether the + * algorithm is in the restoration phase... In the restoration + * phase, the dual variables are probably not not changing. */ + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + { + return true; + } + //@} + + /** Routines to get the scaling parameters. These do not need to + * be overloaded unless the options are set for User scaling + */ + //@{ + virtual void GetScalingParameters( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + Number& obj_scaling, + SmartPtr<Vector>& x_scaling, + SmartPtr<Vector>& c_scaling, + SmartPtr<Vector>& d_scaling) const + { + THROW_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED, + "You have set options for user provided scaling, but have" + " not implemented GetScalingParameters in the NLP interface"); + } + //@} + + /** Method for obtaining the subspace in which the limited-memory + * Hessian approximation should be done. This is only called if + * the limited-memory Hessian approximation is chosen. Since the + * Hessian is zero in the space of all variables that appear in + * the problem functions only linearly, this allows the user to + * provide a VectorSpace for all nonlinear variables, and an + * ExpansionMatrix to lift from this VectorSpace to the + * VectorSpace of the primal variables x. If the returned values + * are NULL, it is assumed that the Hessian is to be approximated + * in the space of all x variables. The default instantiation of + * this method returns NULL, and a user only has to overwrite + * this method if the approximation is to be done only in a + * subspace. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr<VectorSpace>& approx_space, + SmartPtr<Matrix>& P_approx) + { + approx_space = NULL; + P_approx = NULL; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + NLP(const NLP&); + + /** Overloaded Equals Operator */ + void operator=(const NLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpNLPScaling.hpp b/thirdparty/linux/include/coin/coin/IpNLPScaling.hpp new file mode 100644 index 0000000..be5f13d --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpNLPScaling.hpp @@ -0,0 +1,451 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLPScaling.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLPSCALING_HPP__ +#define __IPNLPSCALING_HPP__ + +#include "IpOptionsList.hpp" +#include "IpRegOptions.hpp" + +namespace Ipopt +{ + // forward declarations + class Vector; + class VectorSpace; + class Matrix; + class MatrixSpace; + class SymMatrix; + class SymMatrixSpace; + class ScaledMatrixSpace; + class SymScaledMatrixSpace; + + /** This is the abstract base class for problem scaling. + * It is repsonsible for determining the scaling factors + * and mapping quantities in and out of scaled and unscaled + * versions + */ + class NLPScalingObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + NLPScalingObject(); + + /** Default destructor */ + virtual ~NLPScalingObject(); + //@} + + /** Method to initialize the options */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + jnlst_ = &jnlst; + return InitializeImpl(options, prefix); + } + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f)=0; + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_c_scaling(SmartPtr<const Matrix> matrix)=0; + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_d_scaling(SmartPtr<const Matrix> matrix)=0; + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const SymMatrix> + apply_hessian_scaling(SmartPtr<const SymMatrix> matrix)=0; + //@} + + /** Methods for scaling bounds - these wrap those above */ + //@{ + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr<Vector> apply_vector_scaling_x_LU_NonConst( + const Matrix& Px_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& x_space); + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr<const Vector> apply_vector_scaling_x_LU( + const Matrix& Px_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& x_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr<Vector> apply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr<const Vector> apply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr<Vector> unapply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr<const Vector> unapply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + //@} + + /** Methods for scaling the gradient of the objective - wraps the + * virtual methods above + */ + //@{ + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr<Vector> + apply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr<const Vector> + apply_grad_obj_scaling(const SmartPtr<const Vector>& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr<Vector> + unapply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr<const Vector> + unapply_grad_obj_scaling(const SmartPtr<const Vector>& v); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + /** Returns true if the primal x variables are scaled. */ + virtual bool have_x_scaling()=0; + /** Returns true if the equality constraints are scaled. */ + virtual bool have_c_scaling()=0; + /** Returns true if the inequality constraints are scaled. */ + virtual bool have_d_scaling()=0; + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + SmartPtr<const MatrixSpace>& new_jac_c_space, + SmartPtr<const MatrixSpace>& new_jac_d_space, + SmartPtr<const SymMatrixSpace>& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U)=0; + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** Accessor method for the journalist */ + const Journalist& Jnlst() const + { + return *jnlst_; + } + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NLPScalingObject(const NLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NLPScalingObject&); + //@} + + SmartPtr<const Journalist> jnlst_; + }; + + /** This is a base class for many standard scaling + * techniques. The overloaded classes only need to + * provide the scaling parameters + */ + class StandardScalingBase : public NLPScalingObject + { + public: + /**@name Constructors/Destructors */ + //@{ + StandardScalingBase(); + + /** Default destructor */ + virtual ~StandardScalingBase(); + //@} + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f); + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_x(const SmartPtr<const Vector>& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_x(const SmartPtr<const Vector>& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_c(const SmartPtr<const Vector>& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_c(const SmartPtr<const Vector>& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_d(const SmartPtr<const Vector>& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_d(const SmartPtr<const Vector>& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v); + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_c_scaling(SmartPtr<const Matrix> matrix); + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_d_scaling(SmartPtr<const Matrix> matrix); + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const SymMatrix> + apply_hessian_scaling(SmartPtr<const SymMatrix> matrix); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + virtual bool have_x_scaling(); + virtual bool have_c_scaling(); + virtual bool have_d_scaling(); + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + SmartPtr<const MatrixSpace>& new_jac_c_space, + SmartPtr<const MatrixSpace>& new_jac_d_space, + SmartPtr<const SymMatrixSpace>& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + protected: + /** Overloaded initialization method */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** This is the method that has to be overloaded by a particular + * scaling method that somehow computes the scaling vectors dx, + * dc, and dd. The pointers to those vectors can be NULL, in + * which case no scaling for that item will be done later. */ + virtual void DetermineScalingParametersImpl( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr<Vector>& dx, + SmartPtr<Vector>& dc, + SmartPtr<Vector>& dd)=0; + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + StandardScalingBase(const StandardScalingBase&); + + /** Overloaded Equals Operator */ + void operator=(const StandardScalingBase&); + //@} + + /** Scaling parameters - we only need to keep copies of + * the objective scaling and the x scaling - the others we can + * get from the scaled matrix spaces. + */ + //@{ + /** objective scaling parameter */ + Number df_; + /** x scaling */ + SmartPtr<Vector> dx_; + //@} + + /** Scaled Matrix Spaces */ + //@{ + /** Scaled jacobian of c space */ + SmartPtr<ScaledMatrixSpace> scaled_jac_c_space_; + /** Scaled jacobian of d space */ + SmartPtr<ScaledMatrixSpace> scaled_jac_d_space_; + /** Scaled hessian of lagrangian spacea */ + SmartPtr<SymScaledMatrixSpace> scaled_h_space_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** Additional scaling value for the objective function */ + Number obj_scaling_factor_; + //@} + }; + + /** Class implementing the scaling object that doesn't to any scaling */ + class NoNLPScalingObject : public StandardScalingBase + { + public: + /**@name Constructors/Destructors */ + //@{ + NoNLPScalingObject() + {} + + /** Default destructor */ + virtual ~NoNLPScalingObject() + {} + //@} + + + protected: + /** Overloaded from StandardScalingBase */ + virtual void DetermineScalingParametersImpl( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr<Vector>& dx, + SmartPtr<Vector>& dc, + SmartPtr<Vector>& dd); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NoNLPScalingObject(const NoNLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NoNLPScalingObject&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpObserver.hpp b/thirdparty/linux/include/coin/coin/IpObserver.hpp new file mode 100644 index 0000000..b16f599 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpObserver.hpp @@ -0,0 +1,366 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpObserver.hpp 2161 2013-01-01 20:39:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOBSERVER_HPP__ +#define __IPOBSERVER_HPP__ + +#include "IpUtils.hpp" +#include <vector> +#include <algorithm> + +//#define IP_DEBUG_OBSERVER +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_OBSERVER +#endif +#ifdef IP_DEBUG_OBSERVER +# include "IpDebug.hpp" +#endif + +namespace Ipopt +{ + /** Forward declarations */ + class Subject; + + /** Slight Variation of the Observer Design Pattern. + * This class implements the Observer class of the + * Observer Design Pattern. An Observer "Attach"es + * to a Subject, indicating that it would like to + * be notified of changes in the Subject. + * Any derived class wishing to recieve notifications + * from a Subject should inherit off of + * Observer and overload the protected method, + * RecieveNotification_(...). + */ + class Observer + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Observer() + {} + + /** Default destructor */ + inline + virtual ~Observer(); + //@} + + /** Enumeration specifying the type of notification */ + enum NotifyType + { + NT_All, + NT_BeingDestroyed, + NT_Changed + }; + + protected: + /** Derived classes should call this method + * to request an "Attach" to a Subject. Do + * not call "Attach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestAttach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should call this method + * to request a "Detach" to a Subject. Do + * not call "Detach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestDetach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should overload this method to + * recieve the requested notification from + * attached Subjects + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject)=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Observer(const Observer&); + + /** Overloaded Equals Operator */ + void operator=(const Observer&); + //@} + + /** A list of the subjects currently being + * observed. */ + std::vector<const Subject*> subjects_; + + /** Private Method for Recieving Notification + * should only be called by the friend class + * Subject. This method will, in turn, call + * the overloaded RecieveNotification method + * for the derived class to process. + */ + inline + void ProcessNotification(NotifyType notify_type, const Subject* subject); + + friend class Subject; + }; + + /** Slight Variation of the Observer Design Pattern (Subject part). + * This class implements the Subject class of the Observer Design + * Pattern. An Observer "Attach"es to a Subject, indicating that it + * would like to be notified of changes in the Subject. Any + * derived class that is to be observed has to inherit off the + * Subject base class. If the subject needs to notify the + * Observer, it calls the Notify method. + */ + class Subject + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Subject() + {} + + /** Default destructor */ + inline + virtual ~Subject(); + //@} + + /**@name Methods to Add and Remove Observers. + * Currently, the notify_type flags are not used, + * and Observers are attached in general and will + * recieve all notifications (of the type requested + * and possibly of types not requested). It is + * up to the observer to ignore the types they + * are not interested in. The NotifyType in the + * parameter list is so a more efficient mechanism + * depending on type could be implemented later if + * necessary.*/ + //@{ + + /** Attach the specified observer + * (i.e., begin recieving notifications). */ + inline + void AttachObserver(Observer::NotifyType notify_type, Observer* observer) const; + + /** Detach the specified observer + * (i.e., no longer recieve notifications). */ + inline + void DetachObserver(Observer::NotifyType notify_type, Observer* observer) const; + //@} + + protected: + + inline + void Notify(Observer::NotifyType notify_type) const; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Subject(const Subject&); + + /** Overloaded Equals Operator */ + void operator=(const Subject&); + //@} + + mutable std::vector<Observer*> observers_; + + }; + + /* inline methods */ + inline + Observer::~Observer() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::~Observer", dbg_verbosity); + if (DBG_VERBOSITY()>=1) { + for (Index i=0; i<(Index)subjects_.size(); i++) { + DBG_PRINT((1,"subjects_[%d] = 0x%x\n", i, subjects_[i])); + } + } +#endif + // Detach all subjects + for (Int i=(Int)(subjects_.size()-1); i>=0; i--) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1,"About to detach subjects_[%d] = 0x%x\n", i, subjects_[i])); +#endif + + RequestDetach(NT_All, subjects_[i]); + } + } + + inline + void Observer::RequestAttach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestAttach", dbg_verbosity); + + // Add the subject to the list if it does not already exist + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + DBG_ASSERT(attached_subject == subjects_.end()); + DBG_ASSERT(subject); +#endif + + // add the subject to the list + subjects_.push_back(subject); + // Attach the observer to the subject + subject->AttachObserver(notify_type, this); + } + + inline + void Observer::RequestDetach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestDetach", dbg_verbosity); + DBG_PRINT((1, "Requesting detach of subject: 0x%x\n", subject)); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + if (attached_subject != subjects_.end()) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1, "Removing subject: 0x%x from the list\n", subject)); +#endif + + subjects_.erase(attached_subject); + } + + // Detach the observer from the subject + subject->DetachObserver(notify_type, this); + } + } + + inline + void Observer::ProcessNotification(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::ProcessNotification", dbg_verbosity); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + + // We must be processing a notification for a + // subject that was previously attached. +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + this->RecieveNotification(notify_type, subject); + + if (notify_type == NT_BeingDestroyed) { + // the subject is going away, remove it from our list + subjects_.erase(attached_subject); + } + } + } + + inline + Subject::~Subject() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::~Subject", dbg_verbosity); +#endif + + std::vector<Observer*>::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(Observer::NT_BeingDestroyed, this); + } + } + + inline + void Subject::AttachObserver(Observer::NotifyType notify_type, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::AttachObserver", dbg_verbosity); + // current implementation notifies all observers of everything + // they must filter the notifications that they are not interested + // in (i.e. a hub, not a router) + DBG_ASSERT(observer); + + std::vector<Observer*>::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); + DBG_ASSERT(attached_observer == observers_.end()); + + DBG_ASSERT(observer); +#endif + + observers_.push_back(observer); + } + + inline + void Subject::DetachObserver(Observer::NotifyType notify_type, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::DetachObserver", dbg_verbosity); + DBG_ASSERT(observer); +#endif + + if (observer) { + std::vector<Observer*>::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_observer != observers_.end()); +#endif + + if (attached_observer != observers_.end()) { + observers_.erase(attached_observer); + } + } + } + + inline + void Subject::Notify(Observer::NotifyType notify_type) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::Notify", dbg_verbosity); +#endif + + std::vector<Observer*>::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(notify_type, this); + } + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpOptionsList.hpp b/thirdparty/linux/include/coin/coin/IpOptionsList.hpp new file mode 100644 index 0000000..a17863f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpOptionsList.hpp @@ -0,0 +1,289 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOptionsList.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOPTLIST_HPP__ +#define __IPOPTLIST_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpRegOptions.hpp" + +#include <iostream> +#include <map> + +namespace Ipopt +{ + /** Exception that can be used to indicate errors with options */ + DECLARE_STD_EXCEPTION(OPTION_INVALID); + + /** This class stores a list of user set options. Each options is + * identified by a case-insensitive keyword (tag). Its value is + * stored internally as a string (always lower case), but for + * convenience set and get methods are provided to obtain Index and + * Number type values. For each keyword we also keep track of how + * often the value of an option has been requested by a get method. + */ + class OptionsList : public ReferencedObject + { + /** Class for storing the value and counter for each option in + * OptionsList. */ + class OptionValue + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor (needed for the map) */ + OptionValue() + : + initialized_(false) + {} + + /** Constructor given the value */ + OptionValue(std::string value, bool allow_clobber, bool dont_print) + : + value_(value), + counter_(0), + initialized_(true), + allow_clobber_(allow_clobber), + dont_print_(dont_print) + {} + + /** Copy Constructor */ + OptionValue(const OptionValue& copy) + : + value_(copy.value_), + counter_(copy.counter_), + initialized_(copy.initialized_), + allow_clobber_(copy.allow_clobber_), + dont_print_(copy.dont_print_) + {} + + /** Equals operator */ + void operator=(const OptionValue& copy) + { + value_=copy.value_; + counter_=copy.counter_; + initialized_=copy.initialized_; + allow_clobber_=copy.allow_clobber_; + dont_print_=copy.dont_print_; + } + + /** Default Destructor */ + ~OptionValue() + {} + //@} + + /** Method for retrieving the value of an option. Calling this + * method will increase the counter by one. */ + std::string GetValue() const + { + DBG_ASSERT(initialized_); + counter_++; + return value_; + } + + /** Method for retrieving the value without increasing the + * counter */ + std::string Value() const + { + DBG_ASSERT(initialized_); + return value_; + } + + /** Method for accessing current value of the request counter */ + Index Counter() const + { + DBG_ASSERT(initialized_); + return counter_; + } + + /** True if the option can be overwritten */ + bool AllowClobber() const + { + DBG_ASSERT(initialized_); + return allow_clobber_; + } + + /** True if this option is not to show up in the + * print_user_options output */ + bool DontPrint() const + { + DBG_ASSERT(initialized_); + return dont_print_; + } + + private: + /** Value for this option */ + std::string value_; + + /** Counter for requests */ + mutable Index counter_; + + /** for debugging */ + bool initialized_; + + /** True if the option can be overwritten */ + bool allow_clobber_; + + /** True if this option is not to show up in the + * print_user_options output */ + bool dont_print_; + }; + + public: + /**@name Constructors/Destructors */ + //@{ + OptionsList(SmartPtr<RegisteredOptions> reg_options, SmartPtr<Journalist> jnlst) + : reg_options_(reg_options), jnlst_(jnlst) + {} + + OptionsList() + {} + + /** Copy Constructor */ + OptionsList(const OptionsList& copy) + { + // copy all the option strings and values + options_ = copy.options_; + // copy the registered options pointer + reg_options_ = copy.reg_options_; + } + + /** Default destructor */ + virtual ~OptionsList() + {} + + /** Overloaded Equals Operator */ + virtual void operator=(const OptionsList& source) + { + options_ = source.options_; + reg_options_ = source.reg_options_; + jnlst_ = source.jnlst_; + } + //@} + + /** Method for clearing all previously set options */ + virtual void clear() + { + options_.clear(); + } + + /** @name Get / Set Methods */ + //@{ + virtual void SetRegisteredOptions(const SmartPtr<RegisteredOptions> reg_options) + { + reg_options_ = reg_options; + } + virtual void SetJournalist(const SmartPtr<Journalist> jnlst) + { + jnlst_ = jnlst; + } + //@} + /** @name Methods for setting options */ + //@{ + virtual bool SetStringValue(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValue(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValue(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for setting options only if they have not been + * set before*/ + //@{ + virtual bool SetStringValueIfUnset(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValueIfUnset(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValueIfUnset(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for retrieving values from the options list. If + * a tag is not found, the methods return false, and value is set + * to the default value defined in the registered options. */ + //@{ + virtual bool GetStringValue(const std::string& tag, std::string& value, + const std::string& prefix) const; + virtual bool GetEnumValue(const std::string& tag, Index& value, + const std::string& prefix) const; + virtual bool GetBoolValue(const std::string& tag, bool& value, + const std::string& prefix) const; + virtual bool GetNumericValue(const std::string& tag, Number& value, + const std::string& prefix) const; + virtual bool GetIntegerValue(const std::string& tag, Index& value, + const std::string& prefix) const; + //@} + + /** Get a string with the list of all options (tag, value, counter) */ + virtual void PrintList(std::string& list) const; + + /** Get a string with the list of all options set by the user + * (tag, value, use/notused). Here, options with dont_print flag + * set to true are not printed. */ + virtual void PrintUserOptions(std::string& list) const; + + /** Read options from the stream is. Returns false if + * an error was encountered. */ + virtual bool ReadFromStream(const Journalist& jnlst, std::istream& is, bool allow_clobber = false); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // OptionsList(); + + //@} + + /** map for storing the options */ + std::map< std::string, OptionValue > options_; + + /** list of all the registered options to validate against */ + SmartPtr<RegisteredOptions> reg_options_; + + /** Journalist for writing error messages, etc. */ + SmartPtr<Journalist> jnlst_; + + /** auxilliary method for converting sting to all lower-case + * letters */ + const std::string& lowercase(const std::string tag) const; + + /** auxilliary method for finding the value for a tag in the + * options list. This method first looks for the concatenated + * string prefix+tag (if prefix is not ""), and if this is not + * found, it looks for tag. The return value is true iff + * prefix+tag or tag is found. In that case, the corresponding + * string value is copied into value. */ + bool find_tag(const std::string& tag, const std::string& prefix, + std::string& value) const; + + /** tells whether or not we can clobber a particular option. + * returns true if the option does not already exist, or if + * the option exists but is set to allow_clobber + */ + bool will_allow_clobber(const std::string& tag) const; + + /** read the next token from stream is. Returns false, if EOF was + * reached before a tokens was ecountered. */ + bool readnexttoken(std::istream& is, std::string& token); + + /** auxilliary string set by lowercase method */ + mutable std::string lowercase_buffer_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpOrigIpoptNLP.hpp b/thirdparty/linux/include/coin/coin/IpOrigIpoptNLP.hpp new file mode 100644 index 0000000..41b10fa --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpOrigIpoptNLP.hpp @@ -0,0 +1,488 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOrigIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPORIGIPOPTNLP_HPP__ +#define __IPORIGIPOPTNLP_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpException.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /** enumeration for the Hessian information type. */ + enum HessianApproximationType { + EXACT=0, + LIMITED_MEMORY + }; + + /** enumeration for the Hessian approximation space. */ + enum HessianApproximationSpace { + NONLINEAR_VARS=0, + ALL_VARS + }; + + /** This class maps the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles caching, + * and (some day) takes care of addition of slacks. + */ + class OrigIpoptNLP : public IpoptNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + OrigIpoptNLP(const SmartPtr<const Journalist>& jnlst, + const SmartPtr<NLP>& nlp, + const SmartPtr<NLPScalingObject>& nlp_scaling); + + /** Default destructor */ + virtual ~OrigIpoptNLP(); + //@} + + /** Initialize - overloaded from IpoptNLP */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr<Vector>& x, + bool init_x, + SmartPtr<Vector>& y_c, + bool init_y_c, + SmartPtr<Vector>& y_d, + bool init_y_d, + SmartPtr<Vector>& z_L, + bool init_z_L, + SmartPtr<Vector>& z_U, + bool init_z_U, + SmartPtr<Vector>& v_L, + SmartPtr<Vector>& v_U + ); + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate) + { + return nlp_->GetWarmStartIterate(warm_start_iterate); + } + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x); + + /** Objective value (depending in mu) - incorrect version for + * OrigIpoptNLP */ + virtual Number f(const Vector& x, Number mu); + + /** Gradient of the objective */ + virtual SmartPtr<const Vector> grad_f(const Vector& x); + + /** Gradient of the objective (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr<const Vector> grad_f(const Vector& x, Number mu); + + /** Equality constraint residual */ + virtual SmartPtr<const Vector> c(const Vector& x); + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr<const Matrix> jac_c(const Vector& x); + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr<const Vector> d(const Vector& x); + + /** Jacobian Matrix for inequality constraints*/ + virtual SmartPtr<const Matrix> jac_d(const Vector& x); + + /** Hessian of the Lagrangian */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ); + + /** Hessian of the Lagrangian (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu); + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr<const SymMatrix> uninitialized_h(); + + /** Lower bounds on x */ + virtual SmartPtr<const Vector> x_L() const + { + return x_L_; + } + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr<const Matrix> Px_L() const + { + return Px_L_; + } + + /** Upper bounds on x */ + virtual SmartPtr<const Vector> x_U() const + { + return x_U_; + } + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr<const Matrix> Px_U() const + { + return Px_U_; + } + + /** Lower bounds on d */ + virtual SmartPtr<const Vector> d_L() const + { + return d_L_; + } + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr<const Matrix> Pd_L() const + { + return Pd_L_; + } + + /** Upper bounds on d */ + virtual SmartPtr<const Vector> d_U() const + { + return d_U_; + } + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr<const Matrix> Pd_U() const + { + return Pd_U_; + } + + virtual SmartPtr<const SymMatrixSpace> HessianMatrixSpace() const + { + return h_space_; + } + + virtual SmartPtr<const VectorSpace> x_space() const + { + return x_space_; + } + //@} + + /** Accessor method for vector/matrix spaces pointers */ + virtual void GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space); + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U); + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const + { + return f_evals_; + } + virtual Index grad_f_evals() const + { + return grad_f_evals_; + } + virtual Index c_evals() const + { + return c_evals_; + } + virtual Index jac_c_evals() const + { + return jac_c_evals_; + } + virtual Index d_evals() const + { + return d_evals_; + } + virtual Index jac_d_evals() const + { + return jac_d_evals_; + } + virtual Index h_evals() const + { + return h_evals_; + } + //@} + + /** Solution Routines - overloaded from IpoptNLP*/ + //@{ + void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr<const IpoptData> ip_data, + SmartPtr<IpoptCalculatedQuantities> ip_cq); + //@} + + /** @name Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Accessor method to the underlying NLP */ + SmartPtr<NLP> nlp() + { + return nlp_; + } + + /**@name Methods related to function evaluation timing. */ + //@{ + + /** Reset the timing statistics */ + void ResetTimes(); + + void PrintTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + const TimedTask& f_eval_time() const + { + return f_eval_time_; + } + const TimedTask& grad_f_eval_time() const + { + return grad_f_eval_time_; + } + const TimedTask& c_eval_time() const + { + return c_eval_time_; + } + const TimedTask& jac_c_eval_time() const + { + return jac_c_eval_time_; + } + const TimedTask& d_eval_time() const + { + return d_eval_time_; + } + const TimedTask& jac_d_eval_time() const + { + return jac_d_eval_time_; + } + const TimedTask& h_eval_time() const + { + return h_eval_time_; + } + + Number TotalFunctionEvaluationCpuTime() const; + Number TotalFunctionEvaluationSysTime() const; + Number TotalFunctionEvaluationWallclockTime() const; + //@} + + private: + /** journalist */ + SmartPtr<const Journalist> jnlst_; + + /** Pointer to the NLP */ + SmartPtr<NLP> nlp_; + + /** Necessary Vector/Matrix spaces */ + //@{ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> c_space_; + SmartPtr<const VectorSpace> d_space_; + SmartPtr<const VectorSpace> x_l_space_; + SmartPtr<const MatrixSpace> px_l_space_; + SmartPtr<const VectorSpace> x_u_space_; + SmartPtr<const MatrixSpace> px_u_space_; + SmartPtr<const VectorSpace> d_l_space_; + SmartPtr<const MatrixSpace> pd_l_space_; + SmartPtr<const VectorSpace> d_u_space_; + SmartPtr<const MatrixSpace> pd_u_space_; + SmartPtr<const MatrixSpace> jac_c_space_; + SmartPtr<const MatrixSpace> jac_d_space_; + SmartPtr<const SymMatrixSpace> h_space_; + + SmartPtr<const MatrixSpace> scaled_jac_c_space_; + SmartPtr<const MatrixSpace> scaled_jac_d_space_; + SmartPtr<const SymMatrixSpace> scaled_h_space_; + //@} + /**@name Storage for Model Quantities */ + //@{ + /** Objective function */ + CachedResults<Number> f_cache_; + + /** Gradient of the objective function */ + CachedResults<SmartPtr<const Vector> > grad_f_cache_; + + /** Equality constraint residuals */ + CachedResults<SmartPtr<const Vector> > c_cache_; + + /** Jacobian Matrix for equality constraints + * (current iteration) */ + CachedResults<SmartPtr<const Matrix> > jac_c_cache_; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + CachedResults<SmartPtr<const Vector> > d_cache_; + + /** Jacobian Matrix for inequality constraints + * (current iteration) */ + CachedResults<SmartPtr<const Matrix> > jac_d_cache_; + + /** Hessian of the lagrangian + * (current iteration) */ + CachedResults<SmartPtr<const SymMatrix> > h_cache_; + + /** Unscaled version of x vector */ + CachedResults<SmartPtr<const Vector> > unscaled_x_cache_; + + /** Lower bounds on x */ + SmartPtr<const Vector> x_L_; + + /** Permutation matrix (x_L_ -> x) */ + SmartPtr<const Matrix> Px_L_; + + /** Upper bounds on x */ + SmartPtr<const Vector> x_U_; + + /** Permutation matrix (x_U_ -> x */ + SmartPtr<const Matrix> Px_U_; + + /** Lower bounds on d */ + SmartPtr<const Vector> d_L_; + + /** Permutation matrix (d_L_ -> d) */ + SmartPtr<const Matrix> Pd_L_; + + /** Upper bounds on d */ + SmartPtr<const Vector> d_U_; + + /** Permutation matrix (d_U_ -> d */ + SmartPtr<const Matrix> Pd_U_; + + /** Original unmodified lower bounds on x */ + SmartPtr<const Vector> orig_x_L_; + + /** Original unmodified upper bounds on x */ + SmartPtr<const Vector> orig_x_U_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + OrigIpoptNLP(); + + /** Copy Constructor */ + OrigIpoptNLP(const OrigIpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const OrigIpoptNLP&); + //@} + + /** @name auxilliary functions */ + //@{ + /** relax the bounds by a relative move of relax_bound_factor. + * Here, relax_bound_factor should be negative (or zero) for + * lower bounds, and positive (or zero) for upper bounds. + */ + void relax_bounds(Number bound_relax_factor, Vector& bounds); + /** Method for getting the unscaled version of the x vector */ + SmartPtr<const Vector> get_unscaled_x(const Vector& x); + //@} + + /** @name Algorithmic parameters */ + //@{ + /** relaxation factor for the bounds */ + Number bound_relax_factor_; + /** Flag indicating whether the primal variables should be + * projected back into original bounds are optimization. */ + bool honor_original_bounds_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Flag indicating in which space Hessian is to be approximated. */ + HessianApproximationSpace hessian_approximation_space_; + /** Flag indicating whether it is desired to check if there are + * Nan or Inf entries in first and second derivative matrices. */ + bool check_derivatives_for_naninf_; + /** Flag indicating if we need to ask for equality constraint + * Jacobians only once */ + bool jac_c_constant_; + /** Flag indicating if we need to ask for inequality constraint + * Jacobians only once */ + bool jac_d_constant_; + /** Flag indicating if we need to ask for Hessian only once */ + bool hessian_constant_; + //@} + + /** @name Counters for the function evaluations */ + //@{ + Index f_evals_; + Index grad_f_evals_; + Index c_evals_; + Index jac_c_evals_; + Index d_evals_; + Index jac_d_evals_; + Index h_evals_; + //@} + + /** Flag indicating if initialization method has been called */ + bool initialized_; + + /**@name Timing statistics for the function evaluations. */ + //@{ + TimedTask f_eval_time_; + TimedTask grad_f_eval_time_; + TimedTask c_eval_time_; + TimedTask jac_c_eval_time_; + TimedTask d_eval_time_; + TimedTask jac_d_eval_time_; + TimedTask h_eval_time_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpPDSystemSolver.hpp b/thirdparty/linux/include/coin/coin/IpPDSystemSolver.hpp new file mode 100644 index 0000000..b436e67 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpPDSystemSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpPDSystemSolver.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPPDSYSTEMSOLVER_HPP__ +#define __IPPDSYSTEMSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include "IpIteratesVector.hpp" + +namespace Ipopt +{ + + /** Pure Primal Dual System Solver Base Class. + * This is the base class for all derived Primal-Dual System Solver Types. + * + * Here, we understand the primal-dual system as the following linear + * system: + * + * \f$ + * \left[\begin{array}{cccccccc} + * W & 0 & J_c^T & J_d^T & -P^x_L & P^x_U & 0 & 0 \\ + * 0 & 0 & 0 & -I & 0 & 0 & -P_L^d & P_U^d \\ + * J_c & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ + * J_d & -I & 0 & 0 & 0 & 0 & 0 & 0\\ + * Z_L(P_L^x)^T & 0 & 0 & 0 & Sl^x_L & 0 & 0 & 0\\ + * -Z_U(P_U^x)^T & 0 & 0 & 0 & 0 & Sl^x_U & 0 & 0\\ + * 0 & V_L(P_L^d)^T & 0 & 0 & 0 & 0 & Sl^s_L & 0 \\ + * 0 & -V_U(P_U^d)^T & 0 & 0 & 0 & 0 & 0 & Sl^s_U \\ + * \end{array}\right] + * \left(\begin{array}{c} + * sol_x\\ sol_s\\ sol_c\\ sol_d\\ sol^z_L\\ sol^z_U\\ sol^v_L\\ + * sol^v_U + * \end{array}\right) = + * \left(\begin{array}{c} + * rhs_x\\ rhs_s\\ rhs_c\\ rhs_d\\ rhs^z_L\\ rhs^z_U\\ rhs^v_L\\ + * rhs^v_U + * \end{array}\right) + * \f$ + * + * Here, \f$Sl^x_L = (P^x_L)^T x - x_L\f$, + * \f$Sl^x_U = x_U - (P^x_U)^T x\f$, \f$Sl^d_L = (P^d_L)^T d(x) - d_L\f$, + * \f$Sl^d_U = d_U - (P^d_U)^T d(x)\f$. The results returned to the + * caller is \f$res = \alpha * sol + \beta * res\f$. + * + * The solution of this linear system (in order to compute the search + * direction of the algorthim) usually requires a considerable amount of + * computation time. Therefore, it is important to tailor the solution + * of this system to the characteristics of the problem. The purpose of + * this base class is to provide a generic interface to the algorithm + * that it can use whenever it requires a solution of the above system. + * Particular implementation can then be written to provide the methods + * defined here. + * + * It is implicitly assumed here, that the upper left 2 by 2 block + * is possibly modified (implicitly or explicitly) so that its + * projection onto the null space of the overall constraint + * Jacobian \f$\left[\begin{array}{cc}J_c & 0\\J_d & + * -I\end{array}\right]\f$ is positive definite. This is necessary + * to guarantee certain descent properties of the resulting search + * direction. For example, in the full space implementation, a + * multiple of the identity might be added to the upper left 2 by 2 + * block. + * + * Note that the Solve method might be called several times for different + * right hand sides, but with identical data. Therefore, if possible, + * an implemetation of PDSystem should check whether the incoming data has + * changed, and not redo factorization etc. unless necessary. + */ + class PDSystemSolver: public AlgorithmStrategyObject + { + public: + /** @name /Destructor */ + //@{ + /** Default Constructor */ + PDSystemSolver() + {} + + /** Default destructor */ + virtual ~PDSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Solve the primal dual system, given one right hand side. If + * the flag allow_inexact is set to true, it is not necessary to + * solve the system to best accuracy; for example, we don't want + * iterative refinement during the computation of the second + * order correction. On the other hand, if improve_solution is + * true, the solution given in res should be improved (here beta + * has to be zero, and res is assume to be the solution for the + * system using rhs, without the factor alpha...). THe return + * value is false, if a solution could not be computed (for + * example, when the Hessian regularization parameter becomes too + * large.) + */ + virtual bool Solve(Number alpha, + Number beta, + const IteratesVector& rhs, + IteratesVector& res, + bool allow_inexact=false, + bool improve_solution=false) =0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Overloaded Equals Operator */ + PDSystemSolver& operator=(const PDSystemSolver&); + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpReferenced.hpp b/thirdparty/linux/include/coin/coin/IpReferenced.hpp new file mode 100644 index 0000000..996beda --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpReferenced.hpp @@ -0,0 +1,258 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReferenced.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPREFERENCED_HPP__ +#define __IPREFERENCED_HPP__ + +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +#include <list> + +#if COIN_IPOPT_CHECKLEVEL > 3 + #define IP_DEBUG_REFERENCED +#endif + +namespace Ipopt +{ + + /** Psydo-class, from which everything has to inherit that wants to + * use be registered as a Referencer for a ReferencedObject. + */ + class Referencer + {} + ; + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * For every most derived object only one ReferencedObject may exist, + * that is multiple inheritance requires virtual inheritance, see also + * the 2nd point in ticket #162. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject + { + public: + ReferencedObject() + : + reference_count_(0) + {} + + virtual ~ReferencedObject() + { + DBG_ASSERT(reference_count_ == 0); + } + + inline + Index ReferenceCount() const; + + inline + void AddRef(const Referencer* referencer) const; + + inline + void ReleaseRef(const Referencer* referencer) const; + + private: + mutable Index reference_count_; + +# ifdef IP_DEBUG_REFERENCED + mutable std::list<const Referencer*> referencers_; +# endif + + }; + + /* inline methods */ + inline + Index ReferencedObject::ReferenceCount() const + { + // DBG_START_METH("ReferencedObject::ReferenceCount()", 0); + // DBG_PRINT((1,"Returning reference_count_ = %d\n", reference_count_)); + return reference_count_; + } + + inline + void ReferencedObject::AddRef(const Referencer* referencer) const + { + // DBG_START_METH("ReferencedObject::AddRef(const Referencer* referencer)", 0); + reference_count_++; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); +# ifdef IP_DEBUG_REFERENCED + referencers_.push_back(referencer); +# endif + + } + + inline + void ReferencedObject::ReleaseRef(const Referencer* referencer) const + { + // DBG_START_METH("ReferencedObject::ReleaseRef(const Referencer* referencer)", + // 0); + reference_count_--; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); + +# ifdef IP_DEBUG_REFERENCED + + bool found = false; + std::list<const Referencer*>::iterator iter; + for (iter = referencers_.begin(); iter != referencers_.end(); iter++) { + if ((*iter) == referencer) { + found = true; + break; + } + } + + // cannot call release on a reference that was never added... + DBG_ASSERT(found); + + if (found) { + referencers_.erase(iter); + } +# endif + + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpRegOptions.hpp b/thirdparty/linux/include/coin/coin/IpRegOptions.hpp new file mode 100644 index 0000000..5859493 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpRegOptions.hpp @@ -0,0 +1,658 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpRegOptions.hpp 2189 2013-03-31 15:06:11Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-06-18 + +#ifndef __IPREGOPTIONS_HPP__ +#define __IPREGOPTIONS_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpSmartPtr.hpp" + +#include <map> + +namespace Ipopt +{ + + enum RegisteredOptionType + { + OT_Number, + OT_Integer, + OT_String, + OT_Unknown + }; + + /** Base class for registered options. The derived types are more + * specific to a string option or a Number (real) option, etc. + */ + class RegisteredOption : public ReferencedObject + { + public: + /** class to hold the valid string settings for a string option */ + class string_entry + { + public: + string_entry(const std::string& value, const std::string& description) + : value_(value), description_(description) + {} + std::string value_; + std::string description_; + }; + + /** Constructors / Destructors */ + //@{ + RegisteredOption(Index counter) + : + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const std::string& name, + const std::string& short_description, + const std::string& long_description, + const std::string& registering_category, + Index counter) + : + name_(name), + short_description_(short_description), + long_description_(long_description), + registering_category_(registering_category), + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const RegisteredOption& copy) + : + name_(copy.name_), + short_description_(copy.short_description_), + long_description_(copy.long_description_), + registering_category_(copy.registering_category_), + type_(copy.type_), + has_lower_(copy.has_lower_), + lower_(copy.lower_), + has_upper_(copy.has_upper_), + upper_(copy.upper_), + valid_strings_(copy.valid_strings_), + counter_(copy.counter_) + {} + + virtual ~RegisteredOption() + {} + //@} + + DECLARE_STD_EXCEPTION(ERROR_CONVERTING_STRING_TO_ENUM); + + /** Standard Get / Set Methods */ + //@{ + /** Get the option's name (tag in the input file) */ + virtual const std::string& Name() const + { + return name_; + } + /** Set the option's name (tag in the input file) */ + virtual void SetName(const std::string& name) + { + name_ = name; + } + /** Get the short description */ + virtual const std::string& ShortDescription() const + { + return short_description_; + } + /** Get the long description */ + virtual const std::string& LongDescription() const + { + return long_description_; + } + /** Set the short description */ + virtual void SetShortDescription(const std::string& short_description) + { + short_description_ = short_description; + } + /** Set the long description */ + virtual void SetLongDescription(const std::string& long_description) + { + long_description_ = long_description; + } + /** Get the registering class */ + virtual const std::string& RegisteringCategory() const + { + return registering_category_; + } + /** Set the registering class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + registering_category_ = registering_category; + } + /** Get the Option's type */ + virtual const RegisteredOptionType& Type() const + { + return type_; + } + /** Get the Option's type */ + virtual void SetType(const RegisteredOptionType& type) + { + type_ = type; + } + /** Counter */ + virtual Index Counter() const + { + return counter_; + } + //@} + + /** @name Get / Set methods valid for specific types - NOTE: the Type + * must be set before calling these methods. + */ + //@{ + /** check if the option has a lower bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasLower() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_lower_; + } + /** check if the lower bound is strict - can be called for + OT_Number */ + virtual const bool& LowerStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_lower_ == true); + return lower_strict_; + } + /** get the Number version of the lower bound - can be called for + * OT_Number */ + virtual Number LowerNumber() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Number); + return lower_; + } + /** set the Number version of the lower bound - can be called for + * OT_Number */ + virtual void SetLowerNumber(const Number& lower, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + lower_ = lower; + lower_strict_ = strict, has_lower_ = true; + } + /** get the Integer version of the lower bound can be called for + * OT_Integer*/ + virtual Index LowerInteger() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Integer); + return (Index)lower_; + } + /** set the Integer version of the lower bound - can be called for + * OT_Integer */ + virtual void SetLowerInteger(const Index& lower) + { + DBG_ASSERT(type_ == OT_Integer); + lower_ = (Number)lower; + has_lower_ = true; + } + /** check if the option has an upper bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasUpper() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_upper_; + } + /** check if the upper bound is strict - can be called for + * OT_Number */ + virtual const bool& UpperStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_upper_ == true); + return upper_strict_; + } + /** get the Number version of the upper bound - can be called for + * OT_Number */ + virtual Number UpperNumber() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Number); + return upper_; + } + /** set the Number version of the upper bound - can be called for + * OT_Number */ + virtual void SetUpperNumber(const Number& upper, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + upper_ = upper; + upper_strict_ = strict; + has_upper_ = true; + } + /** get the Integer version of the upper bound - can be called for + * OT_Integer*/ + virtual Index UpperInteger() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Integer); + return (Index)upper_; + } + /** set the Integer version of the upper bound - can be called for + * OT_Integer */ + virtual void SetUpperInteger(const Index& upper) + { + DBG_ASSERT(type_ == OT_Integer); + upper_ = (Number)upper; + has_upper_ = true; + } + /** method to add valid string entries - can be called for + * OT_String */ + virtual void AddValidStringSetting(const std::string value, + const std::string description) + { + DBG_ASSERT(type_ == OT_String); + valid_strings_.push_back(string_entry(value, description)); + } + /** get the default as a Number - can be called for OT_Number */ + virtual Number DefaultNumber() const + { + DBG_ASSERT(type_ == OT_Number); + return default_number_; + } + /** Set the default as a Number - can be called for OT_Number */ + virtual void SetDefaultNumber(const Number& default_value) + { + DBG_ASSERT(type_ == OT_Number); + default_number_ = default_value; + } + /** get the default as an Integer - can be called for OT_Integer*/ + virtual Index DefaultInteger() const + { + DBG_ASSERT(type_ == OT_Integer); + return (Index)default_number_; + } + /** Set the default as an Integer - can be called for + OT_Integer */ + virtual void SetDefaultInteger(const Index& default_value) + { + DBG_ASSERT(type_ == OT_Integer); + default_number_ = (Number)default_value; + } + /** get the default as a string - can be called for OT_String */ + virtual std::string DefaultString() const + { + DBG_ASSERT(type_ == OT_String); + return default_string_; + } + /** get the default as a string, but as the index of the string in + * the list - helps map from a string to an enum- can be called + * for OT_String */ + virtual Index DefaultStringAsEnum() const + { + DBG_ASSERT(type_ == OT_String); + return MapStringSettingToEnum(default_string_); + } + /** Set the default as a string - can be called for OT_String */ + virtual void SetDefaultString(const std::string& default_value) + { + DBG_ASSERT(type_ == OT_String); + default_string_ = default_value; + } + /** get the valid string settings - can be called for OT_String */ + virtual std::vector<string_entry> GetValidStrings() const + { + DBG_ASSERT(type_ == OT_String); + return valid_strings_; + } + /** Check if the Number value is a valid setting - can be called + * for OT_Number */ + virtual bool IsValidNumberSetting(const Number& value) const + { + DBG_ASSERT(type_ == OT_Number); + if (has_lower_ && ((lower_strict_ == true && value <= lower_) || + (lower_strict_ == false && value < lower_))) { + return false; + } + if (has_upper_ && ((upper_strict_ == true && value >= upper_) || + (upper_strict_ == false && value > upper_))) { + return false; + } + return true; + } + /** Check if the Integer value is a valid setting - can be called + * for OT_Integer */ + virtual bool IsValidIntegerSetting(const Index& value) const + { + DBG_ASSERT(type_ == OT_Integer); + if (has_lower_ && value < lower_) { + return false; + } + if (has_upper_ && value > upper_) { + return false; + } + return true; + } + /** Check if the String value is a valid setting - can be called + * for OT_String */ + virtual bool IsValidStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the case used when + * the setting was registered. + */ + virtual std::string MapStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the index of the + * matched setting in the list of string settings. Helps map a + * string setting to an enumeration. + */ + virtual Index MapStringSettingToEnum(const std::string& value) const; + //@} + + /** output a description of the option */ + virtual void OutputDescription(const Journalist& jnlst) const; + /** output a more concise version */ + virtual void OutputShortDescription(const Journalist& jnlst) const; + /** output a latex version */ + virtual void OutputLatexDescription(const Journalist& jnlst) const; + + private: + std::string name_; + std::string short_description_; + std::string long_description_; + std::string registering_category_; + RegisteredOptionType type_; + + bool has_lower_; + bool lower_strict_; + Number lower_; + bool has_upper_; + bool upper_strict_; + Number upper_; + Number default_number_; + + void MakeValidLatexString(std::string source, std::string& dest) const; + std::string MakeValidLatexNumber(Number value) const; + + /** Compare two strings and return true if they are equal (case + insensitive comparison) */ + bool string_equal_insensitive(const std::string& s1, + const std::string& s2) const; + + std::vector<string_entry> valid_strings_; + std::string default_string_; + + /** Has the information as how many-th option this one was + * registered. */ + const Index counter_; + }; + + /** Class for storing registered options. Used for validation and + * documentation. + */ + class RegisteredOptions : public ReferencedObject + { + public: + /** Constructors / Destructors */ + //@{ + /** Standard Constructor */ + RegisteredOptions() + : + next_counter_(0), + current_registering_category_("Uncategorized") + {} + + /** Standard Destructor */ + virtual ~RegisteredOptions() + {} + //@} + + DECLARE_STD_EXCEPTION(OPTION_ALREADY_REGISTERED); + + /** Methods to interact with registered options */ + //@{ + /** set the registering class. All subsequent options will be + * added with the registered class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + current_registering_category_ = registering_category; + } + + /** retrieve the value of the current registering category */ + virtual std::string RegisteringCategory() + { + return current_registering_category_; + } + + /** Add a Number option (with no restrictions) */ + virtual void AddNumberOption(const std::string& name, + const std::string& short_description, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a lower bound) */ + virtual void AddLowerBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a upper bound) */ + virtual void AddUpperBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number upper, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a both bounds) */ + virtual void AddBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool lower_strict, + Number upper, bool upper_strict, + Number default_value, + const std::string& long_description=""); + /** Add a Integer option (with no restrictions) */ + virtual void AddIntegerOption(const std::string& name, + const std::string& short_description, + Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a lower bound) */ + virtual void AddLowerBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a upper bound) */ + virtual void AddUpperBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index upper, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a both bounds) */ + virtual void AddBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index upper, + Index default_value, + const std::string& long_description=""); + + /** Add a String option (with no restrictions) */ + virtual void AddStringOption(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::vector<std::string>& settings, + const std::vector<std::string>& descriptions, + const std::string& long_description=""); + /** Methods that make adding string options with only a few + * entries easier */ + virtual void AddStringOption1(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& long_description=""); + virtual void AddStringOption2(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& long_description=""); + virtual void AddStringOption3(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& long_description=""); + virtual void AddStringOption4(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& long_description=""); + virtual void AddStringOption5(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& long_description=""); + virtual void AddStringOption6(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& long_description=""); + virtual void AddStringOption7(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& long_description=""); + virtual void AddStringOption8(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& long_description=""); + virtual void AddStringOption9(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& long_description=""); + virtual void AddStringOption10(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& setting10, + const std::string& description10, + const std::string& long_description=""); + + /** Get a registered option - this will return NULL if the option + * does not exist */ + virtual SmartPtr<const RegisteredOption> GetOption(const std::string& name); + + /** Output documentation for the options - gives a description, + * etc. */ + virtual void OutputOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories); + + /** Output documentation in Latex format to include in a latex file */ + virtual void OutputLatexOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories); + //@} + + typedef std::map<std::string, SmartPtr<RegisteredOption> > RegOptionsList; + + /** Giving access to iteratable representation of the registered + * options */ + virtual const RegOptionsList& RegisteredOptionsList () const + { + return registered_options_; + } + + private: + Index next_counter_; + std::string current_registering_category_; + std::map<std::string, SmartPtr<RegisteredOption> > registered_options_; + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpReturnCodes.h b/thirdparty/linux/include/coin/coin/IpReturnCodes.h new file mode 100644 index 0000000..b16d2c6 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpReturnCodes.h @@ -0,0 +1,18 @@ +/*********************************************************************** +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.h 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +#ifndef __IPRETURNCODES_H__ +#define __IPRETURNCODES_H__ + +/* include from a common include file */ + +#include "IpReturnCodes_inc.h" + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpReturnCodes.hpp b/thirdparty/linux/include/coin/coin/IpReturnCodes.hpp new file mode 100644 index 0000000..36dd7d7 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpReturnCodes.hpp @@ -0,0 +1,21 @@ +/*********************************************************************** +// Copyright (C) 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2006-03-01 +************************************************************************/ + +#ifndef __IPRETURNCODES_HPP__ +#define __IPRETURNCODES_HPP__ + +/* include from a common include file */ + +namespace Ipopt +{ +#include "IpReturnCodes_inc.h" +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpReturnCodes.inc b/thirdparty/linux/include/coin/coin/IpReturnCodes.inc new file mode 100644 index 0000000..c6bf70a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpReturnCodes.inc @@ -0,0 +1,70 @@ +C Copyright (C) 2005, 2009 International Business Machines and others. +C All Rights Reserved. +C This code is published under the Eclipse Public License. +C +C $Id: IpReturnCodes.inc 1861 2010-12-21 21:34:47Z andreasw $ +C +C Author: Andreas Waechter IBM 2005-08-11 +C + INTEGER IP_SOLVE_SUCCEEDED + PARAMETER( IP_SOLVE_SUCCEEDED = 0 ) + + INTEGER IP_ACCEPTABLE_LEVEL + PARAMETER( IP_ACCEPTABLE_LEVEL = 1 ) + + INTEGER IP_INFEASIBLE_PROBLEM + PARAMETER( IP_INFEASIBLE_PROBLEM = 2 ) + + INTEGER IP_SEARCH_DIRECTION_TOO_SMALL + PARAMETER( IP_SEARCH_DIRECTION_TOO_SMALL = 3 ) + + INTEGER IP_DIVERGING_ITERATES + PARAMETER( IP_DIVERGING_ITERATES = 4 ) + + INTEGER IP_USER_REQUESTED_STOP + PARAMETER( IP_USER_REQUESTED_STOP = 5 ) + + INTEGER IP_FEASIBLE_POINT_FOUND + PARAMETER( IP_FEASIBLE_POINT_FOUND = 6 ) + + INTEGER IP_ITERATION_EXCEEDED + PARAMETER( IP_ITERATION_EXCEEDED = -1 ) + + INTEGER IP_RESTORATION_FAILED + PARAMETER( IP_RESTORATION_FAILED = -2 ) + + INTEGER IP_ERROR_IN_STEP_COMPUTATION + PARAMETER( IP_ERROR_IN_STEP_COMPUTATION = -3 ) + + INTEGER IP_CPUTIME_EXCEEDED + PARAMETER( IP_CPUTIME_EXCEEDED = -4 ) + + INTEGER IP_NOT_ENOUGH_DEGREES_OF_FRE + PARAMETER( IP_NOT_ENOUGH_DEGREES_OF_FRE = -10 ) + + INTEGER IP_INVALID_PROBLEM_DEFINITION + PARAMETER( IP_INVALID_PROBLEM_DEFINITION = -11) + + INTEGER IP_INVALID_OPTION + PARAMETER( IP_INVALID_OPTION = -12 ) + + INTEGER IP_INVALID_NUMBER_DETECTED + PARAMETER( IP_INVALID_NUMBER_DETECTED = -13 ) + + INTEGER IP_UNRECOVERABLE_EXCEPTION + PARAMETER( IP_UNRECOVERABLE_EXCEPTION = -100 ) + + INTEGER IP_NON_IPOPT_EXCEPTION + PARAMETER( IP_NON_IPOPT_EXCEPTION = -101 ) + + INTEGER IP_INSUFFICIENT_MEMORY + PARAMETER( IP_INSUFFICIENT_MEMORY = -102 ) + + INTEGER IP_INTERNAL_ERROR + PARAMETER( IP_INTERNAL_ERROR = -199 ) + + INTEGER IP_REGULAR_MODE + PARAMETER( IP_REGULAR_MODE = 0 ) + + INTEGER IP_RESTORATION_PHASE_MODE + PARAMETER( IP_RESTORATION_PHASE_MODE = 1 ) diff --git a/thirdparty/linux/include/coin/coin/IpReturnCodes_inc.h b/thirdparty/linux/include/coin/coin/IpReturnCodes_inc.h new file mode 100644 index 0000000..80190ed --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpReturnCodes_inc.h @@ -0,0 +1,46 @@ +/*********************************************************************** +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes_inc.h 2216 2013-04-14 17:06:00Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!! REMEMBER TO UPDATE IpReturnCodes.inc and Ipopt.java !!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +/** Return codes for the Optimize call for an application */ +enum ApplicationReturnStatus + { + Solve_Succeeded=0, + Solved_To_Acceptable_Level=1, + Infeasible_Problem_Detected=2, + Search_Direction_Becomes_Too_Small=3, + Diverging_Iterates=4, + User_Requested_Stop=5, + Feasible_Point_Found=6, + + Maximum_Iterations_Exceeded=-1, + Restoration_Failed=-2, + Error_In_Step_Computation=-3, + Maximum_CpuTime_Exceeded=-4, + Not_Enough_Degrees_Of_Freedom=-10, + Invalid_Problem_Definition=-11, + Invalid_Option=-12, + Invalid_Number_Detected=-13, + + Unrecoverable_Exception=-100, + NonIpopt_Exception_Thrown=-101, + Insufficient_Memory=-102, + Internal_Error=-199 + }; + +/** enum to indicate the mode in which the algorithm is */ +enum AlgorithmMode + { + RegularMode=0, + RestorationPhaseMode=1 + }; diff --git a/thirdparty/linux/include/coin/coin/IpScaledMatrix.hpp b/thirdparty/linux/include/coin/coin/IpScaledMatrix.hpp new file mode 100644 index 0000000..c182a05 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpScaledMatrix.hpp @@ -0,0 +1,254 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSCALEDMATRIX_HPP__ +#define __IPSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class ScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class ScaledMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ScaledMatrix(const ScaledMatrixSpace* owner_space); + + /** Destructor */ + ~ScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr<const Matrix> unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr<Matrix>& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr<const Matrix> GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr<Matrix> GetUnscaledMatrixNonConst(); + + /** return the vector for the row scaling */ + SmartPtr<const Vector> RowScaling() const; + + /** return the vector for the column scaling */ + SmartPtr<const Vector> ColumnScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed that the scaling factors are + * valid. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized + * implementation missing so far! + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation + * missing so far! + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ScaledMatrix(); + + /** Copy Constructor */ + ScaledMatrix(const ScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr<const Matrix> matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr<Matrix> nonconst_matrix_; + + /** Matrix space stored as a ScaledMatrixSpace */ + SmartPtr<const ScaledMatrixSpace> owner_space_; + }; + + /** This is the matrix space for ScaledMatrix. + */ + class ScaledMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + ScaledMatrixSpace(const SmartPtr<const Vector>& row_scaling, + bool row_scaling_reciprocal, + const SmartPtr<const MatrixSpace>& unscaled_matrix_space, + const SmartPtr<const Vector>& column_scaling, + bool column_scaling_reciprocal); + + /** Destructor */ + ~ScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + ScaledMatrix* MakeNewScaledMatrix(bool allocate_unscaled_matrix = false) const + { + ScaledMatrix* ret = new ScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr<Matrix> unscaled_matrix = unscaled_matrix_space_->MakeNew(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewScaledMatrix(); + } + + /** return the vector for the row scaling */ + SmartPtr<const Vector> RowScaling() const + { + return ConstPtr(row_scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr<const MatrixSpace> UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + /** return the vector for the column scaling */ + SmartPtr<const Vector> ColumnScaling() const + { + return ConstPtr(column_scaling_); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + ScaledMatrixSpace(); + + /** Copy Constructor */ + ScaledMatrixSpace(const ScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + ScaledMatrixSpace& operator=(const ScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr<Vector> row_scaling_; + /** unscaled matrix space */ + SmartPtr<const MatrixSpace> unscaled_matrix_space_; + /** column scaling vector */ + SmartPtr<Vector> column_scaling_; + }; + + inline + void ScaledMatrix::SetUnscaledMatrix(const SmartPtr<const Matrix> unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void ScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr<Matrix>& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr<const Matrix> ScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr<Matrix> ScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline + SmartPtr<const Vector> ScaledMatrix::RowScaling() const + { + return ConstPtr(owner_space_->RowScaling()); + } + + inline + SmartPtr<const Vector> ScaledMatrix::ColumnScaling() const + { + return ConstPtr(owner_space_->ColumnScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSearchDirCalculator.hpp b/thirdparty/linux/include/coin/coin/IpSearchDirCalculator.hpp new file mode 100644 index 0000000..3425c43 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSearchDirCalculator.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSearchDirCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-10-13 + +#ifndef __IPSEARCHDIRCALCULATOR_HPP__ +#define __IPSEARCHDIRCALCULATOR_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for computing the search direction for the line + * search. + */ + class SearchDirectionCalculator : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + SearchDirectionCalculator() + {} + + /** Default destructor */ + virtual ~SearchDirectionCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for computing the search direction. The + * computed direction is stored in IpData().delta().*/ + virtual bool ComputeSearchDirection()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // SearchDirectionCalculator(); + + /** Copy Constructor */ + SearchDirectionCalculator(const SearchDirectionCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const SearchDirectionCalculator&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSmartPtr.hpp b/thirdparty/linux/include/coin/coin/IpSmartPtr.hpp new file mode 100644 index 0000000..dec0ab5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSmartPtr.hpp @@ -0,0 +1,734 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSmartPtr.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSMARTPTR_HPP__ +#define __IPSMARTPTR_HPP__ + +#include "IpReferenced.hpp" + +#include "IpDebug.hpp" +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifndef IPOPT_UNUSED +# if defined(__GNUC__) +# define IPOPT_UNUSED __attribute__((unused)) +# else +# define IPOPT_UNUSED +# endif +#endif + +namespace Ipopt +{ + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template<class T> + class SmartPtr : public Referencer + { + public: +#define ipopt_dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr(); + + /** Copy constructor, initialized from copy of type T */ + SmartPtr(const SmartPtr<T>& copy); + + /** Copy constructor, initialized from copy of type U */ + template <class U> + SmartPtr(const SmartPtr<U>& copy); + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr); + + /** Destructor, automatically decrements the + * reference count, deletes the object if + * necessary.*/ + ~SmartPtr(); + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const; + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const; + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr<T>& operator=(T* rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr<T>& operator=(const SmartPtr<T>& rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr of a different type */ + template <class U> + SmartPtr<T>& operator=(const SmartPtr<U>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template <class U1, class U2> + friend + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded less-than comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U> + friend + bool operator<(const SmartPtr<U>& lhs, const SmartPtr<U>& rhs); + //@} + + /**@name friend method declarations. */ + //@{ + /** Returns the raw pointer contained. + * Use to get the value of + * the raw ptr (i.e. to pass to other + * methods/functions, etc.) + * Note: This method does NOT copy, + * therefore, modifications using this + * value modify the underlying object + * contained by the SmartPtr, + * NEVER delete this returned value. + */ + template <class U> + friend + U* GetRawPtr(const SmartPtr<U>& smart_ptr); + + /** Returns a const pointer */ + template <class U> + friend + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr); + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + template <class U> + friend + bool IsValid(const SmartPtr<U>& smart_ptr); + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + template <class U> + friend + bool IsNull(const SmartPtr<U>& smart_ptr); + //@} + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Set the value of the internal raw pointer + * from another raw pointer, releasing the + * previously referenced object if necessary. */ + SmartPtr<T>& SetFromRawPtr_(T* rhs); + + /** Set the value of the internal raw pointer + * from a SmartPtr, releasing the previously referenced + * object if necessary. */ + SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs); + + /** Release the currently referenced object. */ + void ReleasePointer_(); + //@} + }; + + /**@name SmartPtr friend function declarations.*/ + //@{ + template <class U> + U* GetRawPtr(const SmartPtr<U>& smart_ptr); + + template <class U> + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr); + + template <class U> + bool IsNull(const SmartPtr<U>& smart_ptr); + + template <class U> + bool IsValid(const SmartPtr<U>& smart_ptr); + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + template <class U1, class U2> + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + template <class U1, class U2> + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + + //@} + + + template <class T> + SmartPtr<T>::SmartPtr() + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr()", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + } + + + template <class T> + SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(copy); + } + + + template <class T> + template <class U> + SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(GetRawPtr(copy)); + } + + + template <class T> + SmartPtr<T>::SmartPtr(T* ptr) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromRawPtr_(ptr); + } + + template <class T> + SmartPtr<T>::~SmartPtr() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + + ReleasePointer_(); + } + + + template <class T> + T* SmartPtr<T>::operator->() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T* SmartPtr<T>::operator->()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot deref a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return ptr_; + } + + + template <class T> + T& SmartPtr<T>::operator*() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T& SmartPtr<T>::operator*()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot dereference a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return *ptr_; + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::operator=(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromRawPtr_(rhs); + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(rhs); + } + + + template <class T> + template <class U> + SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(GetRawPtr(rhs)); + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + if (rhs != 0) + rhs->AddRef(this); + + // Release any old pointer + ReleasePointer_(); + + ptr_ = rhs; + + return *this; + } + + template <class T> + SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + SetFromRawPtr_(GetRawPtr(rhs)); + + return (*this); + } + + + template <class T> + void SmartPtr<T>::ReleasePointer_() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "void SmartPtr<T>::ReleasePointer()", + ipopt_dbg_smartptr_verbosity); +#endif + + if (ptr_) { + ptr_->ReleaseRef(this); + if (ptr_->ReferenceCount() == 0) + delete ptr_; + } + } + + + template <class U> + U* GetRawPtr(const SmartPtr<U>& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "T* GetRawPtr(const SmartPtr<T>& smart_ptr)", + 0); +#endif + + return smart_ptr.ptr_; + } + + template <class U> + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr) + { + // compiler should implicitly cast + return GetRawPtr(smart_ptr); + } + + template <class U> + bool IsValid(const SmartPtr<U>& smart_ptr) + { + return !IsNull(smart_ptr); + } + + template <class U> + bool IsNull(const SmartPtr<U>& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool IsNull(const SmartPtr<T>& smart_ptr)", + 0); +#endif + + return (smart_ptr.ptr_ == 0); + } + + + template <class U1, class U2> + bool ComparePointers(const U1* lhs, const U2* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool ComparePtrs(const U1* lhs, const U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + // Even if lhs and rhs point to the same object + // with different interfaces U1 and U2, we cannot guarantee that + // the value of the pointers will be equivalent. We can + // guarantee this if we convert to ReferencedObject* (see also #162) + const ReferencedObject* v_lhs = lhs; + const ReferencedObject* v_rhs = rhs; + + return v_lhs == v_rhs; + } + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(SmartPtr<U1>& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + const U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, rhs); + return !retValue; + } + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, raw_rhs); + return !retValue; + } + + template <class U1, class U2> + bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(raw_lhs, rhs); + return !retValue; + } + + template <class T> + void swap(SmartPtr<T>& a, SmartPtr<T>& b) + { +#ifdef IP_DEBUG_REFERENCED + SmartPtr<T> tmp(a); + a = b; + b = tmp; +#else + std::swap(a.prt_, b.ptr_); +#endif + } + + template <class T> + bool operator<(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return lhs.ptr_ < rhs.ptr_; + } + + template <class T> + bool operator> (const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return rhs < lhs; + } + + template <class T> bool + operator<=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return !( rhs < lhs ); + } + + template <class T> bool + operator>=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return !( lhs < rhs ); + } +} // namespace Ipopt + +#undef ipopt_dbg_smartptr_verbosity + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSolveStatistics.hpp b/thirdparty/linux/include/coin/coin/IpSolveStatistics.hpp new file mode 100644 index 0000000..625ddfb --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSolveStatistics.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSolveStatistics.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-08-15 + +#ifndef __IPSOLVESTATISTICS_HPP__ +#define __IPSOLVESTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +namespace Ipopt +{ + // forward declaration (to avoid inclusion of too many header files) + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + + /** This class collects statistics about an optimziation run, such + * as iteration count, final infeasibilities etc. It is meant to + * provide such information to a user of Ipopt during the + * finalize_solution call. + */ + class SolveStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. It takes in those collecting Ipopt + * objects that can provide the statistics information. Those + * statistics are retrieved at the time of the constructor + * call. */ + SolveStatistics(const SmartPtr<IpoptNLP>& ip_nlp, + const SmartPtr<IpoptData>& ip_data, + const SmartPtr<IpoptCalculatedQuantities>& ip_cq); + + /** Default destructor */ + virtual ~SolveStatistics() + {} + //@} + + /** @name Accessor methods for retrieving different kind of solver + * statistics information */ + //@{ + /** Iteration counts. */ + virtual Index IterationCount() const; + /** Total CPU time, including function evaluations. */ + virtual Number TotalCpuTime() const; + /** Total CPU time, including function evaluations. Included for + * backward compatibility. */ + Number TotalCPUTime() const + { + return TotalCpuTime(); + } + /** Total System time, including function evaluations. */ + virtual Number TotalSysTime() const; + /** Total wall clock time, including function evaluations. */ + virtual Number TotalWallclockTime() const; + /** Number of NLP function evaluations. */ + virtual void NumberOfEvaluations(Index& num_obj_evals, + Index& num_constr_evals, + Index& num_obj_grad_evals, + Index& num_constr_jac_evals, + Index& num_hess_evals) const; + /** Unscaled solution infeasibilities */ + virtual void Infeasibilities(Number& dual_inf, + Number& constr_viol, + Number& complementarity, + Number& kkt_error) const; + /** Scaled solution infeasibilities */ + virtual void ScaledInfeasibilities(Number& scaled_dual_inf, + Number& scaled_constr_viol, + Number& scaled_complementarity, + Number& scaled_kkt_error) const; + /** Final value of objective function */ + virtual Number FinalObjective() const; + /** Final scaled value of objective function */ + virtual Number FinalScaledObjective() const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SolveStatistics(); + + /** Copy Constructor */ + SolveStatistics(const SolveStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const SolveStatistics&); + //@} + + /** @name Fields for storing the statistics data */ + //@{ + /** Number of iterations. */ + Index num_iters_; + /* Total CPU time */ + Number total_cpu_time_; + /* Total system time */ + Number total_sys_time_; + /* Total wall clock time */ + Number total_wallclock_time_; + /** Number of objective function evaluations. */ + Index num_obj_evals_; + /** Number of constraints evaluations (max of equality and + * inequality) */ + Index num_constr_evals_; + /** Number of objective gradient evaluations. */ + Index num_obj_grad_evals_; + /** Number of constraint Jacobian evaluations. */ + Index num_constr_jac_evals_; + /** Number of Lagrangian Hessian evaluations. */ + Index num_hess_evals_; + + /** Final scaled value of objective function */ + Number scaled_obj_val_; + /** Final unscaled value of objective function */ + Number obj_val_; + /** Final scaled dual infeasibility (max-norm) */ + Number scaled_dual_inf_; + /** Final unscaled dual infeasibility (max-norm) */ + Number dual_inf_; + /** Final scaled constraint violation (max-norm) */ + Number scaled_constr_viol_; + /** Final unscaled constraint violation (max-norm) */ + Number constr_viol_; + /** Final scaled complementarity error (max-norm) */ + Number scaled_compl_; + /** Final unscaled complementarity error (max-norm) */ + Number compl_; + /** Final overall scaled KKT error (max-norm) */ + Number scaled_kkt_error_; + /** Final overall unscaled KKT error (max-norm) */ + Number kkt_error_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpStdCInterface.h b/thirdparty/linux/include/coin/coin/IpStdCInterface.h new file mode 100644 index 0000000..4f11336 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpStdCInterface.h @@ -0,0 +1,271 @@ +/************************************************************************* + Copyright (C) 2004, 2010 International Business Machines and others. + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: IpStdCInterface.h 2082 2012-02-16 03:00:34Z andreasw $ + + Authors: Carl Laird, Andreas Waechter IBM 2004-09-02 + *************************************************************************/ + +#ifndef __IPSTDCINTERFACE_H__ +#define __IPSTDCINTERFACE_H__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type for all number. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef double Number; + + /** Type for all incides. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Index; + + /** Type for all integers. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Int; + + /* This includes the SolverReturn enum type */ +#include "IpReturnCodes.h" + + /** Structure collecting all information about the problem + * definition and solve statistics etc. This is defined in the + * source file. */ + struct IpoptProblemInfo; + + /** Pointer to a Ipopt Problem. */ + typedef struct IpoptProblemInfo* IpoptProblem; + + /** define a boolean type for C */ + typedef int Bool; +#ifndef TRUE +# define TRUE (1) +#endif +#ifndef FALSE +# define FALSE (0) +#endif + + /** A pointer for anything that is to be passed between the called + * and individual callback function */ + typedef void * UserDataPtr; + + /** Type defining the callback function for evaluating the value of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_F_CB)(Index n, Number* x, Bool new_x, + Number* obj_value, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the gradient of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Grad_F_CB)(Index n, Number* x, Bool new_x, + Number* grad_f, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the value of + * the constraint functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_G_CB)(Index n, Number* x, Bool new_x, + Index m, Number* g, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Jacobian of + * the constrant functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Jac_G_CB)(Index n, Number *x, Bool new_x, + Index m, Index nele_jac, + Index *iRow, Index *jCol, Number *values, + UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Hessian of + * the Lagrangian function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_H_CB)(Index n, Number *x, Bool new_x, Number obj_factor, + Index m, Number *lambda, Bool new_lambda, + Index nele_hess, Index *iRow, Index *jCol, + Number *values, UserDataPtr user_data); + + /** Type defining the callback function for giving intermediate + * execution control to the user. If set, it is called once per + * iteration, providing the user with some information on the state + * of the optimization. This can be used to print some + * user-defined output. It also gives the user a way to terminate + * the optimization prematurely. If this method returns false, + * Ipopt will terminate the optimization. */ + typedef Bool (*Intermediate_CB)(Index alg_mod, /* 0 is regular, 1 is resto */ + Index iter_count, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, UserDataPtr user_data); + + /** Function for creating a new Ipopt Problem object. This function + * returns an object that can be passed to the IpoptSolve call. It + * contains the basic definition of the optimization problem, such + * as number of variables and constraints, bounds on variables and + * constraints, information about the derivatives, and the callback + * function for the computation of the optimization problem + * functions and derivatives. During this call, the options file + * PARAMS.DAT is read as well. + * + * If NULL is returned, there was a problem with one of the inputs + * or reading the options file. */ + IPOPT_EXPORT(IpoptProblem) CreateIpoptProblem( + Index n /** Number of optimization variables */ + , Number* x_L /** Lower bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* x_U /** Upper bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index m /** Number of constraints. */ + , Number* g_L /** Lower bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* g_U /** Upper bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index nele_jac /** Number of non-zero elements in constraint + Jacobian. */ + , Index nele_hess /** Number of non-zero elements in Hessian of + Lagrangian. */ + , Index index_style /** indexing style for iRow & jCol, + 0 for C style, 1 for Fortran style */ + , Eval_F_CB eval_f /** Callback function for evaluating + objective function */ + , Eval_G_CB eval_g /** Callback function for evaluating + constraint functions */ + , Eval_Grad_F_CB eval_grad_f + /** Callback function for evaluating gradient + of objective function */ + , Eval_Jac_G_CB eval_jac_g + /** Callback function for evaluating Jacobian + of constraint functions */ + , Eval_H_CB eval_h /** Callback function for evaluating Hessian + of Lagrangian function */ + ); + + /** Method for freeing a previously created IpoptProblem. After + freeing an IpoptProblem, it cannot be used anymore. */ + IPOPT_EXPORT(void) FreeIpoptProblem(IpoptProblem ipopt_problem); + + + /** Function for adding a string option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptStrOption(IpoptProblem ipopt_problem, char* keyword, char* val); + + /** Function for adding a Number option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptNumOption(IpoptProblem ipopt_problem, char* keyword, Number val); + + /** Function for adding an Int option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptIntOption(IpoptProblem ipopt_problem, char* keyword, Int val); + + /** Function for opening an output file for a given name with given + * printlevel. Returns false, if there was a problem opening the + * file. */ + IPOPT_EXPORT(Bool) OpenIpoptOutputFile(IpoptProblem ipopt_problem, char* file_name, + Int print_level); + + /** Optional function for setting scaling parameter for the NLP. + * This corresponds to the get_scaling_parameters method in TNLP. + * If the pointers x_scaling or g_scaling are NULL, then no scaling + * for x resp. g is done. */ + IPOPT_EXPORT(Bool) SetIpoptProblemScaling(IpoptProblem ipopt_problem, + Number obj_scaling, + Number* x_scaling, + Number* g_scaling); + + /** Setting a callback function for the "intermediate callback" + * method in the TNLP. This gives control back to the user once + * per iteration. If set, it provides the user with some + * information on the state of the optimization. This can be used + * to print some user-defined output. It also gives the user a way + * to terminate the optimization prematurely. If the callback + * method returns false, Ipopt will terminate the optimization. + * Calling this set method to set the CB pointer to NULL disables + * the intermediate callback functionality. */ + IPOPT_EXPORT(Bool) SetIntermediateCallback(IpoptProblem ipopt_problem, + Intermediate_CB intermediate_cb); + + /** Function calling the Ipopt optimization algorithm for a problem + previously defined with CreateIpoptProblem. The return + specified outcome of the optimization procedure (e.g., success, + failure etc). + */ + IPOPT_EXPORT(enum ApplicationReturnStatus) IpoptSolve( + IpoptProblem ipopt_problem + /** Problem that is to be optimized. Ipopt + will use the options previously specified with + AddIpoptOption (etc) for this problem. */ + , Number* x /** Input: Starting point + Output: Optimal solution */ + , Number* g /** Values of constraint at final point + (output only - ignored if set to NULL) */ + , Number* obj_val /** Final value of objective function + (output only - ignored if set to NULL) */ + , Number* mult_g /** Input: Initial values for the constraint + multipliers (only if warm start option + is chosen) + Output: Final multipliers for constraints + (ignored if set to NULL) */ + , Number* mult_x_L /** Input: Initial values for the multipliers for + lower variable bounds (only if warm start + option is chosen) + Output: Final multipliers for lower variable + bounds (ignored if set to NULL) */ + , Number* mult_x_U /** Input: Initial values for the multipliers for + upper variable bounds (only if warm start + option is chosen) + Output: Final multipliers for upper variable + bounds (ignored if set to NULL) */ + , UserDataPtr user_data + /** Pointer to user data. This will be + passed unmodified to the callback + functions. */ + ); + + /** + void IpoptStatisticsCounts; + + void IpoptStatisticsInfeasibilities; */ +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSumSymMatrix.hpp b/thirdparty/linux/include/coin/coin/IpSumSymMatrix.hpp new file mode 100644 index 0000000..42b1168 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSumSymMatrix.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSumSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSUMSYMMATRIX_HPP__ +#define __IPSUMSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SumSymMatrixSpace; + + /** Class for Matrices which are sum of symmetric matrices. + * For each term in the we store the matrix and a factor. + */ + class SumSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix and + * the number of terms in the sum. + */ + SumSymMatrix(const SumSymMatrixSpace* owner_space); + + /** Destructor */ + ~SumSymMatrix(); + //@} + + /** Method for setting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void SetTerm(Index iterm, Number factor, const SymMatrix& matrix); + + /** Method for getting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void GetTerm(Index iterm, Number& factor, SmartPtr<const SymMatrix>& matrix) const; + + /** Return the number of terms */ + Index NTerms() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SumSymMatrix(); + + /** Copy Constructor */ + SumSymMatrix(const SumSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SumSymMatrix&); + //@} + + /** std::vector storing the factors for each term. */ + std::vector<Number> factors_; + + /** std::vector storing the matrices for each term. */ + std::vector<SmartPtr<const SymMatrix> > matrices_; + + /** Copy of the owner_space as a SumSymMatrixSpace */ + const SumSymMatrixSpace* owner_space_; + }; + + /** Class for matrix space for SumSymMatrix */ + class SumSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix and the number + * of terms in the sum. */ + SumSymMatrixSpace(Index ndim, Index nterms) + : + SymMatrixSpace(ndim), + nterms_(nterms) + {} + + /** Destructor */ + ~SumSymMatrixSpace() + {} + //@} + + /** @name Accessor functions */ + //@{ + /** Number of terms in the sum. */ + Index NTerms() const + { + return nterms_; + } + //@} + + /** Use this method to set the matrix spaces for the various terms. + * You will not be able to create a matrix until all these spaces + * are set. */ + void SetTermSpace(Index term_idx, const SymMatrixSpace& space); + + /** Get the matix space for a particular term */ + SmartPtr<const SymMatrixSpace> GetTermSpace(Index term_idx) const; + + /** Method for creating a new matrix of this specific type. */ + SumSymMatrix* MakeNewSumSymMatrix() const; + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const; + + private: + Index nterms_; + + std::vector< SmartPtr<const SymMatrixSpace> > term_spaces_; + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSymLinearSolver.hpp b/thirdparty/linux/include/coin/coin/IpSymLinearSolver.hpp new file mode 100644 index 0000000..82e7dd4 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSymLinearSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymLinearSolver.hpp 2322 2013-06-12 17:45:57Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMLINEARSOLVER_HPP__ +#define __IPSYMLINEARSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include <vector> + +namespace Ipopt +{ + + /** Enum to report outcome of a linear solve */ + enum ESymSolverStatus { + /** Successful solve */ + SYMSOLVER_SUCCESS, + /** Matrix seems to be singular; solve was aborted */ + SYMSOLVER_SINGULAR, + /** The number of negative eigenvalues is not correct */ + SYMSOLVER_WRONG_INERTIA, + /** Call the solver interface again after the matrix values have + * been restored */ + SYMSOLVER_CALL_AGAIN, + /** Unrecoverable error in linear solver occurred. The + * optimization will be aborted. */ + SYMSOLVER_FATAL_ERROR + }; + + /** Base class for all derived symmetric linear + * solvers. In the full space version of Ipopt a large linear + * system has to be solved for the augmented system. This case is + * meant to be the base class for all derived linear solvers for + * symmetric matrices (of type SymMatrix). + * + * A linear solver can be used repeatedly for matrices with + * identical structure of nonzero elements. The nonzero structure + * of those matrices must not be changed between calls. + * + * The called might ask the solver to only solve the linear system + * if the system is nonsingular, and if the number of negative + * eigenvalues matches a given number. + */ + class SymLinearSolver: public AlgorithmStrategyObject + { + public: + /** @name Constructor/Destructor */ + //@{ + SymLinearSolver() + {} + + virtual ~SymLinearSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** @name Methods for requesting solution of the linear system. */ + //@{ + /** Solve operation for multiple right hand sides. Solves the + * linear system A * Sol = Rhs with multiple right hand sides. If + * necessary, A is factorized. Correct solutions are only + * guaranteed if the return values is SYMSOLVER_SUCCESS. The + * solver will return SYMSOLVER_SINGULAR if the linear system is + * singular, and it will return SYMSOLVER_WRONG_INERTIA if + * check_NegEVals is true and the number of negative eigenvalues + * in the matrix does not match numberOfNegEVals. + * + * check_NegEVals cannot be chosen true, if ProvidesInertia() + * returns false. + */ + virtual ESymSolverStatus MultiSolve(const SymMatrix &A, + std::vector<SmartPtr<const Vector> >& rhsV, + std::vector<SmartPtr<Vector> >& solV, + bool check_NegEVals, + Index numberOfNegEVals)=0; + + /** Solve operation for a single right hand side. Solves the + * linear system A * Sol = Rhs. See MultiSolve for more + * details. */ + ESymSolverStatus Solve(const SymMatrix &A, + const Vector& rhs, Vector& sol, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector<SmartPtr<const Vector> > rhsV(1); + rhsV[0] = &rhs; + std::vector<SmartPtr<Vector> > solV(1); + solV[0] = / + return MultiSolve(A, rhsV, solV, check_NegEVals, + numberOfNegEVals); + } + + /** Number of negative eigenvalues detected during last + * factorization. Returns the number of negative eigenvalues of + * the most recent factorized matrix. This must not be called if + * the linear solver does not compute this quantities (see + * ProvidesInertia). + */ + virtual Index NumberOfNegEVals() const =0; + //@} + + //* @name Options of Linear solver */ + //@{ + /** Request to increase quality of solution for next solve. + * Ask linear solver to increase quality of solution for the next + * solve (e.g. increase pivot tolerance). Returns false, if this + * is not possible (e.g. maximal pivot tolerance already used.) + */ + virtual bool IncreaseQuality() =0; + + /** Query whether inertia is computed by linear solver. + * Returns true, if linear solver provides inertia. + */ + virtual bool ProvidesInertia() const =0; + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSymMatrix.hpp b/thirdparty/linux/include/coin/coin/IpSymMatrix.hpp new file mode 100644 index 0000000..4a0137b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSymMatrix.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMMATRIX_HPP__ +#define __IPSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymMatrixSpace; + + /** This is the base class for all derived symmetric matrix types. + */ + class SymMatrix : public Matrix + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor, taking the owner_space. + */ + inline + SymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + virtual ~SymMatrix() + {} + //@} + + /** @name Information about the size of the matrix */ + //@{ + /** Dimension of the matrix (number of rows and columns) */ + inline + Index Dim() const; + //@} + + inline + SmartPtr<const SymMatrixSpace> OwnerSymMatrixSpace() const; + + protected: + /** @name Overloaded methods from Matrix. */ + //@{ + /** Since the matrix is + * symmetric, it is only necessary to implement the + * MultVectorImpl method in a class that inherits from this base + * class. If the TransMultVectorImpl is called, this base class + * automatically calls MultVectorImpl instead. */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + // Since this matrix is symetric, this is the same operation as + // MultVector + MultVector(alpha, x, beta, y); + } + /** Since the matrix is symmetric, the row and column max norms + * are identical */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + { + ComputeRowAMaxImpl(cols_norms, init); + } + //@} + + private: + /** Copy of the owner space ptr as a SymMatrixSpace instead + * of a MatrixSpace + */ + const SymMatrixSpace* owner_space_; + }; + + + /** SymMatrixSpace base class, corresponding to the SymMatrix base + * class. */ + class SymMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension (identical to the number of + * rows and columns). + */ + SymMatrixSpace(Index dim) + : + MatrixSpace(dim,dim) + {} + + /** Destructor */ + virtual ~SymMatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new matrix of this specific + * type. */ + virtual SymMatrix* MakeNewSymMatrix() const=0; + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymMatrix(); + } + + /** Accessor method for the dimension of the matrices in this + * matrix space. + */ + Index Dim() const + { + DBG_ASSERT(NRows() == NCols()); + return NRows(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + SymMatrixSpace(); + + /* Copy constructor */ + SymMatrixSpace(const SymMatrixSpace&); + + /** Overloaded Equals Operator */ + SymMatrixSpace& operator=(const SymMatrixSpace&); + //@} + + }; + + /* inline methods */ + inline + SymMatrix::SymMatrix(const SymMatrixSpace* owner_space) + : + Matrix(owner_space), + owner_space_(owner_space) + {} + + inline + Index SymMatrix::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr<const SymMatrixSpace> SymMatrix::OwnerSymMatrixSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSymScaledMatrix.hpp b/thirdparty/linux/include/coin/coin/IpSymScaledMatrix.hpp new file mode 100644 index 0000000..d58742f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSymScaledMatrix.hpp @@ -0,0 +1,230 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMSCALEDMATRIX_HPP__ +#define __IPSYMSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class SymScaledMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + SymScaledMatrix(const SymScaledMatrixSpace* owner_space); + + /** Destructor */ + ~SymScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr<const SymMatrix> unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr<SymMatrix>& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr<const SymMatrix> GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr<SymMatrix> GetUnscaledMatrixNonConst(); + + /** return the vector for the row and column scaling */ + SmartPtr<const Vector> RowColScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed here that the scaling factors + * are always valid numbers. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymScaledMatrix(); + + /** Copy Constructor */ + SymScaledMatrix(const SymScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr<const SymMatrix> matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr<SymMatrix> nonconst_matrix_; + + /** Matrix space stored as a SymScaledMatrixSpace */ + SmartPtr<const SymScaledMatrixSpace> owner_space_; + }; + + /** This is the matrix space for SymScaledMatrix. + */ + class SymScaledMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + SymScaledMatrixSpace(const SmartPtr<const Vector>& row_col_scaling, + bool row_col_scaling_reciprocal, + const SmartPtr<const SymMatrixSpace>& unscaled_matrix_space) + : + SymMatrixSpace(unscaled_matrix_space->Dim()), + unscaled_matrix_space_(unscaled_matrix_space) + { + scaling_ = row_col_scaling->MakeNewCopy(); + if (row_col_scaling_reciprocal) { + scaling_->ElementWiseReciprocal(); + } + } + + /** Destructor */ + ~SymScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + SymScaledMatrix* MakeNewSymScaledMatrix(bool allocate_unscaled_matrix = false) const + { + SymScaledMatrix* ret = new SymScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr<SymMatrix> unscaled_matrix = unscaled_matrix_space_->MakeNewSymMatrix(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded method from SymMatrixSpace */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymScaledMatrix(); + } + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymScaledMatrix(); + } + + /** return the vector for the row and column scaling */ + SmartPtr<const Vector> RowColScaling() const + { + return ConstPtr(scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr<const SymMatrixSpace> UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + SymScaledMatrixSpace(); + + /** Copy Constructor */ + SymScaledMatrixSpace(const SymScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + SymScaledMatrixSpace& operator=(const SymScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr<Vector> scaling_; + /** unscaled matrix space */ + SmartPtr<const SymMatrixSpace> unscaled_matrix_space_; + }; + + inline + void SymScaledMatrix::SetUnscaledMatrix(const SmartPtr<const SymMatrix> unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void SymScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr<SymMatrix>& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr<const SymMatrix> SymScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr<SymMatrix> SymScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline SmartPtr<const Vector> SymScaledMatrix::RowColScaling() const + { + return ConstPtr(owner_space_->RowColScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpSymTMatrix.hpp b/thirdparty/linux/include/coin/coin/IpSymTMatrix.hpp new file mode 100644 index 0000000..ead2d85 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpSymTMatrix.hpp @@ -0,0 +1,253 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMTMATRIX_HPP__ +#define __IPSYMTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymTMatrixSpace; + + /** Class for symmetric matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a symmetric matrix is + * stored in three arrays, Irn, Jcn, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (as the row and column indices), and the last + * array stores the value at that location. Off-diagonal elements + * need to be stored only once since the matrix is symmetric. For + * example, the element \f$a_{1,2}=a_{2,1}\f$ would be stored only + * once, either with Irn[i]=1 and Jcn[i]=2, or with Irn[i]=2 and + * Jcn[i]=1. Both representations are identical. If nonzero + * elements (or their symmetric counter part) are listed more than + * once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irn and Jcn) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + * + */ + class SymTMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + SymTMatrix(const SymTMatrixSpace* owner_space); + + /** Destructor */ + ~SymTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements is copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to the matrix + * space. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Obtain pointer to the internal Index array irn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Irows() const; + + /** Obtain pointer to the internal Index array jcn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Jcols() const; + + /** Obtain pointer to the internal Number array values_ with the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + Number* Values(); + /** Obtain pointer to the internal Number array values_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Number* Values() const; + //@} + + /**@name Methods for providing copy of the matrix data */ + //@{ + /** Copy the nonzero structure into provided space */ + void FillStruct(ipfint* Irn, ipfint* Jcn) const; + + /** Copy the value data into provided space */ + void FillValues(Number* Values) const; + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymTMatrix(); + + /** Copy Constructor */ + SymTMatrix(const SymTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymTMatrix&); + //@} + + /** Copy of the owner_space ptr as a SymTMatrixSpace insteaqd + * of a MatrixSpace + */ + const SymTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a SymTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class SymTMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns (both as + * dim), as well as the number of nonzeros and the position of + * the nonzero elements. Note that the counting of the nonzeros + * starts a 1, i.e., iRows[i]==1 and jCols[i]==1 refers to the + * first element in the first row. This is in accordance with + * the HSL data structure. Off-diagonal elements are stored only + * once. + */ + SymTMatrixSpace(Index dim, Index nonZeros, const Index* iRows, + const Index* jCols); + + /** Destructor */ + ~SymTMatrixSpace(); + //@} + + /** Overloaded MakeNew method for the sYMMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymTMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + SymTMatrix* MakeNewSymTMatrix() const + { + return new SymTMatrix(this); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /**@name Methods called by SymTMatrix for memory management */ + //@{ + /** Allocate internal storage for the SymTMatrix values */ + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the SymTMatrix values */ + void FreeInternalStorage(Number* values) const; + //@} + + const Index nonZeros_; + Index* iRows_; + Index* jCols_; + + friend class SymTMatrix; + }; + + /* Inline Methods */ + inline + Index SymTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* SymTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* SymTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTNLP.hpp b/thirdparty/linux/include/coin/coin/IpTNLP.hpp new file mode 100644 index 0000000..998d38e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTNLP.hpp @@ -0,0 +1,301 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLP.hpp 2212 2013-04-14 14:51:52Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLP_HPP__ +#define __IPTNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +#include <map> + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Base class for all NLP's that use standard triplet matrix form + * and dense vectors. This is the standard base class for all + * NLP's that use the standard triplet matrix form (as for Harwell + * routines) and dense vectors. The class TNLPAdapter then converts + * this interface to an interface that can be used directly by + * ipopt. + * + * This interface presents the problem form: + * + * min f(x) + * + * s.t. gL <= g(x) <= gU + * + * xL <= x <= xU + * + * In order to specify an equality constraint, set gL_i = gU_i = + * rhs. The value that indicates "infinity" for the bounds + * (i.e. the variable or constraint has no lower bound (-infinity) + * or upper bound (+infinity)) is set through the option + * nlp_lower_bound_inf and nlp_upper_bound_inf. To indicate that a + * variable has no upper or lower bound, set the bound to + * -ipopt_inf or +ipopt_inf respectively + */ + class TNLP : public ReferencedObject + { + public: + /** Type of the constraints*/ + enum LinearityType + { + LINEAR/** Constraint/Variable is linear.*/, + NON_LINEAR/**Constraint/Varaible is non-linear.*/ + }; + + /**@name Constructors/Destructors */ + //@{ + TNLP() + {} + + /** Default destructor */ + virtual ~TNLP() + {} + //@} + + DECLARE_STD_EXCEPTION(INVALID_TNLP); + + /**@name methods to gather information about the NLP */ + //@{ + /** overload this method to return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. The index_style parameter lets you specify C or Fortran + * style indexing for the sparse matrix iRow and jCol parameters. + * C_STYLE is 0-based, and FORTRAN_STYLE is 1-based. + */ + enum IndexStyleEnum { C_STYLE=0, FORTRAN_STYLE=1 }; + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style)=0; + + typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType; + typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType; + typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType; + + /** overload this method to return any meta data for + * the variables and the constraints */ + virtual bool get_var_con_metadata(Index n, + StringMetaDataMapType& var_string_md, + IntegerMetaDataMapType& var_integer_md, + NumericMetaDataMapType& var_numeric_md, + Index m, + StringMetaDataMapType& con_string_md, + IntegerMetaDataMapType& con_integer_md, + NumericMetaDataMapType& con_numeric_md) + + { + return false; + } + + /** overload this method to return the information about the bound + * on the variables and constraints. The value that indicates + * that a bound does not exist is specified in the parameters + * nlp_lower_bound_inf and nlp_upper_bound_inf. By default, + * nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is + * 1e19. (see TNLPAdapter) */ + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u)=0; + + /** overload this method to return scaling parameters. This is + * only called if the options are set to retrieve user scaling. + * There, use_x_scaling (or use_g_scaling) should get set to true + * only if the variables (or constraints) are to be scaled. This + * method should return true only if the scaling parameters could + * be provided. + */ + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling) + { + return false; + } + + /** overload this method to return the variables linearity + * (TNLP::LINEAR or TNLP::NON_LINEAR). The var_types + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_variables_linearity(Index n, LinearityType* var_types) + { + return false; + } + + /** overload this method to return the constraint linearity. + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_constraints_linearity(Index m, LinearityType* const_types) + { + return false; + } + + /** overload this method to return the starting point. The bool + * variables indicate whether the algorithm wants you to + * initialize x, z_L/z_u, and lambda, respectively. If, for some + * reason, the algorithm wants you to initialize these and you + * cannot, return false, which will cause Ipopt to stop. You + * will have to run Ipopt with different options then. + */ + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda)=0; + + /** overload this method to provide an Ipopt iterate (already in + * the form Ipopt requires it internally) for a warm start. + * Since this is only for expert users, a default dummy + * implementation is provided and returns false. */ + virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate) + { + return false; + } + + /** overload this method to return the value of the objective function */ + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value)=0; + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f)=0; + + /** overload this method to return the vector of constraint values */ + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g)=0; + /** overload this method to return the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values)=0; + + /** overload this method to return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only. A default implementation is provided, in case the user + * wants to se quasi-Newton approximations to estimate the second + * derivatives and doesn't not neet to implement this method. */ + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, + Index* iRow, Index* jCol, Number* values) + { + return false; + } + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq)=0; + /** This method is called just before finalize_solution. With + * this method, the algorithm returns any metadata collected + * during its run, including the metadata provided by the user + * with the above get_var_con_metadata. Each metadata can be of + * type string, integer, and numeric. It can be associated to + * either the variables or the constraints. The metadata that + * was associated with the primal variable vector is stored in + * var_..._md. The metadata associated with the constraint + * multipliers is stored in con_..._md. The metadata associated + * with the bound multipliers is stored in var_..._md, with the + * suffixes "_z_L", and "_z_U", denoting lower and upper + * bounds. */ + virtual void finalize_metadata(Index n, + const StringMetaDataMapType& var_string_md, + const IntegerMetaDataMapType& var_integer_md, + const NumericMetaDataMapType& var_numeric_md, + Index m, + const StringMetaDataMapType& con_string_md, + const IntegerMetaDataMapType& con_integer_md, + const NumericMetaDataMapType& con_numeric_md) + {} + + + /** Intermediate Callback method for the user. Providing dummy + * default implementation. For details see IntermediateCallBack + * in IpNLP.hpp. */ + virtual bool intermediate_callback(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + { + return true; + } + //@} + + /** @name Methods for quasi-Newton approximation. If the second + * derivatives are approximated by Ipopt, it is better to do this + * only in the space of nonlinear variables. The following + * methods are call by Ipopt if the quasi-Newton approximation is + * selected. If -1 is returned as number of nonlinear variables, + * Ipopt assumes that all variables are nonlinear. Otherwise, it + * calls get_list_of_nonlinear_variables with an array into which + * the indices of the nonlinear variables should be written - the + * array has the lengths num_nonlin_vars, which is identical with + * the return value of get_number_of_nonlinear_variables(). It + * is assumed that the indices are counted starting with 1 in the + * FORTRAN_STYLE, and 0 for the C_STYLE. */ + //@{ + virtual Index get_number_of_nonlinear_variables() + { + return -1; + } + + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars) + { + return false; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //TNLP(); + + /** Copy Constructor */ + TNLP(const TNLP&); + + /** Overloaded Equals Operator */ + void operator=(const TNLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTNLPAdapter.hpp b/thirdparty/linux/include/coin/coin/IpTNLPAdapter.hpp new file mode 100644 index 0000000..6eea8e3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTNLPAdapter.hpp @@ -0,0 +1,427 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPAdapter.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLPADAPTER_HPP__ +#define __IPTNLPADAPTER_HPP__ + +#include "IpNLP.hpp" +#include "IpTNLP.hpp" +#include "IpOrigIpoptNLP.hpp" +#include <list> + +namespace Ipopt +{ + + // forward declarations + class ExpansionMatrix; + class ExpansionMatrixSpace; + class IteratesVector; + class TDependencyDetector; + + /** This class Adapts the TNLP interface so it looks like an NLP interface. + * This is an Adapter class (Design Patterns) that converts a TNLP to an + * NLP. This allows users to write to the "more convenient" TNLP interface. + */ + class TNLPAdapter : public NLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + TNLPAdapter(const SmartPtr<TNLP> tnlp, + const SmartPtr<const Journalist> jnlst = NULL); + + /** Default destructor */ + virtual ~TNLPAdapter(); + //@} + + /**@name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(INVALID_TNLP); + DECLARE_STD_EXCEPTION(ERROR_IN_TNLP_DERIVATIVE_TEST); + //@} + + /** @name TNLPAdapter Initialization. */ + //@{ + virtual bool ProcessOptions(const OptionsList& options, + const std::string& prefix); + + /** Method for creating the derived vector / matrix types + * (Do not delete these, the ). */ + virtual bool GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space); + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& Px_L, + Vector& x_L, + const Matrix& Px_U, + Vector& x_U, + const Matrix& Pd_L, + Vector& d_L, + const Matrix& Pd_U, + Vector& d_U); + + /** Method for obtaining the starting point + * for all the iterates. */ + virtual bool GetStartingPoint( + SmartPtr<Vector> x, + bool need_x, + SmartPtr<Vector> y_c, + bool need_y_c, + SmartPtr<Vector> y_d, + bool need_y_d, + SmartPtr<Vector> z_L, + bool need_z_L, + SmartPtr<Vector> z_U, + bool need_z_U + ); + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate); + //@} + + /** @name TNLPAdapter evaluation routines. */ + //@{ + virtual bool Eval_f(const Vector& x, Number& f); + + virtual bool Eval_grad_f(const Vector& x, Vector& g_f); + + virtual bool Eval_c(const Vector& x, Vector& c); + + virtual bool Eval_jac_c(const Vector& x, Matrix& jac_c); + + virtual bool Eval_d(const Vector& x, Vector& d); + + virtual bool Eval_jac_d(const Vector& x, Matrix& jac_d); + + virtual bool Eval_h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + SymMatrix& h); + + virtual void GetScalingParameters( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + Number& obj_scaling, + SmartPtr<Vector>& x_scaling, + SmartPtr<Vector>& c_scaling, + SmartPtr<Vector>& d_scaling) const; + //@} + + /** @name Solution Reporting Methods */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, + const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method returning information on quasi-Newton approximation. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr<VectorSpace>& approx_space, + SmartPtr<Matrix>& P_approx); + + /** Enum for treatment of fixed variables option */ + enum FixedVariableTreatmentEnum + { + MAKE_PARAMETER=0, + MAKE_CONSTRAINT, + RELAX_BOUNDS + }; + + /** Enum for specifying which derivative test is to be performed. */ + enum DerivativeTestEnum + { + NO_TEST=0, + FIRST_ORDER_TEST, + SECOND_ORDER_TEST, + ONLY_SECOND_ORDER_TEST + }; + + /** Enum for specifying technique for computing Jacobian */ + enum JacobianApproxEnum + { + JAC_EXACT=0, + JAC_FINDIFF_VALUES + }; + + /** Method for performing the derivative test */ + bool CheckDerivatives(DerivativeTestEnum deriv_test, + Index deriv_test_start_index); + + /** @name Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Accessor method for the underlying TNLP. */ + SmartPtr<TNLP> tnlp() const + { + return tnlp_; + } + + /** @name Methods for translating data for IpoptNLP into the TNLP + * data. These methods are used to obtain the current (or + * final) data for the TNLP formulation from the IpoptNLP + * structure. */ + //@{ + /** Sort the primal variables, and add the fixed values in x */ + void ResortX(const Vector& x, Number* x_orig); + void ResortG(const Vector& c, const Vector& d, Number *g_orig); + void ResortBnds(const Vector& x_L, Number* x_L_orig, + const Vector& x_U, Number* x_U_orig); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TNLPAdapter(const TNLPAdapter&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPAdapter&); + //@} + + /** @name Method implementing the detection of linearly dependent + equality constraints */ + bool DetermineDependentConstraints(Index n_x_var, + const Index* x_not_fixed_map, + const Number* x_l, const Number* x_u, + const Number* g_l, const Number* g_u, + Index n_c, const Index* c_map, + std::list<Index>& c_deps); + + /** Pointer to the TNLP class (class specific to Number* vectors and + * harwell triplet matrices) */ + SmartPtr<TNLP> tnlp_; + + /** Journalist */ + SmartPtr<const Journalist> jnlst_; + + /** Object that can be used to detect linearly dependent rows in + * the equality constraint Jacobian */ + SmartPtr<TDependencyDetector> dependency_detector_; + + /**@name Algorithmic parameters */ + //@{ + /** Value for a lower bound that denotes -infinity */ + Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Number nlp_upper_bound_inf_; + /** Flag indicating how fixed variables should be handled */ + FixedVariableTreatmentEnum fixed_variable_treatment_; + /* Determines relaxation of fixing bound for RELAX_BOUNDS. */ + Number bound_relax_factor_; + /* Maximal slack for one-sidedly bounded variables. If a + * variable has only one bound, say a lower bound xL, then an + * upper bound xL + max_onesided_bound_slack_. If this value is + * zero, no upper bound is added. */ + /* Took this out: Number max_onesided_bound_slack_; */ + /** Enum indicating whether and which derivative test should be + * performed at starting point. */ + DerivativeTestEnum derivative_test_; + /** Size of the perturbation for the derivative test */ + Number derivative_test_perturbation_; + /** Relative threshold for marking deviation from finite + * difference test */ + Number derivative_test_tol_; + /** Flag indicating if all test values should be printed, or only + * those violating the threshold. */ + bool derivative_test_print_all_; + /** Index of first quantity to be checked. */ + Index derivative_test_first_index_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Number of linear variables. */ + Index num_linear_variables_; + /** Flag indicating how Jacobian is computed. */ + JacobianApproxEnum jacobian_approximation_; + /** Size of the perturbation for the derivative approximation */ + Number findiff_perturbation_; + /** Maximal perturbation of the initial point */ + Number point_perturbation_radius_; + /** Flag indicating if rhs should be considered during dependency + * detection */ + bool dependency_detection_with_rhs_; + + /** Overall convergence tolerance */ + Number tol_; + //@} + + /**@name Problem Size Data */ + //@{ + /** full dimension of x (fixed + non-fixed) */ + Index n_full_x_; + /** full dimension of g (c + d) */ + Index n_full_g_; + /** non-zeros of the jacobian of c */ + Index nz_jac_c_; + /** non-zeros of the jacobian of c without added constraints for + * fixed variables. */ + Index nz_jac_c_no_extra_; + /** non-zeros of the jacobian of d */ + Index nz_jac_d_; + /** number of non-zeros in full-size Jacobian of g */ + Index nz_full_jac_g_; + /** number of non-zeros in full-size Hessian */ + Index nz_full_h_; + /** number of non-zeros in the non-fixed-size Hessian */ + Index nz_h_; + /** Number of fixed variables */ + Index n_x_fixed_; + //@} + + /** Numbering style of variables and constraints */ + TNLP::IndexStyleEnum index_style_; + + /** @name Local copy of spaces (for warm start) */ + //@{ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> c_space_; + SmartPtr<const VectorSpace> d_space_; + SmartPtr<const VectorSpace> x_l_space_; + SmartPtr<const MatrixSpace> px_l_space_; + SmartPtr<const VectorSpace> x_u_space_; + SmartPtr<const MatrixSpace> px_u_space_; + SmartPtr<const VectorSpace> d_l_space_; + SmartPtr<const MatrixSpace> pd_l_space_; + SmartPtr<const VectorSpace> d_u_space_; + SmartPtr<const MatrixSpace> pd_u_space_; + SmartPtr<const MatrixSpace> Jac_c_space_; + SmartPtr<const MatrixSpace> Jac_d_space_; + SmartPtr<const SymMatrixSpace> Hess_lagrangian_space_; + //@} + + /**@name Local Copy of the Data */ + //@{ + Number* full_x_; /** copy of the full x vector (fixed & non-fixed) */ + Number* full_lambda_; /** copy of lambda (yc & yd) */ + Number* full_g_; /** copy of g (c & d) */ + Number* jac_g_; /** the values for the full jacobian of g */ + Number* c_rhs_; /** the rhs values of c */ + //@} + + /**@name Tags for deciding when to update internal copies of vectors */ + //@{ + TaggedObject::Tag x_tag_for_iterates_; + TaggedObject::Tag y_c_tag_for_iterates_; + TaggedObject::Tag y_d_tag_for_iterates_; + TaggedObject::Tag x_tag_for_g_; + TaggedObject::Tag x_tag_for_jac_g_; + //@} + + /**@name Methods to update the values in the local copies of vectors */ + //@{ + bool update_local_x(const Vector& x); + bool update_local_lambda(const Vector& y_c, const Vector& y_d); + //@} + + /**@name Internal routines for evaluating g and jac_g (values stored since + * they are used in both c and d routines */ + //@{ + bool internal_eval_g(bool new_x); + bool internal_eval_jac_g(bool new_x); + //@} + + /** @name Internal methods for dealing with finite difference + approxation */ + //@{ + /** Initialize sparsity structure for finite difference Jacobian */ + void initialize_findiff_jac(const Index* iRow, const Index* jCol); + //@} + + /**@name Internal Permutation Spaces and matrices + */ + //@{ + /** Expansion from fixed x (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_full_x_; + SmartPtr<ExpansionMatrixSpace> P_x_full_x_space_; + + /** Expansion from fixed x_L (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_x_L_; + SmartPtr<ExpansionMatrixSpace> P_x_x_L_space_; + + /** Expansion from fixed x_U (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_x_U_; + SmartPtr<ExpansionMatrixSpace> P_x_x_U_space_; + + /** Expansion from c only (ipopt) to full ampl c */ + SmartPtr<ExpansionMatrixSpace> P_c_g_space_; + SmartPtr<ExpansionMatrix> P_c_g_; + + /** Expansion from d only (ipopt) to full ampl d */ + SmartPtr<ExpansionMatrixSpace> P_d_g_space_; + SmartPtr<ExpansionMatrix> P_d_g_; + + Index* jac_idx_map_; + Index* h_idx_map_; + + /** Position of fixed variables. This is required for a warm start */ + Index* x_fixed_map_; + //@} + + /** @name Data for finite difference approximations of derivatives */ + //@{ + /** Number of unique nonzeros in constraint Jacobian */ + Index findiff_jac_nnz_; + /** Start position for nonzero indices in ja for each column of + Jacobian */ + Index* findiff_jac_ia_; + /** Ordered by columns, for each column the row indices in + Jacobian */ + Index* findiff_jac_ja_; + /** Position of entry in original triplet matrix */ + Index* findiff_jac_postriplet_; + /** Copy of the lower bounds */ + Number* findiff_x_l_; + /** Copy of the upper bounds */ + Number* findiff_x_u_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTNLPReducer.hpp b/thirdparty/linux/include/coin/coin/IpTNLPReducer.hpp new file mode 100644 index 0000000..bce1478 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTNLPReducer.hpp @@ -0,0 +1,180 @@ +// Copyright (C) 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPReducer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2008-08-10 + +#ifndef __IPTNLPREDUCER_HPP__ +#define __IPTNLPREDUCER_HPP__ + +#include "IpTNLP.hpp" + +namespace Ipopt +{ + /** This is a wrapper around a given TNLP class that takes out a + * list of constraints that are given to the constructor. It is + * provided for convenience, if one wants to experiment with + * problems that consist of only a subset of the constraints. But + * keep in mind that this is not efficient, since behind the scenes + * we are still evaluation all functions and derivatives, and are + * making copies of the original data. */ + class TNLPReducer : public TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor is given the indices of the constraints that + * should be taken out of the problem statement, as well as the + * original TNLP. */ + TNLPReducer(TNLP& tnlp, Index n_g_skip, const Index* index_g_skip, + Index n_xL_skip, const Index* index_xL_skip, + Index n_xU_skip, const Index* index_xU_skip, + Index n_x_fix, const Index* index_f_fix); + + /** Default destructor */ + virtual ~TNLPReducer(); + //@} + + /** @name Overloaded methods from TNLP */ + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style); + + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u); + + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling); + + virtual bool get_variables_linearity(Index n, LinearityType* var_types); + + virtual bool get_constraints_linearity(Index m, LinearityType* const_types); + + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda); + + virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate); + + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value); + + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f); + + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g); + + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values); + + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, + Index* iRow, Index* jCol, Number* values); + + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool intermediate_callback(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual Index get_number_of_nonlinear_variables(); + + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TNLPReducer(); + + /** Copy Constructor */ + TNLPReducer(const TNLPReducer&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPReducer&); + //@} + + /** @name original TNLP */ + //@{ + SmartPtr<TNLP> tnlp_; + Index m_orig_; + Index nnz_jac_g_orig_; + //@} + + /** Number of constraints to be skipped */ + Index n_g_skip_; + + /** Array of indices of the constraints that are to be skipped. + * This is provided at the beginning in the constructor. */ + Index* index_g_skip_; + + /** Index style for original problem. Internally, we use C-Style + * now. */ + IndexStyleEnum index_style_orig_; + + /** Map from original constraints to new constraints. A -1 means + * that a constraint is skipped. */ + Index* g_keep_map_; + + /** Number of constraints in reduced NLP */ + Index m_reduced_; + + /** Number of Jacobian nonzeros in the reduced NLP */ + Index nnz_jac_g_reduced_; + + /** Number of Jacobian nonzeros that are skipped */ + Index nnz_jac_g_skipped_; + + /** Array of Jacobian elements that are to be skipped. This is in + * increasing order. */ + Index* jac_g_skipped_; + + /** Number of lower variable bounds to be skipped. */ + Index n_xL_skip_; + + /** Array of indices of the lower variable bounds to be skipped. */ + Index* index_xL_skip_; + + /** Number of upper variable bounds to be skipped. */ + Index n_xU_skip_; + + /** Array of indices of the upper variable bounds to be skipped. */ + Index* index_xU_skip_; + + /** Number of variables that are to be fixed to initial value. */ + Index n_x_fix_; + + /** Array of indices of the variables that are to be fixed. */ + Index* index_x_fix_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTaggedObject.hpp b/thirdparty/linux/include/coin/coin/IpTaggedObject.hpp new file mode 100644 index 0000000..7262c43 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTaggedObject.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTaggedObject.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTAGGEDOBJECT_HPP__ +#define __IPTAGGEDOBJECT_HPP__ + +#include "IpUtils.hpp" +#include "IpDebug.hpp" +#include "IpReferenced.hpp" +#include "IpObserver.hpp" +#include <limits> + +/* keyword to declare a thread-local variable according to http://en.wikipedia.org/wiki/Thread-local_storage + * GCC < 4.5 on MacOS X does not support TLS + * With Intel compiler on MacOS X, problems with TLS were reported. + */ +#ifndef IPOPT_THREAD_LOCAL + +#if defined(_MSC_VER) +#define IPOPT_THREAD_LOCAL __declspec(thread) +#elif defined(__APPLE__) && ((defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 405)) || defined(__INTEL_COMPILER)) +#define IPOPT_THREAD_LOCAL +#else +#define IPOPT_THREAD_LOCAL __thread +#endif + +#endif + +namespace Ipopt +{ + + /** TaggedObject class. + * Often, certain calculations or operations are expensive, + * and it can be very inefficient to perform these calculations + * again if the input to the calculation has not changed + * since the result was last stored. + * This base class provides an efficient mechanism to update + * a tag, indicating that the object has changed. + * Users of a TaggedObject class, need their own Tag data + * member to keep track of the state of the TaggedObject, the + * last time they performed a calculation. A basic use case for + * users of a class inheriting from TaggedObject follows like + * this: + * + * 1. Initialize your own Tag to zero in constructor. + * + * 2. Before an expensive calculation, + * check if the TaggedObject has changed, passing in + * your own Tag, indicating the last time you used + * the object for the calculation. If it has changed, + * perform the calculation again, and store the result. + * If it has not changed, simply return the stored result. + * + * Here is a simple example: + \verbatim + if (vector.HasChanged(my_vector_tag_)) { + my_vector_tag_ = vector.GetTag(); + result = PerformExpensiveCalculation(vector); + return result; + } + else { + return result; + } + \endverbatim + * + * Objects derived from TaggedObject must indicate that they have changed to + * the base class using the protected member function ObjectChanged(). For + * example, a Vector class, inside its own set method, MUST call + * ObjectChanged() to update the internally stored tag for comparison. + */ + class TaggedObject : public ReferencedObject, public Subject + { + public: + /** Type for the Tag values */ + typedef unsigned int Tag; + + /** Constructor. */ + TaggedObject() + : + Subject() + { + ObjectChanged(); + } + + /** Destructor. */ + virtual ~TaggedObject() + {} + + /** Users of TaggedObjects call this to + * update their own internal tags every time + * they perform the expensive operation. + */ + Tag GetTag() const + { + return tag_; + } + + /** Users of TaggedObjects call this to + * check if the object HasChanged since + * they last updated their own internal + * tag. + */ + bool HasChanged(const Tag comparison_tag) const + { + return (comparison_tag == tag_) ? false : true; + } + protected: + /** Objects derived from TaggedObject MUST call this + * method every time their internal state changes to + * update the internal tag for comparison + */ + void ObjectChanged() + { + DBG_START_METH("TaggedObject::ObjectChanged()", 0); + tag_ = unique_tag_; + unique_tag_++; + DBG_ASSERT(unique_tag_ < std::numeric_limits<Tag>::max()); + // The Notify method from the Subject base class notifies all + // registered Observers that this subject has changed. + Notify(Observer::NT_Changed); + } + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TaggedObject(const TaggedObject&); + + /** Overloaded Equals Operator */ + void operator=(const TaggedObject&); + //@} + + /** static data member that is incremented every + * time ANY TaggedObject changes. This allows us + * to obtain a unique Tag when the object changes + */ + static IPOPT_THREAD_LOCAL Tag unique_tag_; + + /** The tag indicating the current state of the object. + * We use this to compare against the comparison_tag + * in the HasChanged method. This member is updated + * from the unique_tag_ every time the object changes. + */ + Tag tag_; + + /** The index indicating the cache priority for this + * TaggedObject. If a result that depended on this + * TaggedObject is cached, it will be cached with this + * priority + */ + Index cache_priority_; + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTimedTask.hpp b/thirdparty/linux/include/coin/coin/IpTimedTask.hpp new file mode 100644 index 0000000..a1c5bac --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTimedTask.hpp @@ -0,0 +1,146 @@ +// Copyright (C) 2006, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimedTask.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMEDTASK_HPP__ +#define __IPTIMEDTASK_HPP__ + +#include "IpUtils.hpp" + +namespace Ipopt +{ + /** This class is used to collect timing information for a + * particular task. */ + class TimedTask + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimedTask() + : + total_cputime_(0.), + total_systime_(0.), + total_walltime_(0.), + start_called_(false), + end_called_(true) + {} + + /** Default destructor */ + ~TimedTask() + {} + //@} + + /** Method for resetting time to zero. */ + void Reset() + { + total_cputime_ = 0.; + total_systime_ = 0.; + total_walltime_ = 0.; + start_called_ = false; + end_called_ = true; + } + + /** Method that is called before execution of the task. */ + void Start() + { + DBG_ASSERT(end_called_); + DBG_ASSERT(!start_called_); + end_called_ = false; + start_called_ = true; + start_cputime_ = CpuTime(); + start_systime_ = SysTime(); + start_walltime_ = WallclockTime(); + } + + /** Method that is called after execution of the task. */ + void End() + { + DBG_ASSERT(!end_called_); + DBG_ASSERT(start_called_); + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + + /** Method that is called after execution of the task for which + * timing might have been started. This only updates the timing + * if the timing has indeed been conducted. This is useful to + * stop timing after catching exceptions. */ + void EndIfStarted() + { + if (start_called_) { + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + DBG_ASSERT(end_called_); + } + + /** Method returning total CPU time spend for task so far. */ + Number TotalCpuTime() const + { + DBG_ASSERT(end_called_); + return total_cputime_; + } + + /** Method returning total system time spend for task so far. */ + Number TotalSysTime() const + { + DBG_ASSERT(end_called_); + return total_systime_; + } + + /** Method returning total wall clock time spend for task so far. */ + Number TotalWallclockTime() const + { + DBG_ASSERT(end_called_); + return total_walltime_; + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not + * implemented and we do not want the compiler to implement them + * for us, so we declare them private and do not define + * them. This ensures that they will not be implicitly + * created/called. */ + //@{ + /** Copy Constructor */ + TimedTask(const TimedTask&); + + /** Overloaded Equals Operator */ + void operator=(const TimedTask&); + //@} + + /** CPU time at beginning of task. */ + Number start_cputime_; + /** Total CPU time for task measured so far. */ + Number total_cputime_; + /** System time at beginning of task. */ + Number start_systime_; + /** Total system time for task measured so far. */ + Number total_systime_; + /** Wall clock time at beginning of task. */ + Number start_walltime_; + /** Total wall clock time for task measured so far. */ + Number total_walltime_; + + /** @name fields for debugging */ + //@{ + bool start_called_; + bool end_called_; + //@} + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTimingStatistics.hpp b/thirdparty/linux/include/coin/coin/IpTimingStatistics.hpp new file mode 100644 index 0000000..850ed1b --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTimingStatistics.hpp @@ -0,0 +1,213 @@ +// Copyright (C) 2005, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimingStatistics.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMINGSTATISTICS_HPP__ +#define __IPTIMINGSTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpJournalist.hpp" +#include "IpTimedTask.hpp" + +namespace Ipopt +{ + /** This class collects all timing statistics for Ipopt. + */ + class TimingStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimingStatistics() + {} + + /** Default destructor */ + virtual ~TimingStatistics() + {} + //@} + + /** Method for resetting all times. */ + void ResetTimes(); + + /** Method for printing all timing information */ + void PrintAllTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + /**@name Accessor methods to all timed tasks. */ + //@{ + TimedTask& OverallAlgorithm() + { + return OverallAlgorithm_; + } + TimedTask& PrintProblemStatistics() + { + return PrintProblemStatistics_; + } + TimedTask& InitializeIterates() + { + return InitializeIterates_; + } + TimedTask& UpdateHessian() + { + return UpdateHessian_; + } + TimedTask& OutputIteration() + { + return OutputIteration_; + } + TimedTask& UpdateBarrierParameter() + { + return UpdateBarrierParameter_; + } + TimedTask& ComputeSearchDirection() + { + return ComputeSearchDirection_; + } + TimedTask& ComputeAcceptableTrialPoint() + { + return ComputeAcceptableTrialPoint_; + } + TimedTask& AcceptTrialPoint() + { + return AcceptTrialPoint_; + } + TimedTask& CheckConvergence() + { + return CheckConvergence_; + } + + TimedTask& PDSystemSolverTotal() + { + return PDSystemSolverTotal_; + } + TimedTask& PDSystemSolverSolveOnce() + { + return PDSystemSolverSolveOnce_; + } + TimedTask& ComputeResiduals() + { + return ComputeResiduals_; + } + TimedTask& StdAugSystemSolverMultiSolve() + { + return StdAugSystemSolverMultiSolve_; + } + TimedTask& LinearSystemScaling() + { + return LinearSystemScaling_; + } + TimedTask& LinearSystemSymbolicFactorization() + { + return LinearSystemSymbolicFactorization_; + } + TimedTask& LinearSystemFactorization() + { + return LinearSystemFactorization_; + } + TimedTask& LinearSystemBackSolve() + { + return LinearSystemBackSolve_; + } + TimedTask& LinearSystemStructureConverter() + { + return LinearSystemStructureConverter_; + } + TimedTask& LinearSystemStructureConverterInit() + { + return LinearSystemStructureConverterInit_; + } + TimedTask& QualityFunctionSearch() + { + return QualityFunctionSearch_; + } + TimedTask& TryCorrector() + { + return TryCorrector_; + } + + TimedTask& Task1() + { + return Task1_; + } + TimedTask& Task2() + { + return Task2_; + } + TimedTask& Task3() + { + return Task3_; + } + TimedTask& Task4() + { + return Task4_; + } + TimedTask& Task5() + { + return Task5_; + } + TimedTask& Task6() + { + return Task6_; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TimingStatistics(const TimingStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const TimingStatistics&); + //@} + + /**@name All timed tasks. */ + //@{ + TimedTask OverallAlgorithm_; + TimedTask PrintProblemStatistics_; + TimedTask InitializeIterates_; + TimedTask UpdateHessian_; + TimedTask OutputIteration_; + TimedTask UpdateBarrierParameter_; + TimedTask ComputeSearchDirection_; + TimedTask ComputeAcceptableTrialPoint_; + TimedTask AcceptTrialPoint_; + TimedTask CheckConvergence_; + + TimedTask PDSystemSolverTotal_; + TimedTask PDSystemSolverSolveOnce_; + TimedTask ComputeResiduals_; + TimedTask StdAugSystemSolverMultiSolve_; + TimedTask LinearSystemScaling_; + TimedTask LinearSystemSymbolicFactorization_; + TimedTask LinearSystemFactorization_; + TimedTask LinearSystemBackSolve_; + TimedTask LinearSystemStructureConverter_; + TimedTask LinearSystemStructureConverterInit_; + TimedTask QualityFunctionSearch_; + TimedTask TryCorrector_; + + TimedTask Task1_; + TimedTask Task2_; + TimedTask Task3_; + TimedTask Task4_; + TimedTask Task5_; + TimedTask Task6_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTripletHelper.hpp b/thirdparty/linux/include/coin/coin/IpTripletHelper.hpp new file mode 100644 index 0000000..35424c0 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTripletHelper.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTripletHelper.hpp 2380 2013-09-06 22:57:49Z ghackebeil $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTRIPLETHELPER_HPP__ +#define __IPTRIPLETHELPER_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + DECLARE_STD_EXCEPTION(UNKNOWN_MATRIX_TYPE); + DECLARE_STD_EXCEPTION(UNKNOWN_VECTOR_TYPE); + + /** forward declarations */ + class Matrix; + class GenTMatrix; + class SymTMatrix; + class DiagMatrix; + class IdentityMatrix; + class ExpansionMatrix; + class ScaledMatrix; + class SymScaledMatrix; + class SumMatrix; + class SumSymMatrix; + class ZeroMatrix; + class ZeroSymMatrix; + class CompoundMatrix; + class CompoundSymMatrix; + class TransposeMatrix; + class ExpandedMultiVectorMatrix; + class Vector; + + class TripletHelper + { + public: + /**@name A set of recursive routines that help with the Triplet format. */ + //@{ + /** find the total number of triplet entries of a Matrix */ + static Index GetNumberEntries(const Matrix& matrix); + + /** fill the irows, jcols structure for the triplet format from the matrix */ + static void FillRowCol(Index n_entries, const Matrix& matrix, Index* iRow, Index* jCol, Index row_offset=0, Index col_offset=0); + + /** fill the values for the triplet format from the matrix */ + static void FillValues(Index n_entries, const Matrix& matrix, Number* values); + + /** fill the values from the vector into a dense double* structure */ + static void FillValuesFromVector(Index dim, const Vector& vector, Number* values); + + /** put the values from the double* back into the vector */ + static void PutValuesInVector(Index dim, const double* values, Vector& vector); + //@} + + private: + /** find the total number of triplet entries for the SumMatrix */ + static Index GetNumberEntries_(const SumMatrix& matrix); + + /** find the total number of triplet entries for the SumSymMatrix */ + static Index GetNumberEntries_(const SumSymMatrix& matrix); + + /** find the total number of triplet entries for the CompoundMatrix */ + static Index GetNumberEntries_(const CompoundMatrix& matrix); + + /** find the total number of triplet entries for the CompoundSymMatrix */ + static Index GetNumberEntries_(const CompoundSymMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const TransposeMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const ExpandedMultiVectorMatrix& matrix); + + static void FillRowCol_(Index n_entries, const GenTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const GenTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const DiagMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const DiagMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const IdentityMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const IdentityMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpansionMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpansionMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const TransposeMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const TransposeMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Number* values); + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpTypes.hpp b/thirdparty/linux/include/coin/coin/IpTypes.hpp new file mode 100644 index 0000000..9c41b8f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpTypes.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTypes.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTYPES_HPP__ +#define __IPTYPES_HPP__ + +#include "IpoptConfig.h" + +namespace Ipopt +{ + /** Type of all numbers */ + typedef double Number; + /** Type of all indices of vectors, matrices etc */ + typedef int Index; + /** Type of default integer */ + typedef int Int; + +} // namespace Ipopt + +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpUtils.hpp b/thirdparty/linux/include/coin/coin/IpUtils.hpp new file mode 100644 index 0000000..4e5f045 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpUtils.hpp @@ -0,0 +1,128 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpUtils.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPUTILS_HPP__ +#define __IPUTILS_HPP__ + +// Standard Ip Include Files +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +namespace Ipopt +{ + + inline Index Max(Index a, Index b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Index Max(Index a, Index b, Index c) + { + Index max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Index Max(Index a, Index b, Index c, Index d) + { + Index max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Index Min(Index a, Index b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Index Min(Index a, Index b, Index c) + { + Index min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Index Min(Index a, Index b, Index c, Index d) + { + Index min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /////////////////////////////////////////// + + inline Number Max(Number a, Number b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Number Max(Number a, Number b, Number c) + { + Number max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Number Max(Number a, Number b, Number c, Number d) + { + Number max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Number Min(Number a, Number b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Number Min(Number a, Number b, Number c) + { + Number min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Number Min(Number a, Number b, Number c, Number d) + { + Number min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /** Function returning true iff the argument is a valid double number + * (not NaN or Inf). */ + bool IsFiniteNumber(Number val); + + /** Function returning a random number between 0 and 1 */ + Number IpRandom01(); + + /** Function resetting the random number generator */ + void IpResetRandom01(); + + /** method determining CPU time */ + Number CpuTime(); + + /** method determining system time */ + Number SysTime(); + + /** method determining wallclock time since first call */ + Number WallclockTime(); + + /** Method for comparing two numbers within machine precision. The + * return value is true if lhs is less or equal the rhs, relaxing + * this inequality by something a little larger than machine + * precision relative to the absolute value of BasVal. */ + bool Compare_le(Number lhs, Number rhs, Number BasVal); + + /** Method for printing a formatted output to a string with given size. + */ + int Snprintf(char* str, long size, const char* format, ...); + +} //namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpVector.hpp b/thirdparty/linux/include/coin/coin/IpVector.hpp new file mode 100644 index 0000000..a903558 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpVector.hpp @@ -0,0 +1,774 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPVECTOR_HPP__ +#define __IPVECTOR_HPP__ + +#include "IpTypes.hpp" +#include "IpTaggedObject.hpp" +#include "IpCachedResults.hpp" +#include "IpSmartPtr.hpp" +#include "IpJournalist.hpp" +#include "IpException.hpp" + +#include <vector> + +namespace Ipopt +{ + /** Exception that can be used to flag unimplemented linear algebra + * methods */ + DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED); + + /* forward declarations */ + class VectorSpace; + + /** Vector Base Class. + * This is the base class for all derived vector types. Those vectors + * are meant to store entities like iterates, Lagrangian multipliers, + * constraint values etc. The implementation of a vector type depends + * on the computational environment (e.g. just a double array on a shared + * memory machine, or distributed double arrays for a distributed + * memory machine.) + * + * Deriving from Vector: This class inherits from tagged object to + * implement an advanced caching scheme. Because of this, the + * TaggedObject method ObjectChanged() must be called each time the + * Vector changes. If you overload the XXXX_Impl protected methods, + * this taken care of (along with caching if possible) for you. If + * you have additional methods in your derived class that change the + * underlying data (vector values), you MUST remember to call + * ObjectChanged() AFTER making the change! + */ + class Vector : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding VectorSpace. + */ + inline + Vector(const VectorSpace* owner_space); + + /** Destructor */ + inline + virtual ~Vector(); + //@} + + /** Create new Vector of the same type with uninitialized data */ + inline + Vector* MakeNew() const; + + /** Create new Vector of the same type and copy the data over */ + inline + Vector* MakeNewCopy() const; + + /**@name Standard BLAS-1 Operations + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + inline + void Copy(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + void Scal(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + inline + void Axpy(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + inline + Number Dot(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + inline + Number Nrm2() const; + + /** Computes the 1-norm of this vector (DASUM) */ + inline + Number Asum() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + inline + Number Amax() const; + //@} + + /** @name Additional (Non-BLAS) Vector Methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Set each element in the vector to the scalar alpha. */ + inline + void Set(Number alpha); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + inline + void ElementWiseDivide(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + inline + void ElementWiseMultiply(const Vector& x); + + /** Element-wise max against entries in x */ + inline + void ElementWiseMax(const Vector& x); + + /** Element-wise min against entries in x */ + inline + void ElementWiseMin(const Vector& x); + + /** Reciprocates the entries in the vector */ + inline + void ElementWiseReciprocal(); + + /** Absolute values of the entries in the vector */ + inline + void ElementWiseAbs(); + + /** Element-wise square root of the entries in the vector */ + inline + void ElementWiseSqrt(); + + /** Replaces the vector values with their sgn values + ( -1 if x_i < 0, 0 if x_i == 0, and 1 if x_i > 0) + */ + inline + void ElementWiseSgn(); + + /** Add scalar to every vector component */ + inline + void AddScalar(Number scalar); + + /** Returns the maximum value in the vector */ + inline + Number Max() const; + + /** Returns the minimum value in the vector */ + inline + Number Min() const; + + /** Returns the sum of the vector entries */ + inline + Number Sum() const; + + /** Returns the sum of the logs of each vector entry */ + inline + Number SumLogs() const; + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** Add one vector, y = a * v1 + c * y. This is automatically + * reduced to call AddTwoVectors. */ + inline + void AddOneVector(Number a, const Vector& v1, Number c); + + /** Add two vectors, y = a * v1 + b * v2 + c * y. Here, this + * vector is y */ + inline void AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. Computes \f$\alpha = + * \max\{\bar\alpha\in(0,1] : x + \bar\alpha \Delta \geq (1-\tau)x\}\f$ + */ + inline + Number FracToBound(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + inline + void AddVectorQuotient(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + inline + bool HasValidNumbers() const; + + /** @name Accessor methods */ + //@{ + /** Dimension of the Vector */ + inline + Index Dim() const; + + /** Return the owner VectorSpace*/ + inline + SmartPtr<const VectorSpace> OwnerSpace() const; + //@} + + /** @name Output methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Print the entire vector */ + void Print(SmartPtr<const Journalist> jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods.) + */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x)=0; + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha)=0; + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x)=0; + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const =0; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const =0; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const =0; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const =0; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number alpha)=0; + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + virtual void ElementWiseDivideImpl(const Vector& x)=0; + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + virtual void ElementWiseMultiplyImpl(const Vector& x)=0; + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x)=0; + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x)=0; + + /** Reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl()=0; + + /** Take elementwise absolute values of the elements of the vector */ + virtual void ElementWiseAbsImpl()=0; + + /** Take elementwise square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl()=0; + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl()=0; + + /** Add scalar to every component of vector */ + virtual void AddScalarImpl(Number scalar)=0; + + /** Max value in the vector */ + virtual Number MaxImpl() const=0; + + /** Min number in the vector */ + virtual Number MinImpl() const=0; + + /** Sum of entries in the vector */ + virtual Number SumImpl() const=0; + + /** Sum of logs of entries in the vector */ + virtual Number SumLogsImpl() const=0; + + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + virtual void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + + /** Fraction to boundary parameter. */ + virtual Number FracToBoundImpl(const Vector& delta, Number tau) const; + + /** Add the quotient of two vectors */ + virtual void AddVectorQuotientImpl(Number a, const Vector& z, + const Vector& s, Number c); + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation using Asum is + * provided. */ + virtual bool HasValidNumbersImpl() const; + + /** Print the entire vector */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + Vector(); + + /** Copy constructor */ + Vector(const Vector&); + + /** Overloaded Equals Operator */ + Vector& operator=(const Vector&); + //@} + + /** Vector Space */ + const SmartPtr<const VectorSpace> owner_space_; + + /**@name CachedResults data members */ + //@{ + /** Cache for dot products */ + mutable CachedResults<Number> dot_cache_; + + mutable TaggedObject::Tag nrm2_cache_tag_; + mutable Number cached_nrm2_; + + mutable TaggedObject::Tag asum_cache_tag_; + mutable Number cached_asum_; + + mutable TaggedObject::Tag amax_cache_tag_; + mutable Number cached_amax_; + + mutable TaggedObject::Tag max_cache_tag_; + mutable Number cached_max_; + + mutable TaggedObject::Tag min_cache_tag_; + mutable Number cached_min_; + + mutable TaggedObject::Tag sum_cache_tag_; + mutable Number cached_sum_; + + mutable TaggedObject::Tag sumlogs_cache_tag_; + mutable Number cached_sumlogs_; + + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + + // AW: I removed this cache since it gets in the way for the + // quality function search + // /** Cache for FracToBound */ + // mutable CachedResults<Number> frac_to_bound_cache_; + //@} + + }; + + /** VectorSpace base class, corresponding to the Vector base class. + * For each Vector implementation, a corresponding VectorSpace has + * to be implemented. A VectorSpace is able to create new Vectors + * of a specific type. The VectorSpace should also store + * information that is common to all Vectors of that type. For + * example, the dimension of a Vector is stored in the VectorSpace + * base class. + */ + class VectorSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension of all vectors generated by + * this VectorSpace. + */ + VectorSpace(Index dim); + + /** Destructor */ + virtual ~VectorSpace() + {} + //@} + + /** Pure virtual method for creating a new Vector of the + * corresponding type. + */ + virtual Vector* MakeNew() const=0; + + /** Accessor function for the dimension of the vectors of this type.*/ + Index Dim() const + { + return dim_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + VectorSpace(); + + /** Copy constructor */ + VectorSpace(const VectorSpace&); + + /** Overloaded Equals Operator */ + VectorSpace& operator=(const VectorSpace&); + //@} + + /** Dimension of the vectors in this vector space. */ + const Index dim_; + }; + + /* inline methods */ + inline + Vector::~Vector() + {} + + inline + Vector::Vector(const VectorSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + dot_cache_(10), + nrm2_cache_tag_(0), + asum_cache_tag_(0), + amax_cache_tag_(0), + max_cache_tag_(0), + min_cache_tag_(0), + sum_cache_tag_(0), + sumlogs_cache_tag_(0), + cached_valid_(0) + { + DBG_ASSERT(IsValid(owner_space_)); + } + + inline + Vector* Vector::MakeNew() const + { + return owner_space_->MakeNew(); + } + + inline + Vector* Vector::MakeNewCopy() const + { + // ToDo: We can probably copy also the cached values for Norms etc here + Vector* copy = MakeNew(); + copy->Copy(*this); + return copy; + } + + inline + void Vector::Copy(const Vector& x) + { + CopyImpl(x); + ObjectChanged(); + // Also copy any cached scalar values from the original vector + // ToDo: Check if that is too much overhead + TaggedObject::Tag x_tag = x.GetTag(); + if (x_tag == x.nrm2_cache_tag_) { + nrm2_cache_tag_ = GetTag(); + cached_nrm2_ = x.cached_nrm2_; + } + if (x_tag == x.asum_cache_tag_) { + asum_cache_tag_ = GetTag(); + cached_asum_ = x.cached_asum_; + } + if (x_tag == x.amax_cache_tag_) { + amax_cache_tag_ = GetTag(); + cached_amax_ = x.cached_amax_; + } + if (x_tag == x.max_cache_tag_) { + max_cache_tag_ = GetTag(); + cached_max_ = x.cached_max_; + } + if (x_tag == x.min_cache_tag_) { + min_cache_tag_ = GetTag(); + cached_min_ = x.cached_min_; + } + if (x_tag == x.sum_cache_tag_) { + sum_cache_tag_ = GetTag(); + cached_sum_ = x.cached_sum_; + } + if (x_tag == x.sumlogs_cache_tag_) { + sumlogs_cache_tag_ = GetTag(); + cached_sumlogs_ = x.cached_sumlogs_; + } + } + + inline + void Vector::Axpy(Number alpha, const Vector &x) + { + AxpyImpl(alpha, x); + ObjectChanged(); + } + + inline + Number Vector::Dot(const Vector &x) const + { + // The current implementation of the caching doesn't allow to have + // a dependency of something with itself. Therefore, we use the + // Nrm2 method if the dot product is to be taken with the vector + // itself. Might be more efficient anyway. + if (this==&x) { + Number nrm2 = Nrm2(); + return nrm2*nrm2; + } + Number retValue; + if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) { + retValue = DotImpl(x); + dot_cache_.AddCachedResult2Dep(retValue, this, &x); + } + return retValue; + } + + inline + Number Vector::Nrm2() const + { + if (nrm2_cache_tag_ != GetTag()) { + cached_nrm2_ = Nrm2Impl(); + nrm2_cache_tag_ = GetTag(); + } + return cached_nrm2_; + } + + inline + Number Vector::Asum() const + { + if (asum_cache_tag_ != GetTag()) { + cached_asum_ = AsumImpl(); + asum_cache_tag_ = GetTag(); + } + return cached_asum_; + } + + inline + Number Vector::Amax() const + { + if (amax_cache_tag_ != GetTag()) { + cached_amax_ = AmaxImpl(); + amax_cache_tag_ = GetTag(); + } + return cached_amax_; + } + + inline + Number Vector::Sum() const + { + if (sum_cache_tag_ != GetTag()) { + cached_sum_ = SumImpl(); + sum_cache_tag_ = GetTag(); + } + return cached_sum_; + } + + inline + Number Vector::SumLogs() const + { + if (sumlogs_cache_tag_ != GetTag()) { + cached_sumlogs_ = SumLogsImpl(); + sumlogs_cache_tag_ = GetTag(); + } + return cached_sumlogs_; + } + + inline + void Vector::ElementWiseSgn() + { + ElementWiseSgnImpl(); + ObjectChanged(); + } + + inline + void Vector::Set(Number alpha) + { + // Could initialize caches here + SetImpl(alpha); + ObjectChanged(); + } + + inline + void Vector::ElementWiseDivide(const Vector& x) + { + ElementWiseDivideImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMultiply(const Vector& x) + { + ElementWiseMultiplyImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseReciprocal() + { + ElementWiseReciprocalImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMax(const Vector& x) + { + // Could initialize some caches here + ElementWiseMaxImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMin(const Vector& x) + { + // Could initialize some caches here + ElementWiseMinImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseAbs() + { + // Could initialize some caches here + ElementWiseAbsImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseSqrt() + { + ElementWiseSqrtImpl(); + ObjectChanged(); + } + + inline + void Vector::AddScalar(Number scalar) + { + // Could initialize some caches here + AddScalarImpl(scalar); + ObjectChanged(); + } + + inline + Number Vector::Max() const + { + if (max_cache_tag_ != GetTag()) { + cached_max_ = MaxImpl(); + max_cache_tag_ = GetTag(); + } + return cached_max_; + } + + inline + Number Vector::Min() const + { + if (min_cache_tag_ != GetTag()) { + cached_min_ = MinImpl(); + min_cache_tag_ = GetTag(); + } + return cached_min_; + } + + inline + void Vector::AddOneVector(Number a, const Vector& v1, Number c) + { + AddTwoVectors(a, v1, 0., v1, c); + } + + inline + void Vector::AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c) + { + AddTwoVectorsImpl(a, v1, b, v2, c); + ObjectChanged(); + } + + inline + Number Vector::FracToBound(const Vector& delta, Number tau) const + { + /* AW: I avoid the caching here, since it leads to overhead in the + quality function search. Caches for this are in + CalculatedQuantities. + Number retValue; + std::vector<const TaggedObject*> tdeps(1); + tdeps[0] = δ + std::vector<Number> sdeps(1); + sdeps[0] = tau; + if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) { + retValue = FracToBoundImpl(delta, tau); + frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps); + } + return retValue; + */ + return FracToBoundImpl(delta, tau); + } + + inline + void Vector::AddVectorQuotient(Number a, const Vector& z, + const Vector& s, Number c) + { + AddVectorQuotientImpl(a, z, s, c); + ObjectChanged(); + } + + inline + bool Vector::HasValidNumbers() const + { + if (valid_cache_tag_ != GetTag()) { + cached_valid_ = HasValidNumbersImpl(); + valid_cache_tag_ = GetTag(); + } + return cached_valid_; + } + + inline + Index Vector::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr<const VectorSpace> Vector::OwnerSpace() const + { + return owner_space_; + } + + inline + VectorSpace::VectorSpace(Index dim) + : + dim_(dim) + {} + +} // namespace Ipopt + +// Macro definitions for debugging vectors +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +#else +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__vec).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __vec_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif //if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin/coin/IpZeroSymMatrix.hpp b/thirdparty/linux/include/coin/coin/IpZeroSymMatrix.hpp new file mode 100644 index 0000000..35ad95e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpZeroSymMatrix.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpZeroSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPZEROSYMMATRIX_HPP__ +#define __IPZEROSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Symmetric Matrices with only zero entries. + */ + class ZeroSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + ZeroSymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~ZeroSymMatrix(); + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const + {} + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + {} + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrix(); + + /** Copy Constructor */ + ZeroSymMatrix(const ZeroSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrix&); + //@} + }; + + /** Class for matrix space for ZeroSymMatrix. */ + class ZeroSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns. + */ + ZeroSymMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~ZeroSymMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewZeroSymMatrix(); + } + + /** Overloaded method from SymMatrixSpace base class + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewZeroSymMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + ZeroSymMatrix* MakeNewZeroSymMatrix() const + { + return new ZeroSymMatrix(this); + } + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrixSpace(); + + /** Copy Constructor */ + ZeroSymMatrixSpace(const ZeroSymMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrixSpace&); + //@} + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin/coin/IpoptConfig.h b/thirdparty/linux/include/coin/coin/IpoptConfig.h new file mode 100644 index 0000000..78dadd3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/IpoptConfig.h @@ -0,0 +1,22 @@ +/* src/Common/config_ipopt.h. Generated by configure. */ +/* src/Common/config_ipopt.h.in. */ + +#ifndef __CONFIG_IPOPT_H__ +#define __CONFIG_IPOPT_H__ + +/* Version number of project */ +#define IPOPT_VERSION "3.12.7" + +/* Major Version number of project */ +#define IPOPT_VERSION_MAJOR 3 + +/* Minor Version number of project */ +#define IPOPT_VERSION_MINOR 12 + +/* Release Version number of project */ +#define IPOPT_VERSION_RELEASE 7 + +/* Define to the C type corresponding to Fortran INTEGER */ +#define FORTRAN_INTEGER_TYPE int + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiAuxInfo.hpp b/thirdparty/linux/include/coin/coin/OsiAuxInfo.hpp new file mode 100644 index 0000000..182d981 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiAuxInfo.hpp @@ -0,0 +1,206 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiAuxInfo_H +#define OsiAuxInfo_H + +class OsiSolverInterface; + +//############################################################################# +/** This class allows for a more structured use of algorithmic tweaking to + an OsiSolverInterface. It is designed to replace the simple use of + appData_ pointer. + + This has been done to make it easier to use NonLinear solvers and other + exotic beasts in a branch and bound mode. After this class definition + there is one for a derived class for just such a purpose. + +*/ + +class OsiAuxInfo { +public: + // Default Constructor + OsiAuxInfo (void * appData = NULL); + + // Copy Constructor + OsiAuxInfo (const OsiAuxInfo & rhs); + // Destructor + virtual ~OsiAuxInfo(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiAuxInfo & operator=(const OsiAuxInfo& rhs); + + /// Get application data + inline void * getApplicationData() const + { return appData_;} +protected: + /// Pointer to user-defined data structure + void * appData_; +}; +//############################################################################# +/** This class allows for the use of more exotic solvers e.g. Non-Linear or Volume. + + You can derive from this although at present I can't see the need. +*/ + +class OsiBabSolver : public OsiAuxInfo { +public: + // Default Constructor + OsiBabSolver (int solverType=0); + + // Copy Constructor + OsiBabSolver (const OsiBabSolver & rhs); + // Destructor + virtual ~OsiBabSolver(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiBabSolver & operator=(const OsiBabSolver& rhs); + + /// Update solver + inline void setSolver(const OsiSolverInterface * solver) + { solver_ = solver;} + /// Update solver + inline void setSolver(const OsiSolverInterface & solver) + { solver_ = &solver;} + + /** returns 0 if no heuristic solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value + numberColumns is size of newSolution + */ + int solution(double & objectiveValue, + double * newSolution, int numberColumns); + /** Set solution and objective value. + Number of columns and optimization direction taken from current solver. + Size of solution is numberColumns (may be padded or truncated in function) */ + void setSolution(const double * solution, int numberColumns, double objectiveValue); + + /** returns true if the object stores a solution, false otherwise. If there + is a solution then solutionValue and solution will be filled out as well. + In that case the user needs to allocate solution to be a big enough + array. + */ + bool hasSolution(double & solutionValue, double * solution); + + /** Sets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check solver to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline void setSolverType(int value) + { solverType_=value;} + /** gets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline int solverType() const + { return solverType_;} + /** Return true if getting solution may add cuts so hot start etc will + be obsolete */ + inline bool solutionAddsCuts() const + { return solverType_==3;} + /// Return true if we should try cuts at root even if looks satisfied + inline bool alwaysTryCutsAtRootNode() const + { return solverType_==4;} + /** Returns true if can use solver objective or feasible values, + otherwise use mipBound etc */ + inline bool solverAccurate() const + { return solverType_==0||solverType_==2||solverType_==4;} + /// Returns true if can use reduced costs for fixing + inline bool reducedCostsAccurate() const + { return solverType_==0||solverType_==4;} + /// Get objective (well mip bound) + double mipBound() const; + /// Returns true if node feasible + bool mipFeasible() const; + /// Set mip bound (only used for some solvers) + inline void setMipBound(double value) + { mipBound_ = value;} + /// Get objective value of saved solution + inline double bestObjectiveValue() const + { return bestObjectiveValue_;} + /// Says whether we want to try cuts at all + inline bool tryCuts() const + { return solverType_!=2;} + /// Says whether we have a warm start (so can do strong branching) + inline bool warmStart() const + { return solverType_!=2;} + /** Get bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline int extraCharacteristics() const + { return extraCharacteristics_;} + /** Set bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline void setExtraCharacteristics(int value) + { extraCharacteristics_=value;} + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + inline const double * beforeLower() const + { return beforeLower_;} + /// Set pointer to lower bounds before branch (only if extraCharacteristics set) + inline void setBeforeLower(const double * array) + { beforeLower_ = array;} + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + inline const double * beforeUpper() const + { return beforeUpper_;} + /// Set pointer to upper bounds before branch (only if extraCharacteristics set) + inline void setBeforeUpper(const double * array) + { beforeUpper_ = array;} +protected: + /// Objective value of best solution (if there is one) (minimization) + double bestObjectiveValue_; + /// Current lower bound on solution ( if > 1.0e50 infeasible) + double mipBound_; + /// Solver to use for getting/setting solutions etc + const OsiSolverInterface * solver_; + /// Best integer feasible solution + double * bestSolution_; + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + const double * beforeLower_; + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + const double * beforeUpper_; + /** Solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + */ + int solverType_; + /// Size of solution + int sizeSolution_; + /** Bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + int extraCharacteristics_; +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiBranchingObject.hpp b/thirdparty/linux/include/coin/coin/OsiBranchingObject.hpp new file mode 100644 index 0000000..78b6984 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiBranchingObject.hpp @@ -0,0 +1,1005 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiBranchingObject_H +#define OsiBranchingObject_H + +#include <cassert> +#include <string> +#include <vector> + +#include "CoinError.hpp" +#include "CoinTypes.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiBranchingObject; +class OsiBranchingInformation; + +//############################################################################# +//This contains the abstract base class for an object and for branching. +//It also contains a simple integer class +//############################################################################# + +/** Abstract base class for `objects'. + + The branching model used in Osi is based on the idea of an <i>object</i>. + In the abstract, an object is something that has a feasible region, can be + evaluated for infeasibility, can be branched on (<i>i.e.</i>, there's some + constructive action to be taken to move toward feasibility), and allows + comparison of the effect of branching. + + This class (OsiObject) is the base class for an object. To round out the + branching model, the class OsiBranchingObject describes how to perform a + branch, and the class OsiBranchDecision describes how to compare two + OsiBranchingObjects. + + To create a new type of object you need to provide three methods: + #infeasibility(), #feasibleRegion(), and #createBranch(), described below. + + This base class is primarily virtual to allow for any form of structure. + Any form of discontinuity is allowed. + + As there is an overhead in getting information from solvers and because + other useful information is available there is also an OsiBranchingInformation + class which can contain pointers to information. + If used it must at minimum contain pointers to current value of objective, + maximum allowed objective and pointers to arrays for bounds and solution + and direction of optimization. Also integer and primal tolerance. + + Classes which inherit might have other information such as depth, number of + solutions, pseudo-shadow prices etc etc. + May be easier just to throw in here - as I keep doing +*/ +class OsiObject { + +public: + + /// Default Constructor + OsiObject (); + + /// Copy constructor + OsiObject ( const OsiObject &); + + /// Assignment operator + OsiObject & operator=( const OsiObject& rhs); + + /// Clone + virtual OsiObject * clone() const=0; + + /// Destructor + virtual ~OsiObject (); + + /** Infeasibility of the object + + This is some measure of the infeasibility of the object. 0.0 + indicates that the object is satisfied. + + The preferred branching direction is returned in whichWay, where for + normal two-way branching 0 is down, 1 is up + + This is used to prepare for strong branching but should also think of + case when no strong branching + + The object may also compute an estimate of cost of going "up" or "down". + This will probably be based on pseudo-cost ideas + + This should also set mutable infeasibility_ and whichWay_ + This is for instant re-use for speed + + Default for this just calls infeasibility with OsiBranchingInformation + NOTE - Convention says that an infeasibility of COIN_DBL_MAX means + object has worked out it can't be satisfied! + */ + double infeasibility(const OsiSolverInterface * solver,int &whichWay) const ; + // Faster version when more information available + virtual double infeasibility(const OsiBranchingInformation * info, int &whichWay) const =0; + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + */ + virtual double feasibleRegion(OsiSolverInterface * solver) const ; + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + Faster version + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const =0; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * /*solver*/, + const OsiBranchingInformation * /*info*/, + int /*way*/) const {throw CoinError("Need code","createBranch","OsiBranchingObject"); return NULL; } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return true;} + /** \brief Return true if object can take part in move to nearest heuristic + */ + virtual bool canMoveToNearest() const + {return false;} + /** Column number if single column object -1 otherwise, + Used by heuristics + */ + virtual int columnNumber() const; + /// Return Priority - note 1 is highest priority + inline int priority() const + { return priority_;} + /// Set priority + inline void setPriority(int priority) + { priority_ = priority;} + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const + {return true;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} + /// Return maximum number of ways branch may have + inline int numberWays() const + { return numberWays_;} + /// Set maximum number of ways branch may have + inline void setNumberWays(int numberWays) + { numberWays_ = static_cast<short int>(numberWays) ; } + /** Return preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline void setWhichWay(int way) + { whichWay_ = static_cast<short int>(way) ; } + /** Return current preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline int whichWay() const + { return whichWay_;} + /// Get pre-emptive preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return -1;} + /// Return infeasibility + inline double infeasibility() const + { return infeasibility_;} + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * ) {} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int , const int * ) {} + /// Updates stuff like pseudocosts before threads + virtual void updateBefore(const OsiObject * ) {} + /// Updates stuff like pseudocosts after threads finished + virtual void updateAfter(const OsiObject * , const OsiObject * ) {} + +protected: + /// data + + /// Computed infeasibility + mutable double infeasibility_; + /// Computed preferred way to branch + mutable short whichWay_; + /// Maximum number of ways on branch + short numberWays_; + /// Priority + int priority_; + +}; +/// Define a class to add a bit of complexity to OsiObject +/// This assumes 2 way branching + + +class OsiObject2 : public OsiObject { + +public: + + /// Default Constructor + OsiObject2 (); + + /// Copy constructor + OsiObject2 ( const OsiObject2 &); + + /// Assignment operator + OsiObject2 & operator=( const OsiObject2& rhs); + + /// Destructor + virtual ~OsiObject2 (); + + /// Set preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + inline void setPreferredWay(int value) + {preferredWay_=value;} + + /// Get preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return preferredWay_;} +protected: + /// Preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + int preferredWay_; + /// "Infeasibility" on other way + mutable double otherInfeasibility_; + +}; + +/** \brief Abstract branching object base class + + In the abstract, an OsiBranchingObject contains instructions for how to + branch. We want an abstract class so that we can describe how to branch on + simple objects (<i>e.g.</i>, integers) and more exotic objects + (<i>e.g.</i>, cliques or hyperplanes). + + The #branch() method is the crucial routine: it is expected to be able to + step through a set of branch arms, executing the actions required to create + each subproblem in turn. The base class is primarily virtual to allow for + a wide range of problem modifications. + + See OsiObject for an overview of the two classes (OsiObject and + OsiBranchingObject) which make up Osi's branching + model. +*/ + +class OsiBranchingObject { + +public: + + /// Default Constructor + OsiBranchingObject (); + + /// Constructor + OsiBranchingObject (OsiSolverInterface * solver, double value); + + /// Copy constructor + OsiBranchingObject ( const OsiBranchingObject &); + + /// Assignment operator + OsiBranchingObject & operator=( const OsiBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const=0; + + /// Destructor + virtual ~OsiBranchingObject (); + + /// The number of branch arms created for this branching object + inline int numberBranches() const + {return numberBranches_;} + + /// The number of branch arms left for this branching object + inline int numberBranchesLeft() const + {return numberBranches_-branchIndex_;} + + /// Increment the number of branch arms left for this branching object + inline void incrementNumberBranchesLeft() + { numberBranches_ ++;} + + /** Set the number of branch arms left for this branching object + Just for forcing + */ + inline void setNumberBranchesLeft(int /*value*/) + {/*assert (value==1&&!branchIndex_);*/ numberBranches_=1;} + + /// Decrement the number of branch arms left for this branching object + inline void decrementNumberBranchesLeft() + {branchIndex_++;} + + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch() {return branch(NULL);} + /** \brief Return true if branch should fix variables + */ + virtual bool boundBranch() const + {return true;} + /** Get the state of the branching object + This is just the branch index + */ + inline int branchIndex() const + {return branchIndex_;} + + /** Set the state of the branching object. + */ + inline void setBranchingIndex(int branchIndex) + { branchIndex_ = static_cast<short int>(branchIndex) ; } + + /// Current value + inline double value() const + {return value_;} + + /// Return pointer back to object which created + inline const OsiObject * originalObject() const + {return originalObject_;} + /// Set pointer back to object which created + inline void setOriginalObject(const OsiObject * object) + {originalObject_=object;} + /** Double checks in case node can change its mind! + Returns objective value + Can change objective etc */ + virtual void checkIsCutoff(double ) {} + /// For debug + int columnNumber() const; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * =NULL) const {} + +protected: + + /// Current value - has some meaning about branch + double value_; + + /// Pointer back to object which created + const OsiObject * originalObject_; + + /** Number of branches + */ + int numberBranches_; + + /** The state of the branching object. i.e. branch index + This starts at 0 when created + */ + short branchIndex_; + +}; +/* This contains information + This could also contain pseudo shadow prices + or information for dealing with computing and trusting pseudo-costs +*/ +class OsiBranchingInformation { + +public: + + /// Default Constructor + OsiBranchingInformation (); + + /** Useful Constructor + (normalSolver true if has matrix etc etc) + copySolution true if constructot should make a copy + */ + OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false); + + /// Copy constructor + OsiBranchingInformation ( const OsiBranchingInformation &); + + /// Assignment operator + OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs); + + /// Clone + virtual OsiBranchingInformation * clone() const; + + /// Destructor + virtual ~OsiBranchingInformation (); + + // Note public +public: + /// data + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// Value of objective function (in minimization sense) + double objectiveValue_; + /// Value of objective cutoff (in minimization sense) + double cutoff_; + /// Direction 1.0 for minimization, -1.0 for maximization + double direction_; + /// Integer tolerance + double integerTolerance_; + /// Primal tolerance + double primalTolerance_; + /// Maximum time remaining before stopping on time + double timeRemaining_; + /// Dual to use if row bound violated (if negative then pseudoShadowPrices off) + double defaultDual_; + /// Pointer to solver + mutable const OsiSolverInterface * solver_; + /// The number of columns + int numberColumns_; + /// Pointer to current lower bounds on columns + mutable const double * lower_; + /// Pointer to current solution + mutable const double * solution_; + /// Pointer to current upper bounds on columns + mutable const double * upper_; + /// Highly optional target (hot start) solution + const double * hotstartSolution_; + /// Pointer to duals + const double * pi_; + /// Pointer to row activity + const double * rowActivity_; + /// Objective + const double * objective_; + /// Pointer to current lower bounds on rows + const double * rowLower_; + /// Pointer to current upper bounds on rows + const double * rowUpper_; + /// Elements in column copy of matrix + const double * elementByColumn_; + /// Column starts + const CoinBigIndex * columnStart_; + /// Column lengths + const int * columnLength_; + /// Row indices + const int * row_; + /** Useful region of length CoinMax(numberColumns,2*numberRows) + This is allocated and deleted before OsiObject::infeasibility + It is zeroed on entry and should be so on exit + It only exists if defaultDual_>=0.0 + */ + double * usefulRegion_; + /// Useful index region to go with usefulRegion_ + int * indexRegion_; + /// Number of solutions found + int numberSolutions_; + /// Number of branching solutions found (i.e. exclude heuristics) + int numberBranchingSolutions_; + /// Depth in tree + int depth_; + /// TEMP + bool owningSolution_; +}; + +/// This just adds two-wayness to a branching object + +class OsiTwoWayBranchingObject : public OsiBranchingObject { + +public: + + /// Default constructor + OsiTwoWayBranchingObject (); + + /** Create a standard tw0-way branch object + + Specifies a simple two-way branch. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject, + int way , double value) ; + + /// Copy constructor + OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &); + + /// Assignment operator + OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs); + + /// Destructor + virtual ~OsiTwoWayBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + + inline int firstBranch() const { return firstBranch_; } + /// Way returns -1 on down +1 on up + inline int way() const + { return !branchIndex_ ? firstBranch_ : -firstBranch_;} +protected: + /// Which way was first branch -1 = down, +1 = up + int firstBranch_; +}; +/// Define a single integer class + + +class OsiSimpleInteger : public OsiObject2 { + +public: + + /// Default Constructor + OsiSimpleInteger (); + + /// Useful constructor - passed solver index + OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleInteger (int iColumn, double lower, double upper); + + /// Copy constructor + OsiSimpleInteger ( const OsiSimpleInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs); + + /// Destructor + virtual ~OsiSimpleInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + + /// Original bounds + inline double originalLowerBound() const + { return originalLower_;} + inline void setOriginalLowerBound(double value) + { originalLower_=value;} + inline double originalUpperBound() const + { return originalUpper_;} + inline void setOriginalUpperBound(double value) + { originalUpper_=value;} + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * solver) ; + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} +protected: + /// data + /// Original lower bound + double originalLower_; + /// Original upper bound + double originalUpper_; + /// Column number in solver + int columnNumber_; + +}; +/** Simple branching object for an integer variable + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. 0 -> down, 1-> up. +*/ + +class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiIntegerBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value) ; + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch in a more flexible way. One arm of the + branch will be lb <= x <= downUpperBound, the other upLowerBound <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value, double downUpperBound, double upLowerBound) ; + + /// Copy constructor + OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &); + + /// Assignment operator + OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiIntegerBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + // Probably could get away with just value which is already stored + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; + + +/** Define Special Ordered Sets of type 1 and 2. These do not have to be + integer - so do not appear in lists of integers. + + which_ points columns of matrix +*/ + + +class OsiSOS : public OsiObject2 { + +public: + + // Default Constructor + OsiSOS (); + + /** Useful constructor - which are indices + and weights are also given. If null then 0,1,2.. + type is SOS type + */ + OsiSOS (const OsiSolverInterface * solver, int numberMembers, + const int * which, const double * weights, int type=1); + + // Copy constructor + OsiSOS ( const OsiSOS &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiSOS & operator=( const OsiSOS& rhs); + + // Destructor + virtual ~OsiSOS (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of members + inline int numberMembers() const + {return numberMembers_;} + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const + {return members_;} + + /// SOS type + inline int sosType() const + {return sosType_;} + + /// SOS type + inline int setType() const + {return sosType_;} + + /** Array of weights */ + inline const double * weights() const + { return weights_;} + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return (sosType_==1&&integerValued_);} + /// Set whether set is integer valued or not + inline void setIntegerValued(bool yesNo) + { integerValued_=yesNo;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /// Set number of members + inline void setNumberMembers(int value) + {numberMembers_=value;} + + /// Members (indices in range 0 ... numberColumns-1) + inline int * mutableMembers() const + {return members_;} + + /// Set SOS type + inline void setSosType(int value) + {sosType_=value;} + + /** Array of weights */ + inline double * mutableWeights() const + { return weights_;} +protected: + /// data + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /// Weights + double * weights_; + + /// Number of members + int numberMembers_; + /// SOS type + int sosType_; + /// Whether integer valued + bool integerValued_; +}; + +/** Branching object for Special ordered sets + + */ +class OsiSOSBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiSOSBranchingObject (); + + // Useful constructor + OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject, + int way, + double separator); + + // Copy constructor + OsiSOSBranchingObject ( const OsiSOSBranchingObject &); + + // Assignment operator + OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiSOSBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); +private: + /// data +}; +/** Lotsize class */ + + +class OsiLotsize : public OsiObject2 { + +public: + + // Default Constructor + OsiLotsize (); + + /* Useful constructor - passed model index. + Also passed valid values - if range then pairs + */ + OsiLotsize (const OsiSolverInterface * solver, int iColumn, + int numberPoints, const double * points, bool range=false); + + // Copy constructor + OsiLotsize ( const OsiLotsize &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLotsize & operator=( const OsiLotsize& rhs); + + // Destructor + virtual ~OsiLotsize (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(const OsiSolverInterface * solver); + + /** Finds range of interest so value is feasible in range range_ or infeasible + between hi[range_] and lo[range_+1]. Returns true if feasible. + */ + bool findRange(double value, double integerTolerance) const; + + /** Returns floor and ceiling + */ + virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value, + double tolerance) const; + + /// Original bounds + inline double originalLowerBound() const + { return bound_[0];} + inline double originalUpperBound() const + { return bound_[rangeType_*numberRanges_-1];} + /// Type - 1 points, 2 ranges + inline int rangeType() const + { return rangeType_;} + /// Number of points + inline int numberRanges() const + { return numberRanges_;} + /// Ranges + inline double * bound() const + { return bound_;} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return false;} + +private: + /// data + + /// Column number in model + int columnNumber_; + /// Type - 1 points, 2 ranges + int rangeType_; + /// Number of points + int numberRanges_; + // largest gap + double largestGap_; + /// Ranges + double * bound_; + /// Current range + mutable int range_; +}; + + +/** Lotsize branching object + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiLotsizeBranchingObject (); + + /** Create a lotsize floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= valid range below(x*), the other valid range above(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject, + int way , double value) ; + + /// Copy constructor + OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &); + + /// Assignment operator + OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiLotsizeBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiCbcSolverInterface.hpp b/thirdparty/linux/include/coin/coin/OsiCbcSolverInterface.hpp new file mode 100644 index 0000000..3250a00 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiCbcSolverInterface.hpp @@ -0,0 +1,764 @@ +// $Id: OsiCbcSolverInterface.hpp 1899 2013-04-09 18:12:08Z stefan $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCbcSolverInterface_H +#define OsiCbcSolverInterface_H + +#include <string> +#include <cfloat> +#include <map> +#include "CbcModel.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiSolverInterface.hpp" +#include "CbcStrategy.hpp" +#include "CoinWarmStartBasis.hpp" + +class OsiRowCut; +class OsiClpSolverInterface; +static const double OsiCbcInfinity = COIN_DBL_MAX; + +//############################################################################# + +/** Cbc Solver Interface + +Instantiation of OsiCbcSolverInterface for the Model Algorithm. + +*/ + +class OsiCbcSolverInterface : + virtual public OsiSolverInterface { + friend void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the cbc algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + // Set a hint parameter - overrides OsiSolverInterface + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * otherInformation=NULL); + /// Get a hint parameter + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength, + void *& otherInformation) const; + + using OsiSolverInterface::getHintParam ; + /// Get a hint parameter + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength) const; + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + //@} + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods */ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const; + + /// Get warmstarting information + virtual CoinWarmStart* getWarmStart() const; + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + //@} + + //--------------------------------------------------------------------------- + /**@name Hotstart related methods (primarily used in strong branching). <br> + The user can create a hotstart (a snapshot) of the optimization process + then reoptimize over and over again always starting from there.<br> + <strong>NOTE</strong>: between hotstarted optimizations only + bound changes are allowed. */ + //@{ + /// Create a hotstart point of the optimization process + virtual void markHotStart(); + /// Optimize starting from the hotstart + virtual void solveFromHotStart(); + /// Delete the snapshot + virtual void unmarkHotStart(); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /**@name Methods related to querying the input data */ + //@{ + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + /// Get number of nonzero elements + virtual int getNumElements() const ; + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L' <= constraint + <li>'E' = constraint + <li>'G' >= constraint + <li>'R' ranged constraint + <li>'N' free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const ; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is undefined + </ul> + */ + virtual const double * getRowRange() const ; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const ; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const ; + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const; + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const ; + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. */ + virtual int getIterationCount() const ; + + /** Get as many dual rays as the solver can provide. (In case of proven + primal infeasibility there should be at least one.) + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const; + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const; + + //@} + + /*! \name Methods for row and column names. + + Because OsiCbc is a pass-through class, it's necessary to override any + virtual method in order to be sure we catch an override by the underlying + solver. See the OsiSolverInterface class documentation for detailed + descriptions. + */ + //@{ + + /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn */ + + virtual std::string dfltRowColName(char rc, + int ndx, unsigned digits = 7) const ; + + /*! \brief Return the name of the objective function */ + + virtual std::string getObjName (unsigned maxLen = std::string::npos) const ; + + /*! \brief Set the name of the objective function */ + + virtual void setObjName (std::string name) ; + + /*! \brief Return the name of the row. */ + + virtual std::string getRowName(int rowIndex, + unsigned maxLen = std::string::npos) const ; + + /*! \brief Return a pointer to a vector of row names */ + + virtual const OsiNameVec &getRowNames() ; + + /*! \brief Set a row name */ + + virtual void setRowName(int ndx, std::string name) ; + + /*! \brief Set multiple row names */ + + virtual void setRowNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len row names starting at index tgtStart */ + + virtual void deleteRowNames(int tgtStart, int len) ; + + /*! \brief Return the name of the column */ + + virtual std::string getColName(int colIndex, + unsigned maxLen = std::string::npos) const ; + + /*! \brief Return a pointer to a vector of column names */ + + virtual const OsiNameVec &getColNames() ; + + /*! \brief Set a column name */ + + virtual void setColName(int ndx, std::string name) ; + + /*! \brief Set multiple column names */ + + virtual void setColNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len column names starting at index tgtStart */ + virtual void deleteColNames(int tgtStart, int len) ; + + //@} + + //@} + + //--------------------------------------------------------------------------- + + /**@name Problem modifying methods */ + //@{ + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColLower ; + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColUpper ; + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + virtual void setColBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the type of a single row<br> */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /** Set the bounds on a number of rows simultaneously<br> + The default implementation just invokes setRowLower() and + setRowUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set the type of a number of rows simultaneously<br> + The default implementation just invokes setRowType() + over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>any</em> characteristics changes + @param senseList the new senses + @param rhsList the new right hand sides + @param rangeList the new ranges + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + //@} + + //------------------------------------------------------------------------- + /**@name Integrality related changing methods */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + //@} + + //------------------------------------------------------------------------- + /// Set objective function sense (1 for min (default), -1 for max,) + virtual void setObjSense(double s ); + + /** Set the primal solution column values + + colsol[numcols()] is an array of values of the problem column + variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of colsol() until changed by another call to + setColsol() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setColSolution(const double * colsol); + + /** Set dual solution vector + + rowprice[numrows()] is an array of values of the problem row + dual variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of rowprice() until changed by another call to + setRowprice() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setRowPrice(const double * rowprice); + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem.<br> + Note that if a column is added then by default it will correspond to a + continuous variable. */ + //@{ + using OsiSolverInterface::addCol ; + /** */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, const int * rows, const double * elements, + const double collb, const double colub, + const double obj) ; + + using OsiSolverInterface::addCols ; + /** */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void deleteCols(const int num, const int * colIndices); + + using OsiSolverInterface::addRow ; + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + + using OsiSolverInterface::addRows ; + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + /** */ + virtual void deleteRows(const int num, const int * rowIndices); + + //----------------------------------------------------------------------- + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + This uses array of pointers + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + //@} + //@} + + //--------------------------------------------------------------------------- + +public: + + /**@name Methods to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + using OsiSolverInterface::readMps ; + /** Read an mps file from the given filename (defaults to Osi reader) - returns + number of errors (see OsiMpsReader class) */ + virtual int readMps(const char *filename, + const char *extension = "mps") ; + + /** Write the problem into an mps file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + /** Write the problem into an mps file of the given filename, + names may be null. formatType is + 0 - normal + 1 - extra accuracy + 2 - IEEE hex (later) + + Returns non-zero on I/O error + */ + virtual int writeMpsNative(const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0) const ; + //@} + + /**@name Message handling (extra for Cbc messages). + Normally I presume you would want the same language. + If not then you could use underlying model pointer */ + //@{ + /// Set language + void newLanguage(CoinMessages::Language language); + void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + //@} + //--------------------------------------------------------------------------- + + /**@name Cbc specific public interfaces */ + //@{ + /// Get pointer to Cbc model + inline CbcModel * getModelPtr() const + { return modelPtr_;} + /// Get pointer to underlying solver + inline OsiSolverInterface * getRealSolverPtr() const + { return modelPtr_->solver();} + /// Set cutoff bound on the objective function. + inline void setCutoff(double value) + { modelPtr_->setCutoff(value);} + /// Get the cutoff bound on the objective function - always as minimize + inline double getCutoff() const + { return modelPtr_->getCutoff();} + /// Set the CbcModel::CbcMaxNumNode maximum node limit + inline void setMaximumNodes( int value) + { modelPtr_->setMaximumNodes(value);} + /// Get the CbcModel::CbcMaxNumNode maximum node limit + inline int getMaximumNodes() const + { return modelPtr_->getMaximumNodes();} + /// Set the CbcModel::CbcMaxNumSol maximum number of solutions + inline void setMaximumSolutions( int value) + { modelPtr_->setMaximumSolutions(value);} + /// Get the CbcModel::CbcMaxNumSol maximum number of solutions + inline int getMaximumSolutions() const + { return modelPtr_->getMaximumSolutions();} + /// Set the CbcModel::CbcMaximumSeconds maximum number of seconds + inline void setMaximumSeconds( double value) + { modelPtr_->setMaximumSeconds(value);} + /// Get the CbcModel::CbcMaximumSeconds maximum number of seconds + inline double getMaximumSeconds() const + { return modelPtr_->getMaximumSeconds();} + /// Node limit reached? + inline bool isNodeLimitReached() const + { return modelPtr_->isNodeLimitReached();} + /// Solution limit reached? + inline bool isSolutionLimitReached() const + { return modelPtr_->isSolutionLimitReached();} + /// Get how many Nodes it took to solve the problem. + inline int getNodeCount() const + { return modelPtr_->getNodeCount();} + /// Final status of problem - 0 finished, 1 stopped, 2 difficulties + inline int status() const + { return modelPtr_->status();} + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + //@} + + //--------------------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiCbcSolverInterface (OsiSolverInterface * solver=NULL, + CbcStrategy * strategy=NULL); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiCbcSolverInterface (const OsiCbcSolverInterface &); +#if 0 + /// Borrow constructor - only delete one copy + OsiCbcSolverInterface (CbcModel * rhs, bool reallyOwn=false); + + /// Releases so won't error + void releaseCbc(); +#endif + /// Assignment operator + OsiCbcSolverInterface & operator=(const OsiCbcSolverInterface& rhs); + + /// Destructor + virtual ~OsiCbcSolverInterface (); + + //@} + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to constraint matrix). */ + virtual void applyRowCut(const OsiRowCut& rc); + + /** Apply a column cut (adjust one or more bounds). */ + virtual void applyColCut(const OsiColCut& cc); + //@} + /**@name Protected member data */ + //@{ + /// Cbc model represented by this class instance + mutable CbcModel * modelPtr_; + //@} +}; +// So unit test can find out if NDEBUG set +bool OsiCbcHasNDEBUG(); + +//############################################################################# +/** A function that tests the methods in the OsiCbcSolverInterface class. */ +void OsiCbcSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiChooseVariable.hpp b/thirdparty/linux/include/coin/coin/OsiChooseVariable.hpp new file mode 100644 index 0000000..1613bca --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiChooseVariable.hpp @@ -0,0 +1,534 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiChooseVariable_H +#define OsiChooseVariable_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "OsiBranchingObject.hpp" + +class OsiSolverInterface; +class OsiHotInfo; + +/** This class chooses a variable to branch on + + The base class just chooses the variable and direction without strong branching but it + has information which would normally be used by strong branching e.g. to re-enter + having fixed a variable but using same candidates for strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseVariable (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseVariable (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseVariable (const OsiChooseVariable &); + + /// Assignment operator + OsiChooseVariable & operator= (const OsiChooseVariable& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseVariable (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + /// Returns true if solution looks feasible against given objects + virtual bool feasibleSolution(const OsiBranchingInformation * info, + const double * solution, + int numberObjects, + const OsiObject ** objects); + /// Saves a good solution + void saveSolution(const OsiSolverInterface * solver); + /// Clears out good solution after use + void clearGoodSolution(); + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation( const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif + /// Objective value for feasible solution + inline double goodObjectiveValue() const + { return goodObjectiveValue_;} + /// Estimate of up change or change on chosen if n-way + inline double upChange() const + { return upChange_;} + /// Estimate of down change or max change on other possibilities if n-way + inline double downChange() const + { return downChange_;} + /// Good solution - deleted by finalize + inline const double * goodSolution() const + { return goodSolution_;} + /// Index of chosen object + inline int bestObjectIndex() const + { return bestObjectIndex_;} + /// Set index of chosen object + inline void setBestObjectIndex(int value) + { bestObjectIndex_ = value;} + /// Preferred way of chosen object + inline int bestWhichWay() const + { return bestWhichWay_;} + /// Set preferred way of chosen object + inline void setBestWhichWay(int value) + { bestWhichWay_ = value;} + /// Index of forced object + inline int firstForcedObjectIndex() const + { return firstForcedObjectIndex_;} + /// Set index of forced object + inline void setFirstForcedObjectIndex(int value) + { firstForcedObjectIndex_ = value;} + /// Preferred way of forced object + inline int firstForcedWhichWay() const + { return firstForcedWhichWay_;} + /// Set preferred way of forced object + inline void setFirstForcedWhichWay(int value) + { firstForcedWhichWay_ = value;} + /// Get the number of objects unsatisfied at this node - accurate on first pass + inline int numberUnsatisfied() const + {return numberUnsatisfied_;} + /// Number of objects to choose for strong branching + inline int numberStrong() const + { return numberStrong_;} + /// Set number of objects to choose for strong branching + inline void setNumberStrong(int value) + { numberStrong_ = value;} + /// Number left on strong list + inline int numberOnList() const + { return numberOnList_;} + /// Number of strong branches actually done + inline int numberStrongDone() const + { return numberStrongDone_;} + /// Number of strong iterations actually done + inline int numberStrongIterations() const + { return numberStrongIterations_;} + /// Number of strong branches which changed bounds + inline int numberStrongFixed() const + { return numberStrongFixed_;} + /// List of candidates + inline const int * candidates() const + { return list_;} + /// Trust results from strong branching for changing bounds + inline bool trustStrongForBound() const + { return trustStrongForBound_;} + /// Set trust results from strong branching for changing bounds + inline void setTrustStrongForBound(bool yesNo) + { trustStrongForBound_ = yesNo;} + /// Trust results from strong branching for valid solution + inline bool trustStrongForSolution() const + { return trustStrongForSolution_;} + /// Set trust results from strong branching for valid solution + inline void setTrustStrongForSolution(bool yesNo) + { trustStrongForSolution_ = yesNo;} + /// Set solver and redo arrays + void setSolver (const OsiSolverInterface * solver); + /** Return status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + */ + inline int status() const + { return status_;} + inline void setStatus(int value) + { status_ = value;} + + +protected: + // Data + /// Objective value for feasible solution + double goodObjectiveValue_; + /// Estimate of up change or change on chosen if n-way + double upChange_; + /// Estimate of down change or max change on other possibilities if n-way + double downChange_; + /// Good solution - deleted by finalize + double * goodSolution_; + /// List of candidates + int * list_; + /// Useful array (for sorting etc) + double * useful_; + /// Pointer to solver + const OsiSolverInterface * solver_; + /* Status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + */ + int status_; + /// Index of chosen object + int bestObjectIndex_; + /// Preferred way of chosen object + int bestWhichWay_; + /// Index of forced object + int firstForcedObjectIndex_; + /// Preferred way of forced object + int firstForcedWhichWay_; + /// The number of objects unsatisfied at this node. + int numberUnsatisfied_; + /// Number of objects to choose for strong branching + int numberStrong_; + /// Number left on strong list + int numberOnList_; + /// Number of strong branches actually done + int numberStrongDone_; + /// Number of strong iterations actually done + int numberStrongIterations_; + /// Number of bound changes due to strong branching + int numberStrongFixed_; + /// List of unsatisfied objects - first numberOnList_ for strong branching + /// Trust results from strong branching for changing bounds + bool trustStrongForBound_; + /// Trust results from strong branching for valid solution + bool trustStrongForSolution_; +}; + +/** This class is the placeholder for the pseudocosts used by OsiChooseStrong. + It can also be used by any other pseudocost based strong branching + algorithm. +*/ + +class OsiPseudoCosts { +protected: + // Data + /// Total of all changes up + double * upTotalChange_; + /// Total of all changes down + double * downTotalChange_; + /// Number of times up + int * upNumber_; + /// Number of times down + int * downNumber_; + /// Number of objects (could be found from solver) + int numberObjects_; + /// Number before we trust + int numberBeforeTrusted_; + +private: + void gutsOfDelete(); + void gutsOfCopy(const OsiPseudoCosts& rhs); + +public: + OsiPseudoCosts(); + virtual ~OsiPseudoCosts(); + OsiPseudoCosts(const OsiPseudoCosts& rhs); + OsiPseudoCosts& operator=(const OsiPseudoCosts& rhs); + + /// Number of times before trusted + inline int numberBeforeTrusted() const + { return numberBeforeTrusted_; } + /// Set number of times before trusted + inline void setNumberBeforeTrusted(int value) + { numberBeforeTrusted_ = value; } + /// Initialize the pseudocosts with n entries + void initialize(int n); + /// Give the number of objects for which pseudo costs are stored + inline int numberObjects() const + { return numberObjects_; } + + /** @name Accessor methods to pseudo costs data */ + //@{ + inline double* upTotalChange() { return upTotalChange_; } + inline const double* upTotalChange() const { return upTotalChange_; } + + inline double* downTotalChange() { return downTotalChange_; } + inline const double* downTotalChange() const { return downTotalChange_; } + + inline int* upNumber() { return upNumber_; } + inline const int* upNumber() const { return upNumber_; } + + inline int* downNumber() { return downNumber_; } + inline const int* downNumber() const { return downNumber_; } + //@} + + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation(const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif +}; + +/** This class chooses a variable to branch on + + This chooses the variable and direction with reliability strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseStrong : public OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseStrong (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrong (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrong (const OsiChooseStrong &); + + /// Assignment operator + OsiChooseStrong & operator= (const OsiChooseStrong& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrong (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /** Pseudo Shadow Price mode + 0 - off + 1 - use if no strong info + 2 - use if strong not trusted + 3 - use even if trusted + */ + inline int shadowPriceMode() const + { return shadowPriceMode_;} + /// Set Shadow price mode + inline void setShadowPriceMode(int value) + { shadowPriceMode_ = value;} + + /** Accessor method to pseudo cost object*/ + const OsiPseudoCosts& pseudoCosts() const + { return pseudoCosts_; } + + /** Accessor method to pseudo cost object*/ + OsiPseudoCosts& pseudoCosts() + { return pseudoCosts_; } + + /** A feww pass-through methods to access members of pseudoCosts_ as if they + were members of OsiChooseStrong object */ + inline int numberBeforeTrusted() const { + return pseudoCosts_.numberBeforeTrusted(); } + inline void setNumberBeforeTrusted(int value) { + pseudoCosts_.setNumberBeforeTrusted(value); } + inline int numberObjects() const { + return pseudoCosts_.numberObjects(); } + +protected: + + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + int doStrongBranching( OsiSolverInterface * solver, + OsiBranchingInformation *info, + int numberToDo, int returnCriterion); + + /** Clear out the results array */ + void resetResults(int num); + +protected: + /** Pseudo Shadow Price mode + 0 - off + 1 - use and multiply by strong info + 2 - use + */ + int shadowPriceMode_; + + /** The pseudo costs for the chooser */ + OsiPseudoCosts pseudoCosts_; + + /** The results of the strong branching done on the candidates where the + pseudocosts were not sufficient */ + OsiHotInfo* results_; + /** The number of OsiHotInfo objetcs that contain information */ + int numResults_; +}; + +/** This class contains the result of strong branching on a variable + When created it stores enough information for strong branching +*/ + +class OsiHotInfo { + +public: + + /// Default Constructor + OsiHotInfo (); + + /// Constructor from useful information + OsiHotInfo ( OsiSolverInterface * solver, + const OsiBranchingInformation *info, + const OsiObject * const * objects, + int whichObject); + + /// Copy constructor + OsiHotInfo (const OsiHotInfo &); + + /// Assignment operator + OsiHotInfo & operator= (const OsiHotInfo& rhs); + + /// Clone + virtual OsiHotInfo * clone() const; + + /// Destructor + virtual ~OsiHotInfo (); + + /** Fill in useful information after strong branch. + Return status + */ + int updateInformation( const OsiSolverInterface * solver, const OsiBranchingInformation * info, + OsiChooseVariable * choose); + /// Original objective value + inline double originalObjectiveValue() const + { return originalObjectiveValue_;} + /// Up change - invalid if n-way + inline double upChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[1];} + /// Down change - invalid if n-way + inline double downChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[0];} + /// Set up change - invalid if n-way + inline void setUpChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[1] = value;} + /// Set down change - invalid if n-way + inline void setDownChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[0] = value;} + /// Change on way k + inline double change(int k) const + { return changes_[k];} + + /// Up iteration count - invalid if n-way + inline int upIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[1];} + /// Down iteration count - invalid if n-way + inline int downIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[0];} + /// Iteration count on way k + inline int iterationCount(int k) const + { return iterationCounts_[k];} + + /// Up status - invalid if n-way + inline int upStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[1];} + /// Down status - invalid if n-way + inline int downStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[0];} + /// Set up status - invalid if n-way + inline void setUpStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[1] = value;} + /// Set down status - invalid if n-way + inline void setDownStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[0] = value;} + /// Status on way k + inline int status(int k) const + { return statuses_[k];} + /// Branching object + inline OsiBranchingObject * branchingObject() const + { return branchingObject_;} + inline int whichObject() const + { return whichObject_;} + +protected: + // Data + /// Original objective value + double originalObjectiveValue_; + /// Objective changes + double * changes_; + /// Iteration counts + int * iterationCounts_; + /** Status + -1 - not done + 0 - feasible and finished + 1 - infeasible + 2 - not finished + */ + int * statuses_; + /// Branching object + OsiBranchingObject * branchingObject_; + /// Which object on list + int whichObject_; +}; + + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiClpSolverInterface.hpp b/thirdparty/linux/include/coin/coin/OsiClpSolverInterface.hpp new file mode 100644 index 0000000..ebc7e64 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiClpSolverInterface.hpp @@ -0,0 +1,1509 @@ +// $Id$ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef OsiClpSolverInterface_H +#define OsiClpSolverInterface_H + +#include <string> +#include <cfloat> +#include <map> + +#include "ClpSimplex.hpp" +#include "ClpLinearObjective.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiSolverInterface.hpp" +#include "CoinWarmStartBasis.hpp" +#include "ClpEventHandler.hpp" +#include "ClpNode.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFinite.hpp" + +class OsiRowCut; +class OsiClpUserSolver; +class OsiClpDisasterHandler; +class CoinSet; +static const double OsiClpInfinity = COIN_DBL_MAX; + +//############################################################################# + +/** Clp Solver Interface + +Instantiation of OsiClpSolverInterface for the Model Algorithm. + +*/ + +class OsiClpSolverInterface : + virtual public OsiSolverInterface { + friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /// Resolve an LP relaxation after problem modification (try GUB) + virtual void resolveGub(int needed); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + + /** Solve when primal column and dual row solutions are near-optimal + options - 0 no presolve (use primal and dual) + 1 presolve (just use primal) + 2 no presolve (just use primal) + basis - 0 use all slack basis + 1 try and put some in basis + */ + void crossover(int options,int basis); + //@} + + /*! @name OsiSimplexInterface methods + \brief Methods for the Osi Simplex API. + + The current implementation should work for both minimisation and + maximisation in mode 1 (tableau access). In mode 2 (single pivot), only + minimisation is supported as of 100907. + */ + //@{ + /** \brief Simplex API capability. + + Returns + - 0 if no simplex API + - 1 if can just do getBInv etc + - 2 if has all OsiSimplex methods + */ + virtual int canDoSimplexInterface() const; + + /*! \brief Enables simplex mode 1 (tableau access) + + Tells solver that calls to getBInv etc are about to take place. + Underlying code may need mutable as this may be called from + CglCut::generateCuts which is const. If that is too horrific then + each solver e.g. BCP or CBC will have to do something outside + main loop. + */ + virtual void enableFactorization() const; + + /*! \brief Undo any setting changes made by #enableFactorization */ + virtual void disableFactorization() const; + + /** Returns true if a basis is available + AND problem is optimal. This should be used to see if + the BInvARow type operations are possible and meaningful. + */ + virtual bool basisIsAvailable() const; + + /** The following two methods may be replaced by the + methods of OsiSolverInterface using OsiWarmStartBasis if: + 1. OsiWarmStartBasis resize operation is implemented + more efficiently and + 2. It is ensured that effects on the solver are the same + + Returns a basis status of the structural/artificial variables + At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + virtual void getBasisStatus(int* cstat, int* rstat) const; + + /** Set the status of structural/artificial variables and + factorize, update solution etc + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ... + */ + virtual int setBasisStatus(const int* cstat, const int* rstat); + + ///Get the reduced gradient for the cost vector c + virtual void getReducedGradient(double* columnReducedCosts, + double * duals, + const double * c) const ; + + ///Get a row of the tableau (slack part in slack if not NULL) + virtual void getBInvARow(int row, double* z, double * slack=NULL) const; + + /** Get a row of the tableau (slack part in slack if not NULL) + If keepScaled is true then scale factors not applied after so + user has to use coding similar to what is in this method + */ + virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=NULL, + bool keepScaled=false) const; + + ///Get a row of the basis inverse + virtual void getBInvRow(int row, double* z) const; + + ///Get a column of the tableau + virtual void getBInvACol(int col, double* vec) const ; + + ///Get a column of the tableau + virtual void getBInvACol(int col, CoinIndexedVector * vec) const ; + + /** Update (i.e. ftran) the vector passed in. + Unscaling is applied after - can't be applied before + */ + + virtual void getBInvACol(CoinIndexedVector * vec) const ; + + ///Get a column of the basis inverse + virtual void getBInvCol(int col, double* vec) const ; + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + virtual void getBasics(int* index) const; + + /*! \brief Enables simplex mode 2 (individual pivot control) + + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. + */ + virtual void enableSimplexInterface(bool doingPrimal); + /// Copy across enabled stuff from one solver to another + void copyEnabledSuff(OsiClpSolverInterface & rhs); + + /*! \brief Undo setting changes made by #enableSimplexInterface */ + virtual void disableSimplexInterface(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(ClpSimplex & rhs); + + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in statOut. Where + 1 is to upper bound, -1 to lower bound + Return code is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus); + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx); + + + //@} + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the clp algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + // Set a hint parameter - overrides OsiSolverInterface + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * otherInformation=NULL); + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + //@} + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods */ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const; + + /// Get warmstarting information + virtual CoinWarmStart* getWarmStart() const; + /// Get warmstarting information + inline CoinWarmStartBasis* getPointerToWarmStart() + { return &basis_;} + /// Get warmstarting information + inline const CoinWarmStartBasis* getConstPointerToWarmStart() const + { return &basis_;} + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + OsiClp version always returns pointer and false. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /// Set column status in ClpSimplex and warmStart + void setColumnStatus(int iColumn, ClpSimplex::Status status); + + //@} + + //--------------------------------------------------------------------------- + /**@name Hotstart related methods (primarily used in strong branching). + The user can create a hotstart (a snapshot) of the optimization process + then reoptimize over and over again always starting from there.<br> + <strong>NOTE</strong>: between hotstarted optimizations only + bound changes are allowed. */ + //@{ + /// Create a hotstart point of the optimization process + virtual void markHotStart(); + /// Optimize starting from the hotstart + virtual void solveFromHotStart(); + /// Delete the snapshot + virtual void unmarkHotStart(); + /** Start faster dual - returns negative if problems 1 if infeasible, + Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + When set resolve does less work + */ + int startFastDual(int options); + /// Stop fast dual + void stopFastDual(); + /// Sets integer tolerance and increment + void setStuff(double tolerance,double increment); + /// Return a conflict analysis cut from small model + OsiRowCut * smallModelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + /** Return a conflict analysis cut from model + If type is 0 then genuine cut, if 1 then only partially processed + */ + OsiRowCut * modelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /**@name Methods related to querying the input data */ + //@{ + /// Get number of columns + virtual int getNumCols() const { + return modelPtr_->numberColumns(); } + + /// Get number of rows + virtual int getNumRows() const { + return modelPtr_->numberRows(); } + + /// Get number of nonzero elements + virtual int getNumElements() const { + int retVal = 0; + const CoinPackedMatrix * matrix =modelPtr_->matrix(); + if ( matrix != NULL ) retVal=matrix->getNumElements(); + return retVal; } + + /// Return name of row if one exists or Rnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const; + + /// Return name of column if one exists or Cnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const; + + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const { return modelPtr_->columnLower(); } + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const { return modelPtr_->columnUpper(); } + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L' <= constraint + <li>'E' = constraint + <li>'G' >= constraint + <li>'R' ranged constraint + <li>'N' free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const ; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is undefined + </ul> + */ + virtual const double * getRowRange() const ; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const { return modelPtr_->rowLower(); } + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const { return modelPtr_->rowUpper(); } + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const + { if (fakeMinInSimplex_) + return linearObjective_ ; + else + return modelPtr_->objective(); } + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const + { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection(): + modelPtr_->optimizationDirection()); } + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + /// Return true if variable is binary + virtual bool isBinary(int colIndex) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if variable is binary and not fixed at either bound + virtual bool isFreeBinary(int colIndex) const; + /** Return array of column length + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + virtual const char * getColType(bool refresh=false) const; + + /** Return true if column is integer but does not have to + be declared as such. + Note: This function returns true if the the column + is binary or a general integer. + */ + bool isOptionalInteger(int colIndex) const; + /** Set the index-th variable to be an optional integer variable */ + void setOptionalInteger(int index); + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get pointer to mutable column-wise copy of matrix + virtual CoinPackedMatrix * getMutableMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const { return OsiClpInfinity; } + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. */ + virtual int getIterationCount() const + { return modelPtr_->numberIterations(); } + + /** Get as many dual rays as the solver can provide. (In case of proven + primal infeasibility there should be at least one.) + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const; + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const; + + //@} + //@} + + //--------------------------------------------------------------------------- + + /**@name Problem modifying methods */ + //@{ + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + virtual void setColBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the type of a single row<br> */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /** Set the bounds on a number of rows simultaneously<br> + The default implementation just invokes setRowLower() and + setRowUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set the type of a number of rows simultaneously<br> + The default implementation just invokes setRowType() + over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>any</em> characteristics changes + @param senseList the new senses + @param rhsList the new right hand sides + @param rangeList the new ranges + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + /** Set the objective coefficients for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the lower bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set the upper bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + +// using OsiSolverInterface::setRowName ; + /// Set name of row +// virtual void setRowName(int rowIndex, std::string & name) ; + virtual void setRowName(int rowIndex, std::string name) ; + +// using OsiSolverInterface::setColName ; + /// Set name of column +// virtual void setColName(int colIndex, std::string & name) ; + virtual void setColName(int colIndex, std::string name) ; + + //@} + + //------------------------------------------------------------------------- + /**@name Integrality related changing methods */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + /// Number of SOS sets + inline int numberSOS() const + { return numberSOS_;} + /// SOS set info + inline const CoinSet * setInfo() const + { return setInfo_;} + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + //@} + + //------------------------------------------------------------------------- + /// Set objective function sense (1 for min (default), -1 for max,) + virtual void setObjSense(double s ) + { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); } + + /** Set the primal solution column values + + colsol[numcols()] is an array of values of the problem column + variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of colsol() until changed by another call to + setColsol() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setColSolution(const double * colsol); + + /** Set dual solution vector + + rowprice[numrows()] is an array of values of the problem row + dual variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of rowprice() until changed by another call to + setRowprice() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setRowPrice(const double * rowprice); + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem.<br> + Note that if a column is added then by default it will correspond to a + continuous variable. */ + //@{ + + //using OsiSolverInterface::addCol ; + /** */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, const int * rows, const double * elements, + const double collb, const double colub, + const double obj) ; + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + /** */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void addCols(const int numcols, + const int * columnStarts, const int * rows, const double * elements, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void deleteCols(const int num, const int * colIndices); + + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + /** Add a row (constraint) to the problem. */ + virtual void addRow(int numberElements, const int * columns, const double * element, + const double rowlb, const double rowub) ; + /*! \brief Add a named row (constraint) to the problem. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** */ + virtual void addRows(const int numrows, + const int * rowStarts, const int * columns, const double * element, + const double* rowlb, const double* rowub); + /// + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false) + {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);} + + /** */ + virtual void deleteRows(const int num, const int * rowIndices); + /** If solver wants it can save a copy of "base" (continuous) model here + */ + virtual void saveBaseModel() ; + /** Strip off rows to get to this number of rows. + If solver wants it can restore a copy of "base" (continuous) model here + */ + virtual void restoreBaseModel(int numberRows); + + //----------------------------------------------------------------------- + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + This uses array of pointers + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + /** Apply a collection of cuts. + + Only cuts which have an <code>effectiveness >= effectivenessLb</code> + are applied. + <ul> + <li> ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + <code>effectiveness < effectivenessLb</code> + <li> ReturnCode.getNuminconsistent() -- number of invalid cuts + <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model + <li> ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible + <li> ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model + <li> cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() + </ul> + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + //@} + //@} + + //--------------------------------------------------------------------------- + +public: + + /**@name Methods to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given as a ClpMatrixBase. */ + virtual void loadProblem(const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + /// This loads a model from a coinModel object - returns number of errors + virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false); + + using OsiSolverInterface::readMps ; + /** Read an mps file from the given filename (defaults to Osi reader) - returns + number of errors (see OsiMpsReader class) */ + virtual int readMps(const char *filename, + const char *extension = "mps") ; + /** Read an mps file from the given filename returns + number of errors (see OsiMpsReader class) */ + int readMps(const char *filename,bool keepNames,bool allowErrors); + /// Read an mps file + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /** Write the problem into an mps file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + /** Write the problem into an mps file of the given filename, + names may be null. formatType is + 0 - normal + 1 - extra accuracy + 2 - IEEE hex (later) + + Returns non-zero on I/O error + */ + virtual int writeMpsNative(const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0) const ; + /// Read file in LP format (with names) + virtual int readLp(const char *filename, const double epsilon = 1e-5); + /** Write the problem into an Lp file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants. + This version calls writeLpNative with names */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would not matter + e.g. strengthening a matrix for MIP + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix); + /// And if it does matter (not used at present) + virtual void replaceMatrix(const CoinPackedMatrix & matrix) ; + //@} + + /**@name Message handling (extra for Clp messages). + Normally I presume you would want the same language. + If not then you could use underlying model pointer */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Set log level (will also set underlying solver's log level) + void setLogLevel(int value); + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + //@} + //--------------------------------------------------------------------------- + + /**@name Clp specific public interfaces */ + //@{ + /// Get pointer to Clp model + ClpSimplex * getModelPtr() const ; + /// Set pointer to Clp model and return old + inline ClpSimplex * swapModelPtr(ClpSimplex * newModel) + { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;} + /// Get special options + inline unsigned int specialOptions() const + { return specialOptions_;} + void setSpecialOptions(unsigned int value); + /// Last algorithm used , 1 = primal, 2 = dual other unknown + inline int lastAlgorithm() const + { return lastAlgorithm_;} + /// Set last algorithm used , 1 = primal, 2 = dual other unknown + inline void setLastAlgorithm(int value) + { lastAlgorithm_ = value;} + /// Get scaling action option + inline int cleanupScaling() const + { return cleanupScaling_;} + /** Set Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + inline void setCleanupScaling(int value) + { cleanupScaling_=value;} + /** Get smallest allowed element in cut. + If smaller than this then ignored */ + inline double smallestElementInCut() const + { return smallestElementInCut_;} + /** Set smallest allowed element in cut. + If smaller than this then ignored */ + inline void setSmallestElementInCut(double value) + { smallestElementInCut_=value;} + /** Get smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline double smallestChangeInCut() const + { return smallestChangeInCut_;} + /** Set smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline void setSmallestChangeInCut(double value) + { smallestChangeInCut_=value;} + /// Pass in initial solve options + inline void setSolveOptions(const ClpSolve & options) + { solveOptions_ = options;} + /** Tighten bounds - lightweight or very lightweight + 0 - normal, 1 lightweight but just integers, 2 lightweight and all + */ + virtual int tightenBounds(int lightweight=0); + /// See if any integer variables make infeasible other way + int infeasibleOtherWay(char * whichWay); + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; + /// Get disaster handler + const OsiClpDisasterHandler * disasterHandler() const + { return disasterHandler_;} + /// Pass in disaster handler + void passInDisasterHandler(OsiClpDisasterHandler * handler); + /// Get fake objective + ClpLinearObjective * fakeObjective() const + { return fakeObjective_;} + /// Set fake objective (and take ownership) + void setFakeObjective(ClpLinearObjective * fakeObjective); + /// Set fake objective + void setFakeObjective(double * fakeObjective); + /*! \brief Set up solver for repeated use by Osi interface. + + The normal usage does things like keeping factorization around so can be + used. Will also do things like keep scaling and row copy of matrix if + matrix does not change. + + \p senseOfAdventure: + - 0 - safe stuff as above + - 1 - will take more risks - if it does not work then bug which will be + fixed + - 2 - don't bother doing most extreme termination checks e.g. don't bother + re-factorizing if less than 20 iterations. + - 3 - Actually safer than 1 (mainly just keeps factorization) + + \p printOut + - -1 always skip round common messages instead of doing some work + - 0 skip if normal defaults + - 1 leaves + */ + void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0); + /// Synchronize model (really if no cuts in tree) + virtual void synchronizeModel(); + /*! \brief Set special options in underlying clp solver. + + Safe as const because #modelPtr_ is mutable. + */ + void setSpecialOptionsMutable(unsigned int value) const; + + //@} + + //--------------------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiClpSolverInterface (); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiClpSolverInterface (const OsiClpSolverInterface &); + + /// Borrow constructor - only delete one copy + OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false); + + /// Releases so won't error + void releaseClp(); + + /// Assignment operator + OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs); + + /// Destructor + virtual ~OsiClpSolverInterface (); + + /// Resets as if default constructor + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to constraint matrix). */ + virtual void applyRowCut(const OsiRowCut& rc); + + /** Apply a column cut (adjust one or more bounds). */ + virtual void applyColCut(const OsiColCut& cc); + //@} + + //--------------------------------------------------------------------------- + +protected: + /**@name Protected methods */ + //@{ + /// The real work of a copy constructor (used by copy and assignment) + void gutsOfDestructor(); + + /// Deletes all mutable stuff + void freeCachedResults() const; + + /// Deletes all mutable stuff for row ranges etc + void freeCachedResults0() const; + + /// Deletes all mutable stuff for matrix etc + void freeCachedResults1() const; + + /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays + void extractSenseRhsRange() const; + + /// + void fillParamMaps(); + /** Warm start + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + CoinWarmStartBasis getBasis(ClpSimplex * model) const; + /** Sets up working basis as a copy of input + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model); + /// Crunch down problem a bit + void crunch(); + /// Extend scale factors + void redoScaleFactors(int numberRows,const CoinBigIndex * starts, + const int * indices, const double * elements); +public: + /** Sets up working basis as a copy of input and puts in as basis + */ + void setBasis( const CoinWarmStartBasis & basis); + /// Just puts current basis_ into ClpSimplex model + inline void setBasis( ) + { setBasis(basis_,modelPtr_);} + /// Warm start difference from basis_ to statusArray + CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ; + /// Warm start from statusArray + CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ; + /// Delete all scale factor stuff and reset option + void deleteScaleFactors(); + /// If doing fast hot start then ranges are computed + inline const double * upRange() const + { return rowActivity_;} + inline const double * downRange() const + { return columnActivity_;} + /// Pass in range array + inline void passInRanges(int * array) + { whichRange_=array;} + /// Pass in sos stuff from AMPl + void setSOSData(int numberSOS,const char * type, + const int * start,const int * indices, const double * weights=NULL); + /// Compute largest amount any at continuous away from bound + void computeLargestAway(); + /// Get largest amount continuous away from bound + inline double largestAway() const + { return largestAway_;} + /// Set largest amount continuous away from bound + inline void setLargestAway(double value) + { largestAway_ = value;} + /// Sort of lexicographic resolve + void lexSolve(); + //@} + +protected: + /**@name Protected member data */ + //@{ + /// Clp model represented by this class instance + mutable ClpSimplex * modelPtr_; + //@} + /**@name Cached information derived from the OSL model */ + //@{ + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /** A pointer to the warmstart information to be used in the hotstarts. + This is NOT efficient and more thought should be given to it... */ + mutable CoinWarmStartBasis* ws_; + /** also save row and column information for hot starts + only used in hotstarts so can be casual */ + mutable double * rowActivity_; + mutable double * columnActivity_; + /// Stuff for fast dual + ClpNodeStuff stuff_; + /// Number of SOS sets + int numberSOS_; + /// SOS set info + CoinSet * setInfo_; + /// Alternate model (hot starts) - but also could be permanent and used for crunch + ClpSimplex * smallModel_; + /// factorization for hot starts + ClpFactorization * factorization_; + /** Smallest allowed element in cut. + If smaller than this then ignored */ + double smallestElementInCut_; + /** Smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. */ + double smallestChangeInCut_; + /// Largest amount continuous away from bound + double largestAway_; + /// Arrays for hot starts + char * spareArrays_; + /** Warmstart information to be used in resolves. */ + CoinWarmStartBasis basis_; + /** The original iteration limit before hotstarts started. */ + int itlimOrig_; + + /*! \brief Last algorithm used + + Coded as + - 0 invalid + - 1 primal + - 2 dual + - -911 disaster in the algorithm that was attempted + - 999 current solution no longer optimal due to change in problem or + basis + */ + mutable int lastAlgorithm_; + + /// To say if destructor should delete underlying model + bool notOwned_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to row-wise copy of continuous problem matrix coefficients. + CoinPackedMatrix *matrixByRowAtContinuous_; + + /// Pointer to integer information + char * integerInformation_; + + /** Pointer to variables for which we want range information + The number is in [0] + memory is not owned by OsiClp + */ + int * whichRange_; + + //std::map<OsiIntParam, ClpIntParam> intParamMap_; + //std::map<OsiDblParam, ClpDblParam> dblParamMap_; + //std::map<OsiStrParam, ClpStrParam> strParamMap_; + + /*! \brief Faking min to get proper dual solution signs in simplex API */ + mutable bool fakeMinInSimplex_ ; + /*! \brief Linear objective + + Normally a pointer to the linear coefficient array in the clp objective. + An independent copy when #fakeMinInSimplex_ is true, because we need + something permanent to point to when #getObjCoefficients is called. + */ + mutable double *linearObjective_; + + /// To save data in OsiSimplex stuff + mutable ClpDataSave saveData_; + /// Options for initialSolve + ClpSolve solveOptions_; + /** Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + int cleanupScaling_; + /** Special options + 0x80000000 off + 0 simple stuff for branch and bound + 1 try and keep work regions as much as possible + 2 do not use any perturbation + 4 allow exit before re-factorization + 8 try and re-use factorization if no cuts + 16 use standard strong branching rather than clp's + 32 Just go to first factorization in fast dual + 64 try and tighten bounds in crunch + 128 Model will only change in column bounds + 256 Clean up model before hot start + 512 Give user direct access to Clp regions in getBInvARow etc (i.e., + do not unscale, and do not return result in getBInv parameters; + you have to know where to look for the answer) + 1024 Don't "borrow" model in initialSolve + 2048 Don't crunch + 4096 quick check for optimality + Bits above 8192 give where called from in Cbc + At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check + 65536 Keep simple i.e. no crunch etc + 131072 Try and keep scaling factors around + 262144 Don't try and tighten bounds (funny global cuts) + 524288 Fake objective and 0-1 + 1048576 Don't recompute ray after crunch + 2097152 + */ + mutable unsigned int specialOptions_; + /// Copy of model when option 131072 set + ClpSimplex * baseModel_; + /// Number of rows when last "scaled" + int lastNumberRows_; + /// Continuous model + ClpSimplex * continuousModel_; + /// Possible disaster handler + OsiClpDisasterHandler * disasterHandler_ ; + /// Fake objective + ClpLinearObjective * fakeObjective_; + /// Row scale factors (has inverse at end) + CoinDoubleArrayWithLength rowScale_; + /// Column scale factors (has inverse at end) + CoinDoubleArrayWithLength columnScale_; + //@} +}; + +class OsiClpDisasterHandler : public ClpDisasterHandler { +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex(); + /// Checks if disaster + virtual bool check() const ; + /// saves information for next attempt + virtual void saveInfo(); + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + OsiClpDisasterHandler(OsiClpSolverInterface * model = NULL); + /** Destructor */ + virtual ~OsiClpDisasterHandler(); + // Copy + OsiClpDisasterHandler(const OsiClpDisasterHandler&); + // Assignment + OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setOsiModel(OsiClpSolverInterface * model); + /// Get model + inline OsiClpSolverInterface * osiModel() const + { return osiModel_;} + /// Set where from + inline void setWhereFrom(int value) + { whereFrom_=value;} + /// Get where from + inline int whereFrom() const + { return whereFrom_;} + /// Set phase + inline void setPhase(int value) + { phase_=value;} + /// Get phase + inline int phase() const + { return phase_;} + /// are we in trouble + bool inTrouble() const; + + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to model + OsiClpSolverInterface * osiModel_; + /** Where from + 0 dual (resolve) + 1 crunch + 2 primal (resolve) + 4 dual (initialSolve) + 6 primal (initialSolve) + */ + int whereFrom_; + /** phase + 0 initial + 1 trying continuing with back in and maybe different perturb + 2 trying continuing with back in and different scaling + 3 trying dual from all slack + 4 trying primal from previous stored basis + */ + int phase_; + /// Are we in trouble + bool inTrouble_; + //@} +}; +// So unit test can find out if NDEBUG set +bool OsiClpHasNDEBUG(); +//############################################################################# +/** A function that tests the methods in the OsiClpSolverInterface class. */ +void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiColCut.hpp b/thirdparty/linux/include/coin/coin/OsiColCut.hpp new file mode 100644 index 0000000..c98eb5c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiColCut.hpp @@ -0,0 +1,324 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiColCut_H +#define OsiColCut_H + +#include <string> + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +/** Column Cut Class + +Column Cut Class has: + <ul> + <li>a sparse vector of column lower bounds + <li>a sparse vector of column upper bounds + </ul> +*/ +class OsiColCut : public OsiCut { + friend void OsiColCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + //---------------------------------------------------------------- + + /**@name Setting column bounds */ + //@{ + /// Set column lower bounds + inline void setLbs( + int nElements, + const int * colIndices, + const double * lbElements ); + + /// Set column lower bounds from a packed vector + inline void setLbs( const CoinPackedVector & lbs ); + + /// Set column upper bounds + inline void setUbs( + int nElements, + const int * colIndices, + const double * ubElements ); + + /// Set column upper bounds from a packed vector + inline void setUbs( const CoinPackedVector & ubs ); + //@} + + //---------------------------------------------------------------- + + /**@name Getting column bounds */ + //@{ + /// Get column lower bounds + inline const CoinPackedVector & lbs() const; + /// Get column upper bounds + inline const CoinPackedVector & ubs() const; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bounds, upper bounds, + and OsiCut are equal. + */ + inline virtual bool operator==(const OsiColCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + inline virtual bool operator!=(const OsiColCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself. + This checks to ensure that: + <ul> + <li>The bound vectors do not have duplicate indices, + <li>The bound vectors indices are >=0 + </ul> + */ + inline virtual bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. This checks to ensure that + the lower & upperbound packed vectors: + <ul> + <li>do not have an index >= the number of column is the model. + </ul> + */ + inline virtual bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the cut is infeasible with respect to its bounds and the + column bounds in the solver interface's models. + This checks whether: + <ul> + <li>the maximum of the new and existing lower bounds is strictly + greater than the minimum of the new and existing upper bounds. +</ul> + */ + inline virtual bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + //---------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiColCut & operator=( const OsiColCut& rhs); + + /// Copy constructor + OsiColCut ( const OsiColCut &); + + /// Default Constructor + OsiColCut (); + + /// Clone + virtual OsiColCut * clone() const; + + /// Destructor + virtual ~OsiColCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const; + //@} + +private: + + /**@name Private member data */ + //@{ + /// Lower bounds + CoinPackedVector lbs_; + /// Upper bounds + CoinPackedVector ubs_; + //@} + +}; + + + +//------------------------------------------------------------------- +// Set lower & upper bound vectors +//------------------------------------------------------------------- +void OsiColCut::setLbs( + int size, + const int * colIndices, + const double * lbElements ) +{ + lbs_.setVector(size,colIndices,lbElements); +} +// +void OsiColCut::setUbs( + int size, + const int * colIndices, + const double * ubElements ) +{ + ubs_.setVector(size,colIndices,ubElements); +} +// +void OsiColCut::setLbs( const CoinPackedVector & lbs ) +{ + lbs_ = lbs; +} +// +void OsiColCut::setUbs( const CoinPackedVector & ubs ) +{ + ubs_ = ubs; +} + +//------------------------------------------------------------------- +// Get Column Lower Bounds and Column Upper Bounds +//------------------------------------------------------------------- +const CoinPackedVector & OsiColCut::lbs() const +{ + return lbs_; +} +// +const CoinPackedVector & OsiColCut::ubs() const +{ + return ubs_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiColCut::operator==( + const OsiColCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) + return false; + if ( lbs() != rhs.lbs() ) + return false; + if ( ubs() != rhs.ubs() ) + return false; + return true; +} +// +bool +OsiColCut::operator!=( + const OsiColCut& rhs) const +{ + return !( (*this)==rhs ); +} + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiColCut::consistent() const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + // Test for consistent cut. + // Are packed vectors consistent? + lb.duplicateIndex("consistent", "OsiColCut"); + ub.duplicateIndex("consistent", "OsiColCut"); + if ( lb.getMinIndex() < 0 ) return false; + if ( ub.getMinIndex() < 0 ) return false; + return true; +} +// +bool OsiColCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + + // Test for consistent cut. + if ( lb.getMaxIndex() >= im.getNumCols() ) return false; + if ( ub.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} + +#if 0 +bool OsiColCut::feasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i<cutLbs.size(); i++ ) { + int colIndx = cutLbs.indices()[i]; + double newLb; + if ( cutLbs.elements()[i] > oldColLb[colIndx] ) + newLb = cutLbs.elements()[i]; + else + newLb = oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.indexExists(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return false; + } + + for ( i=0; i<cutUbs.size(); i++ ) { + int colIndx = cutUbs.indices()[i]; + double newUb = cutUbs.elements()[i] < oldColUb[colIndx] ? cutUbs.elements()[i] : oldColUb[colIndx]; + double newLb = oldColLb[colIndx]; + if ( cutLbs.indexExists(colIndx) ) + if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return false; + } + + return true; +} +#endif + + +bool OsiColCut::infeasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i<cutLbs.getNumElements(); i++ ) { + int colIndx = cutLbs.getIndices()[i]; + double newLb= cutLbs.getElements()[i] > oldColLb[colIndx] ? + cutLbs.getElements()[i] : oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.isExistingIndex(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return true; + } + + for ( i=0; i<cutUbs.getNumElements(); i++ ) { + int colIndx = cutUbs.getIndices()[i]; + double newUb = cutUbs.getElements()[i] < oldColUb[colIndx] ? + cutUbs.getElements()[i] : oldColUb[colIndx]; + double newLb = oldColLb[colIndx]; + if ( cutLbs.isExistingIndex(colIndx) ) + if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return true; + } + + return false; +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiCollections.hpp b/thirdparty/linux/include/coin/coin/OsiCollections.hpp new file mode 100644 index 0000000..d68df1a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiCollections.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCollections_H +#define OsiCollections_H + +#include <vector> + +//Forward declarations +class OsiColCut; +class OsiRowCut; +class OsiCut; + + + +/* Collection Classes */ + +/**@name Typedefs for Standard Template Library collections of Osi Objects. */ +//@{ +/// Vector of int +typedef std::vector<int> OsiVectorInt; +/// Vector of double +typedef std::vector<double> OsiVectorDouble; +/// Vector of OsiColCut pointers +typedef std::vector<OsiColCut *> OsiVectorColCutPtr; +/// Vector of OsiRowCut pointers +typedef std::vector<OsiRowCut *> OsiVectorRowCutPtr; +/// Vector of OsiCut pointers +typedef std::vector<OsiCut *> OsiVectorCutPtr; +//@} + + + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiConfig.h b/thirdparty/linux/include/coin/coin/OsiConfig.h new file mode 100644 index 0000000..ee9424f --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiConfig.h @@ -0,0 +1,19 @@ +/* src/Osi/config_osi.h. Generated by configure. */ +/* src/Osi/config_osi.h.in. */ + +#ifndef __CONFIG_OSI_H__ +#define __CONFIG_OSI_H__ + +/* Version number of project */ +#define OSI_VERSION "0.107.8" + +/* Major Version number of project */ +#define OSI_VERSION_MAJOR 0 + +/* Minor Version number of project */ +#define OSI_VERSION_MINOR 107 + +/* Release Version number of project */ +#define OSI_VERSION_RELEASE 8 + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiCut.hpp b/thirdparty/linux/include/coin/coin/OsiCut.hpp new file mode 100644 index 0000000..0b2cc5c --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiCut.hpp @@ -0,0 +1,245 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCut_H +#define OsiCut_H + +#include "OsiCollections.hpp" +#include "OsiSolverInterface.hpp" + +/** Base Class for cut. + +The Base cut class contains: + <ul> + <li>a measure of the cut's effectivness + </ul> +*/ + +/* + COIN_NOTEST_DUPLICATE is rooted in CoinUtils. Check there before you + meddle here. +*/ +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif + + +class OsiCut { + +public: + + //------------------------------------------------------------------- + /**@name Effectiveness */ + //@{ + /// Set effectiveness + inline void setEffectiveness( double e ); + /// Get effectiveness + inline double effectiveness() const; + //@} + + /**@name GloballyValid */ + //@{ + /// Set globallyValid (nonzero true) + inline void setGloballyValid( bool trueFalse ) + { globallyValid_=trueFalse ? 1 : 0;} + inline void setGloballyValid( ) + { globallyValid_=1;} + inline void setNotGloballyValid( ) + { globallyValid_=0;} + /// Get globallyValid + inline bool globallyValid() const + { return globallyValid_!=0;} + /// Set globallyValid as integer (nonzero true) + inline void setGloballyValidAsInteger( int trueFalse ) + { globallyValid_=trueFalse;} + /// Get globallyValid + inline int globallyValidAsInteger() const + { return globallyValid_;} + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const {} + //@} + +#if 0 + / **@name Times used */ + / /@{ + / // Set times used + inline void setTimesUsed( int t ); + / // Increment times used + inline void incrementTimesUsed(); + / // Get times used + inline int timesUsed() const; + / /@} + + / **@name Times tested */ + / /@{ + / // Set times tested + inline void setTimesTested( int t ); + / // Increment times tested + inline void incrementTimesTested(); + / // Get times tested + inline int timesTested() const; + / /@} +#endif + + //---------------------------------------------------------------- + + /**@name Comparison operators */ + //@{ + ///equal. 2 cuts are equal if there effectiveness are equal + inline virtual bool operator==(const OsiCut& rhs) const; + /// not equal + inline virtual bool operator!=(const OsiCut& rhs) const; + /// less than. True if this.effectiveness < rhs.effectiveness + inline virtual bool operator< (const OsiCut& rhs) const; + /// less than. True if this.effectiveness > rhs.effectiveness + inline virtual bool operator> (const OsiCut& rhs) const; + //@} + + //---------------------------------------------------------------- + // consistent() - returns true if the cut is consistent with repect to itself. + // This might include checks to ensure that a packed vector + // itself does not have a negative index. + // consistent(const OsiSolverInterface& si) - returns true if cut is consistent with + // respect to the solver interface's model. This might include a check to + // make sure a column index is not greater than the number + // of columns in the problem. + // infeasible(const OsiSolverInterface& si) - returns true if the cut is infeasible + // "with respect to itself". This might include a check to ensure + // the lower bound is greater than the upper bound, or if the + // cut simply replaces bounds that the new bounds are feasible with + // respect to the old bounds. + //----------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself, + without considering any + data in the model. For example, it might check to ensure + that a column index is not negative. + */ + inline virtual bool consistent() const=0; + + /** Returns true if cut is consistent when considering the solver + interface's model. For example, it might check to ensure + that a column index is not greater than the number of columns + in the model. Assumes consistent() is true. + */ + inline virtual bool consistent(const OsiSolverInterface& si) const=0; + + /** Returns true if the cut is infeasible "with respect to itself" and + cannot be satisfied. This method does NOT check whether adding the + cut to the solver interface's model will make the -model- infeasble. + A cut which returns !infeasible(si) may very well make the model + infeasible. (Of course, adding a cut with returns infeasible(si) + will make the model infeasible.) + + The "with respect to itself" is in quotes becaues + in the case where the cut + simply replaces existing bounds, it may make + sense to test infeasibility with respect to the current bounds + held in the solver interface's model. For example, if the cut + has a single variable in it, it might check that the maximum + of new and existing lower bounds is greater than the minium of + the new and existing upper bounds. + + Assumes that consistent(si) is true.<br> + Infeasible cuts can be a useful mechanism for a cut generator to + inform the solver interface that its detected infeasibility of the + problem. + */ + inline virtual bool infeasible(const OsiSolverInterface &si) const=0; + + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const=0; + //@} + +protected: + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiCut (); + + /// Copy constructor + OsiCut ( const OsiCut &); + + /// Assignment operator + OsiCut & operator=( const OsiCut& rhs); + + /// Destructor + virtual ~OsiCut (); + //@} + +private: + + /**@name Private member data */ + //@{ + /// Effectiveness + double effectiveness_; + /// If cut has global validity i.e. can be used anywhere in tree + int globallyValid_; +#if 0 + /// Times used + int timesUsed_; + /// Times tested + int timesTested_; +#endif + //@} +}; + + +//------------------------------------------------------------------- +// Set/Get member data +//------------------------------------------------------------------- +void OsiCut::setEffectiveness(double e) { effectiveness_=e; } +double OsiCut::effectiveness() const { return effectiveness_; } + +#if 0 +void OsiCut::setTimesUsed( int t ) { timesUsed_=t; } +void OsiCut::incrementTimesUsed() { timesUsed_++; } +int OsiCut::timesUsed() const { return timesUsed_; } + +void OsiCut::setTimesTested( int t ) { timesTested_=t; } +void OsiCut::incrementTimesTested() { timesTested_++; } +int OsiCut::timesTested() const{ return timesTested_; } +#endif + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiCut::operator==(const OsiCut& rhs) const +{ + return effectiveness()==rhs.effectiveness(); +} +bool +OsiCut::operator!=(const OsiCut& rhs) const +{ + return !( (*this)==rhs ); +} +bool +OsiCut::operator< (const OsiCut& rhs) const +{ + return effectiveness()<rhs.effectiveness(); +} +bool +OsiCut::operator> (const OsiCut& rhs) const +{ + return effectiveness()>rhs.effectiveness(); +} +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiCuts.hpp b/thirdparty/linux/include/coin/coin/OsiCuts.hpp new file mode 100644 index 0000000..5eea264 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiCuts.hpp @@ -0,0 +1,474 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCuts_H +#define OsiCuts_H + +#include "CoinPragma.hpp" + +#include <cmath> +#include <cfloat> +#include "OsiCollections.hpp" +#include "OsiRowCut.hpp" +#include "OsiColCut.hpp" +#include "CoinFloatEqual.hpp" + +/** Collections of row cuts and column cuts +*/ +class OsiCuts { + friend void OsiCutsUnitTest(); + +public: + /**@name Iterator classes + */ + //@{ + /** Iterator + + This is a class for iterating over the collection of cuts. + */ + class iterator { + friend class OsiCuts; + public: + iterator(OsiCuts& cuts); + iterator(const iterator & src); + iterator & operator=( const iterator& rhs); + ~iterator (); + OsiCut* operator*() const { return cutP_; } + iterator operator++(); + + iterator operator++(int) + { + iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const iterator& it) const { + return !((*this)==it); + } + + bool operator<(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + + private: + iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + iterator begin(); + iterator end(); + OsiCuts& cuts_; + int rowCutIndex_; + int colCutIndex_; + OsiCut * cutP_; + }; + + /** Const Iterator + + This is a class for iterating over the collection of cuts. + */ + class const_iterator { + friend class OsiCuts; + public: + typedef std::forward_iterator_tag iterator_category; + typedef OsiCut* value_type; + typedef size_t difference_type; + typedef OsiCut ** pointer; + typedef OsiCut *& reference; + + public: + const_iterator(const OsiCuts& cuts); + const_iterator(const const_iterator & src); + const_iterator & operator=( const const_iterator& rhs); + ~const_iterator (); + const OsiCut* operator*() const { return cutP_; } + + const_iterator operator++(); + + const_iterator operator++(int) + { + const_iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const const_iterator& it) const { + return !((*this)==it); + } + + bool operator<(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + private: + inline const_iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + const_iterator begin(); + const_iterator end(); + const OsiCuts * cutsPtr_; + int rowCutIndex_; + int colCutIndex_; + const OsiCut * cutP_; + }; + //@} + + //------------------------------------------------------------------- + // + // Cuts class definition begins here: + // + //------------------------------------------------------------------- + + /** \name Inserting a cut into collection */ + //@{ + /** \brief Insert a row cut */ + inline void insert( const OsiRowCut & rc ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinAbsFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinAbsFltEq treatAsSame=CoinAbsFltEq(1.0e-12) ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinRelFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinRelFltEq treatAsSame ); + /** \brief Insert a column cut */ + inline void insert( const OsiColCut & cc ); + + /** \brief Insert a row cut. + + The OsiCuts object takes control of the cut object. + On return, \c rcPtr is NULL. + */ + inline void insert( OsiRowCut * & rcPtr ); + /** \brief Insert a column cut. + + The OsiCuts object takes control of the cut object. + On return \c ccPtr is NULL. + */ + inline void insert( OsiColCut * & ccPtr ); +#if 0 + inline void insert( OsiCut * & cPtr ); +#endif + + /** \brief Insert a set of cuts */ + inline void insert(const OsiCuts & cs); + + //@} + + /**@name Number of cuts in collection */ + //@{ + /// Number of row cuts in collection + inline int sizeRowCuts() const; + /// Number of column cuts in collection + inline int sizeColCuts() const; + /// Number of cuts in collection + inline int sizeCuts() const; + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + inline void printCuts() const; + //@} + + /**@name Get a cut from collection */ + //@{ + /// Get pointer to i'th row cut + inline OsiRowCut * rowCutPtr(int i); + /// Get const pointer to i'th row cut + inline const OsiRowCut * rowCutPtr(int i) const; + /// Get pointer to i'th column cut + inline OsiColCut * colCutPtr(int i); + /// Get const pointer to i'th column cut + inline const OsiColCut * colCutPtr(int i) const; + + /// Get reference to i'th row cut + inline OsiRowCut & rowCut(int i); + /// Get const reference to i'th row cut + inline const OsiRowCut & rowCut(int i) const; + /// Get reference to i'th column cut + inline OsiColCut & colCut(int i); + /// Get const reference to i'th column cut + inline const OsiColCut & colCut(int i) const; + + /// Get const pointer to the most effective cut + inline const OsiCut * mostEffectiveCutPtr() const; + /// Get pointer to the most effective cut + inline OsiCut * mostEffectiveCutPtr(); + //@} + + /**@name Deleting cut from collection */ + //@{ + /// Remove i'th row cut from collection + inline void eraseRowCut(int i); + /// Remove i'th column cut from collection + inline void eraseColCut(int i); + /// Get pointer to i'th row cut and remove ptr from collection + inline OsiRowCut * rowCutPtrAndZap(int i); + /*! \brief Clear all row cuts without deleting them + + Handy in case one wants to use CGL without managing cuts in one of + the OSI containers. Client is ultimately responsible for deleting the + data structures holding the row cuts. + */ + inline void dumpCuts() ; + /*! \brief Selective delete and clear for row cuts. + + Deletes the cuts specified in \p to_erase then clears remaining cuts + without deleting them. A hybrid of eraseRowCut(int) and dumpCuts(). + Client is ultimately responsible for deleting the data structures + for row cuts not specified in \p to_erase. + */ + inline void eraseAndDumpCuts(const std::vector<int> to_erase) ; + //@} + + /**@name Sorting collection */ + //@{ + /// Cuts with greatest effectiveness are first. + inline void sort(); + //@} + + + /**@name Iterators + Example of using an iterator to sum effectiveness + of all cuts in the collection. + <pre> + double sumEff=0.0; + for ( OsiCuts::iterator it=cuts.begin(); it!=cuts.end(); ++it ) + sumEff+= (*it)->effectiveness(); + </pre> + */ + //@{ + /// Get iterator to beginning of collection + inline iterator begin() { iterator it(*this); it.begin(); return it; } + /// Get const iterator to beginning of collection + inline const_iterator begin() const { const_iterator it(*this); it.begin(); return it; } + /// Get iterator to end of collection + inline iterator end() { iterator it(*this); it.end(); return it; } + /// Get const iterator to end of collection + inline const_iterator end() const { const_iterator it(*this); it.end(); return it; } + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + OsiCuts (); + + /// Copy constructor + OsiCuts ( const OsiCuts &); + + /// Assignment operator + OsiCuts & operator=( const OsiCuts& rhs); + + /// Destructor + virtual ~OsiCuts (); + //@} + +private: + //*@name Function operator for sorting cuts by efectiveness */ + //@{ + class OsiCutCompare + { + public: + /// Function for sorting cuts by effectiveness + inline bool operator()(const OsiCut * c1P,const OsiCut * c2P) + { return c1P->effectiveness() > c2P->effectiveness(); } + }; + //@} + + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfCopy( const OsiCuts & source ); + /// Delete internal data + void gutsOfDestructor(); + //@} + + /**@name Private member data */ + //@{ + /// Vector of row cuts pointers + OsiVectorRowCutPtr rowCutPtrs_; + /// Vector of column cuts pointers + OsiVectorColCutPtr colCutPtrs_; + //@} + +}; + + +//------------------------------------------------------------------- +// insert cuts into collection +//------------------------------------------------------------------- +void OsiCuts::insert( const OsiRowCut & rc ) +{ + OsiRowCut * newCutPtr = rc.clone(); + //assert(dynamic_cast<OsiRowCut*>(newCutPtr) != NULL ); + rowCutPtrs_.push_back(static_cast<OsiRowCut*>(newCutPtr)); +} +void OsiCuts::insert( const OsiColCut & cc ) +{ + OsiColCut * newCutPtr = cc.clone(); + //assert(dynamic_cast<OsiColCut*>(newCutPtr) != NULL ); + colCutPtrs_.push_back(static_cast<OsiColCut*>(newCutPtr)); +} + +void OsiCuts::insert( OsiRowCut* & rcPtr ) +{ + rowCutPtrs_.push_back(rcPtr); + rcPtr = NULL; +} +void OsiCuts::insert( OsiColCut* &ccPtr ) +{ + colCutPtrs_.push_back(ccPtr); + ccPtr = NULL; +} +#if 0 +void OsiCuts::insert( OsiCut* & cPtr ) +{ + OsiRowCut * rcPtr = dynamic_cast<OsiRowCut*>(cPtr); + if ( rcPtr != NULL ) { + insert( rcPtr ); + cPtr = rcPtr; + } + else { + OsiColCut * ccPtr = dynamic_cast<OsiColCut*>(cPtr); + assert( ccPtr != NULL ); + insert( ccPtr ); + cPtr = ccPtr; + } +} +#endif + +// LANNEZ SEBASTIEN added Thu May 25 01:22:51 EDT 2006 +void OsiCuts::insert(const OsiCuts & cs) +{ + for (OsiCuts::const_iterator it = cs.begin (); it != cs.end (); it++) + { + const OsiRowCut * rCut = dynamic_cast <const OsiRowCut * >(*it); + const OsiColCut * cCut = dynamic_cast <const OsiColCut * >(*it); + assert (rCut || cCut); + if (rCut) + insert (*rCut); + else + insert (*cCut); + } +} + +//------------------------------------------------------------------- +// sort +//------------------------------------------------------------------- +void OsiCuts::sort() +{ + std::sort(colCutPtrs_.begin(),colCutPtrs_.end(),OsiCutCompare()); + std::sort(rowCutPtrs_.begin(),rowCutPtrs_.end(),OsiCutCompare()); +} + + +//------------------------------------------------------------------- +// Get number of in collections +//------------------------------------------------------------------- +int OsiCuts::sizeRowCuts() const { + return static_cast<int>(rowCutPtrs_.size()); } +int OsiCuts::sizeColCuts() const { + return static_cast<int>(colCutPtrs_.size()); } +int OsiCuts::sizeCuts() const { + return static_cast<int>(sizeRowCuts()+sizeColCuts()); } + +//---------------------------------------------------------------- +// Get i'th cut from the collection +//---------------------------------------------------------------- +const OsiRowCut * OsiCuts::rowCutPtr(int i) const { return rowCutPtrs_[i]; } +const OsiColCut * OsiCuts::colCutPtr(int i) const { return colCutPtrs_[i]; } +OsiRowCut * OsiCuts::rowCutPtr(int i) { return rowCutPtrs_[i]; } +OsiColCut * OsiCuts::colCutPtr(int i) { return colCutPtrs_[i]; } + +const OsiRowCut & OsiCuts::rowCut(int i) const { return *rowCutPtr(i); } +const OsiColCut & OsiCuts::colCut(int i) const { return *colCutPtr(i); } +OsiRowCut & OsiCuts::rowCut(int i) { return *rowCutPtr(i); } +OsiColCut & OsiCuts::colCut(int i) { return *colCutPtr(i); } + +//---------------------------------------------------------------- +// Get most effective cut from collection +//---------------------------------------------------------------- +const OsiCut * OsiCuts::mostEffectiveCutPtr() const +{ + const_iterator b=begin(); + const_iterator e=end(); + return *(std::min_element(b,e,OsiCutCompare())); +} +OsiCut * OsiCuts::mostEffectiveCutPtr() +{ + iterator b=begin(); + iterator e=end(); + //return *(std::min_element(b,e,OsiCutCompare())); + OsiCut * retVal = NULL; + double maxEff = COIN_DBL_MIN; + for ( OsiCuts::iterator it=b; it!=e; ++it ) { + if (maxEff < (*it)->effectiveness() ) { + maxEff = (*it)->effectiveness(); + retVal = *it; + } + } + return retVal; +} + +//---------------------------------------------------------------- +// Print all cuts +//---------------------------------------------------------------- +void +OsiCuts::printCuts() const +{ + // do all column cuts first + int i; + int numberColCuts=sizeColCuts(); + for (i=0;i<numberColCuts;i++) { + const OsiColCut * cut = colCutPtr(i); + cut->print(); + } + int numberRowCuts=sizeRowCuts(); + for (i=0;i<numberRowCuts;i++) { + const OsiRowCut * cut = rowCutPtr(i); + cut->print(); + } +} + +//---------------------------------------------------------------- +// Erase i'th cut from the collection +//---------------------------------------------------------------- +void OsiCuts::eraseRowCut(int i) +{ + delete rowCutPtrs_[i]; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); +} +void OsiCuts::eraseColCut(int i) +{ + delete colCutPtrs_[i]; + colCutPtrs_.erase( colCutPtrs_.begin()+i ); +} +/// Get pointer to i'th row cut and remove ptr from collection +OsiRowCut * +OsiCuts::rowCutPtrAndZap(int i) +{ + OsiRowCut * cut = rowCutPtrs_[i]; + rowCutPtrs_[i]=NULL; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); + return cut; +} +void OsiCuts::dumpCuts() +{ + rowCutPtrs_.clear() ; +} +void OsiCuts::eraseAndDumpCuts(const std::vector<int> to_erase) +{ + for (unsigned i=0; i<to_erase.size(); i++) { + delete rowCutPtrs_[to_erase[i]]; + } + rowCutPtrs_.clear(); +} + + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiPresolve.hpp b/thirdparty/linux/include/coin/coin/OsiPresolve.hpp new file mode 100644 index 0000000..9ec3d2a --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiPresolve.hpp @@ -0,0 +1,252 @@ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiPresolve_H +#define OsiPresolve_H +#include "OsiSolverInterface.hpp" + +class CoinPresolveAction; +#include "CoinPresolveMatrix.hpp" + + +/*! \class OsiPresolve + \brief OSI interface to COIN problem simplification capabilities + + COIN provides a number of classes which implement problem simplification + algorithms (CoinPresolveAction, CoinPrePostsolveMatrix, and derived + classes). The model of operation is as follows: + <ul> + <li> + Create a copy of the original problem. + </li> + <li> + Subject the copy to a series of transformations (the <i>presolve</i> + methods) to produce a presolved model. Each transformation is also + expected to provide a method to reverse the transformation (the + <i>postsolve</i> method). The postsolve methods are collected in a + linked list; the postsolve method for the final presolve transformation + is at the head of the list. + </li> + <li> + Hand the presolved problem to the solver for optimization. + </li> + <li> + Apply the collected postsolve methods to the presolved problem + and solution, restating the solution in terms of the original problem. + </li> + </ul> + + The COIN presolve algorithms are unaware of OSI. The OsiPresolve class takes + care of the interface. Given an OsiSolverInterface \c origModel, it will take + care of creating a clone properly loaded with the presolved problem and ready + for optimization. After optimization, it will apply postsolve + transformations and load the result back into \c origModel. + + Assuming a problem has been loaded into an + \c OsiSolverInterface \c origModel, a bare-bones application looks like this: + \code + OsiPresolve pinfo ; + OsiSolverInterface *presolvedModel ; + // Return an OsiSolverInterface loaded with the presolved problem. + presolvedModel = pinfo.presolvedModel(*origModel,1.0e-8,false,numberPasses) ; + presolvedModel->initialSolve() ; + // Restate the solution and load it back into origModel. + pinfo.postsolve(true) ; + delete presolvedModel ; + \endcode +*/ + + + +class OsiPresolve { +public: + /// Default constructor (empty object) + OsiPresolve(); + + /// Virtual destructor + virtual ~OsiPresolve(); + + /*! \brief Create a new OsiSolverInterface loaded with the presolved problem. + + This method implements the first two steps described in the class + documentation. It clones \c origModel and applies presolve + transformations, storing the resulting list of postsolve + transformations. It returns a pointer to a new OsiSolverInterface loaded + with the presolved problem, or NULL if the problem is infeasible or + unbounded. If \c keepIntegers is true then bounds may be tightened in + the original. Bounds will be moved by up to \c feasibilityTolerance to + try and stay feasible. When \c doStatus is true, the current solution will + be transformed to match the presolved model. + + This should be paired with postsolve(). It is up to the client to + destroy the returned OsiSolverInterface, <i>after</i> calling postsolve(). + + This method is virtual. Override this method if you need to customize + the steps of creating a model to apply presolve transformations. + + In some sense, a wrapper for presolve(CoinPresolveMatrix*). + */ + virtual OsiSolverInterface *presolvedModel(OsiSolverInterface & origModel, + double feasibilityTolerance=0.0, + bool keepIntegers=true, + int numberPasses=5, + const char * prohibited=NULL, + bool doStatus=true, + const char * rowProhibited=NULL); + + /*! \brief Restate the solution to the presolved problem in terms of the + original problem and load it into the original model. + + postsolve() restates the solution in terms of the original problem and + updates the original OsiSolverInterface supplied to presolvedModel(). If + the problem has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept of a basic + solution, then set updateStatus + + The advantage of going back to the original problem is that it + will be exactly as it was, <i>i.e.</i>, 0.0 will not become 1.0e-19. + + Note that if you modified the original problem after presolving, then you + must ``undo'' these modifications before calling postsolve(). + + In some sense, a wrapper for postsolve(CoinPostsolveMatrix&). + */ + virtual void postsolve(bool updateStatus=true); + + /*! \brief Return a pointer to the presolved model. */ + OsiSolverInterface * model() const; + + /// Return a pointer to the original model + OsiSolverInterface * originalModel() const; + + /// Set the pointer to the original model + void setOriginalModel(OsiSolverInterface *model); + + /// Return a pointer to the original columns + const int * originalColumns() const; + + /// Return a pointer to the original rows + const int * originalRows() const; + + /// Return number of rows in original model + inline int getNumRows() const + { return nrows_;} + + /// Return number of columns in original model + inline int getNumCols() const + { return ncols_;} + + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) + { nonLinearValue_ = value;} + inline double nonLinearValue() const + { return nonLinearValue_;} + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column processing on integer columns + and dual stuff on integers + - 0x02 switch off actions which can change +1 to something else + (doubleton, tripleton, implied free) + - 0x04 allow transfer of costs from singletons and between integer + variables (when advantageous) + - 0x08 do not allow x+y+z=1 transform + - 0x10 allow actions that don't easily unroll + - 0x20 allow dubious gub element reduction + + GUB element reduction is only partially implemented in CoinPresolve (see + gubrow_action) and willl cause an abort at postsolve. It's not clear + what's meant by `dual stuff on integers'. + -- lh, 110605 -- + */ + inline void setPresolveActions(int action) + { presolveActions_ = (presolveActions_&0xffff0000)|(action&0xffff);} + +private: + /*! Original model (solver interface loaded with the original problem). + + Must not be destroyed until after postsolve(). + */ + OsiSolverInterface * originalModel_; + + /*! Presolved model (solver interface loaded with the presolved problem) + + Must be destroyed by the client (using delete) after postsolve(). + */ + OsiSolverInterface * presolvedModel_; + + /*! "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + + /// Original column numbers + int * originalColumn_; + + /// Original row numbers + int * originalRow_; + + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /*! \brief Number of columns in original model. + + The problem will expand back to its former size as postsolve + transformations are applied. It is efficient to allocate data structures + for the final size of the problem rather than expand them as needed. + */ + int ncols_; + + /*! \brief Number of rows in original model. */ + int nrows_; + + /*! \brief Number of nonzero matrix coefficients in the original model. */ + CoinBigIndex nelems_; + + /** Whether we want to skip dual part of presolve etc. + 1 bit allows duplicate column processing on integer columns + and dual stuff on integers + 4 transfers costs to integer variables + */ + int presolveActions_; + /// Number of major passes + int numberPasses_; + +protected: + /*! \brief Apply presolve transformations to the problem. + + Handles the core activity of applying presolve transformations. + + If you want to apply the individual presolve routines differently, or + perhaps add your own to the mix, define a derived class and override + this method + */ + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /*! \brief Reverse presolve transformations to recover the solution + to the original problem. + + Handles the core activity of applying postsolve transformations. + + Postsolving is pretty generic; just apply the transformations in reverse + order. You will probably only be interested in overriding this method if + you want to add code to test for consistency while debugging new presolve + techniques. + */ + virtual void postsolve(CoinPostsolveMatrix &prob); + + /*! \brief Destroys queued postsolve actions. + + <i>E.g.</i>, when presolve() determines the problem is infeasible, so that + it will not be necessary to actually solve the presolved problem and + convert the result back to the original problem. + */ + void gutsOfDestroy(); +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiRowCut.hpp b/thirdparty/linux/include/coin/coin/OsiRowCut.hpp new file mode 100644 index 0000000..1332802 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiRowCut.hpp @@ -0,0 +1,331 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCut_H +#define OsiRowCut_H + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +//#define OSI_INLINE_ROWCUT_METHODS +#ifdef OSI_INLINE_ROWCUT_METHODS +#define OsiRowCut_inline inline +#else +#define OsiRowCut_inline +#endif + +/** Row Cut Class + +A row cut has: + <ul> + <li>a lower bound<br> + <li>an upper bound<br> + <li>a vector of row elements + </ul> +*/ +class OsiRowCut : public OsiCut { + friend void OsiRowCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + /**@name Row bounds */ + //@{ + /// Get lower bound + OsiRowCut_inline double lb() const; + /// Set lower bound + OsiRowCut_inline void setLb(double lb); + /// Get upper bound + OsiRowCut_inline double ub() const; + /// Set upper bound + OsiRowCut_inline void setUb(double ub); + //@} + + /**@name Row rhs, sense, range */ + //@{ + /// Get sense ('E', 'G', 'L', 'N', 'R') + char sense() const; + /// Get right-hand side + double rhs() const; + /// Get range (ub - lb for 'R' rows, 0 otherwise) + double range() const; + //@} + + //------------------------------------------------------------------- + /**@name Row elements */ + //@{ + /// Set row elements + OsiRowCut_inline void setRow( + int size, + const int * colIndices, + const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /// Set row elements from a packed vector + OsiRowCut_inline void setRow( const CoinPackedVector & v ); + /// Get row elements + OsiRowCut_inline const CoinPackedVector & row() const; + /// Get row elements for changing + OsiRowCut_inline CoinPackedVector & mutableRow() ; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bound, upper bound, row elements, + and OsiCut are equal. + */ + OsiRowCut_inline bool operator==(const OsiRowCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + OsiRowCut_inline bool operator!=(const OsiRowCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent. + This checks to ensure that: + <ul> + <li>The row element vector does not have duplicate indices + <li>The row element vector indices are >= 0 + </ul> + */ + OsiRowCut_inline bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. + This checks to ensure that + <ul> + <li>The row element vector indices are < the number of columns + in the model + </ul> + */ + OsiRowCut_inline bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the row cut itself is infeasible and cannot be satisfied. + This checks whether + <ul> + <li>the lower bound is strictly greater than the + upper bound. + </ul> + */ + OsiRowCut_inline bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + /**@name Arithmetic operators. Apply CoinPackedVector methods to the vector */ + //@{ + /// add <code>value</code> to every vector entry + void operator+=(double value) + { row_ += value; } + + /// subtract <code>value</code> from every vector entry + void operator-=(double value) + { row_ -= value; } + + /// multiply every vector entry by <code>value</code> + void operator*=(double value) + { row_ *= value; } + + /// divide every vector entry by <code>value</code> + void operator/=(double value) + { row_ /= value; } + //@} + + /// Allow access row sorting function + void sortIncrIndex() + {row_.sortIncrIndex();} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut & operator=( const OsiRowCut& rhs); + + /// Copy constructor + OsiRowCut ( const OsiRowCut &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut (); + + /** \brief Ownership Constructor + + This constructor assumes ownership of the vectors passed as parameters + for indices and elements. \p colIndices and \p elements will be NULL + on return. + */ + OsiRowCut(double cutlb, double cutub, + int capacity, int size, + int *&colIndices, double *&elements); + + /// Destructor + virtual ~OsiRowCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const ; + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Row elements + CoinPackedVector row_; + /// Row lower bound + double lb_; + /// Row upper bound + double ub_; + //@} +}; + +#ifdef OSI_INLINE_ROWCUT_METHODS + +//------------------------------------------------------------------- +// Set/Get lower & upper bounds +//------------------------------------------------------------------- +double OsiRowCut::lb() const { return lb_; } +void OsiRowCut::setLb(double lb) { lb_ = lb; } +double OsiRowCut::ub() const { return ub_; } +void OsiRowCut::setUb(double ub) { ub_ = ub; } + +//------------------------------------------------------------------- +// Set row elements +//------------------------------------------------------------------- +void OsiRowCut::setRow(int size, + const int * colIndices, const double * elements) +{ + row_.setVector(size,colIndices,elements); +} +void OsiRowCut::setRow( const CoinPackedVector & v ) +{ + row_ = v; +} + +//------------------------------------------------------------------- +// Get the row +//------------------------------------------------------------------- +const CoinPackedVector & OsiRowCut::row() const +{ + return row_; +} + +//------------------------------------------------------------------- +// Get the row so we can change +//------------------------------------------------------------------- +CoinPackedVector & OsiRowCut::mutableRow() +{ + return row_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiRowCut::operator==(const OsiRowCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) return false; + if ( row() != rhs.row() ) return false; + if ( lb() != rhs.lb() ) return false; + if ( ub() != rhs.ub() ) return false; + return true; +} +bool +OsiRowCut::operator!=(const OsiRowCut& rhs) const +{ + return !( (*this)==rhs ); +} + + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiRowCut::consistent() const +{ + const CoinPackedVector & r=row(); + r.duplicateIndex("consistent", "OsiRowCut"); + if ( r.getMinIndex() < 0 ) return false; + return true; +} +bool OsiRowCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & r=row(); + if ( r.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} +bool OsiRowCut::infeasible(const OsiSolverInterface &im) const +{ + if ( lb() > ub() ) return true; + + return false; +} + +#endif + +/** Row Cut Class which refers back to row which created it. + It may be useful to strengthen a row rather than add a cut. To do this + we need to know which row is strengthened. This trivial extension + to OsiRowCut does that. + +*/ +class OsiRowCut2 : public OsiRowCut { + +public: + + /**@name Which row */ + //@{ + /// Get row + inline int whichRow() const + { return whichRow_;} + /// Set row + inline void setWhichRow(int row) + { whichRow_=row;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut2 & operator=( const OsiRowCut2& rhs); + + /// Copy constructor + OsiRowCut2 ( const OsiRowCut2 &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut2 (int row=-1); + + /// Destructor + virtual ~OsiRowCut2 (); + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Which row + int whichRow_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiRowCutDebugger.hpp b/thirdparty/linux/include/coin/coin/OsiRowCutDebugger.hpp new file mode 100644 index 0000000..548e8e3 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiRowCutDebugger.hpp @@ -0,0 +1,187 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCutDebugger_H +#define OsiRowCutDebugger_H + +/*! \file OsiRowCutDebugger.hpp + + \brief Provides a facility to validate cut constraints to ensure that they + do not cut off a given solution. +*/ + +#include <string> + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" + +/*! \brief Validate cuts against a known solution + + OsiRowCutDebugger provides a facility for validating cuts against a known + solution for a problem. The debugger knows an optimal solution for many of + the miplib3 problems. Check the source for + #activate(const OsiSolverInterface&,const char*) + in OsiRowCutDebugger.cpp for the full set of known problems. + + A full solution vector can be supplied as a parameter with + (#activate(const OsiSolverInterface&,const double*,bool)). + Only the integer values need to be valid. + The default behaviour is to solve an lp relaxation with the integer + variables fixed to the specified values and use the optimal solution to fill + in the continuous variables in the solution. + The debugger can be instructed to preserve the continuous variables (useful + when debugging solvers where the linear relaxation doesn't capture all the + constraints). + + Note that the solution must match the problem held in the solver interface. + If you want to use the row cut debugger on a problem after applying presolve + transformations, your solution must match the presolved problem. (But see + #redoSolution().) +*/ +class OsiRowCutDebugger { + friend void OsiRowCutDebuggerUnitTest(const OsiSolverInterface * siP, + const std::string & mpsDir); + +public: + + /*! @name Validate Row Cuts + + Check that the specified cuts do not cut off the known solution. + */ + //@{ + /*! \brief Check that the set of cuts does not cut off the solution known + to the debugger. + + Check if any generated cuts cut off the solution known to the debugger! + If so then print offending cuts. Return the number of invalid cuts. + */ + virtual int validateCuts(const OsiCuts & cs, int first, int last) const; + + /*! \brief Check that the cut does not cut off the solution known to the + debugger. + + Return true if cut is invalid + */ + virtual bool invalidCut(const OsiRowCut & rowcut) const; + + /*! \brief Returns true if the solution held in the solver is compatible + with the known solution. + + More specifically, returns true if the known solution satisfies the column + bounds held in the solver. + */ + bool onOptimalPath(const OsiSolverInterface &si) const; + //@} + + /*! @name Activate the Debugger + + The debugger is considered to be active when it holds a known solution. + */ + //@{ + /*! \brief Activate a debugger using the name of a problem. + + The debugger knows an optimal solution for most of miplib3. Check the + source code for the full list. Returns true if the debugger is + successfully activated. + */ + bool activate(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Activate a debugger using a full solution array. + + The solution must have one entry for every variable, but only the entries + for integer values are used. By default the debugger will solve an lp + relaxation with the integer variables fixed and fill in values for the + continuous variables from this solution. If the debugger should preserve + the given values for the continuous variables, set \p keepContinuous to + \c true. + + Returns true if debugger activates successfully. + */ + bool activate(const OsiSolverInterface &si, const double* solution, + bool keepContinuous = false) ; + + /// Returns true if the debugger is active + bool active() const; + //@} + + /*! @name Query or Manipulate the Known Solution */ + //@{ + /// Return the known solution + inline const double * optimalSolution() const + { return knownSolution_;} + + /// Return the number of columns in the known solution + inline int numberColumns() const { return (numberColumns_) ; } + + /// Return the value of the objective for the known solution + inline double optimalValue() const { return knownValue_;} + + /*! \brief Edit the known solution to reflect column changes + + Given a translation array \p originalColumns[numberColumns] which can + translate current column indices to original column indices, this method + will edit the solution held in the debugger so that it matches the current + set of columns. + + Useful when the original problem is preprocessed prior to cut generation. + The debugger does keep a record of the changes. + */ + void redoSolution(int numberColumns, const int *originalColumns); + + /// Print optimal solution (returns -1 bad debug, 0 on optimal, 1 not) + int printOptimalSolution(const OsiSolverInterface & si) const; + //@} + + /**@name Constructors and Destructors */ + //@{ + /// Default constructor - no checking + OsiRowCutDebugger (); + + /*! \brief Constructor with name of model. + + See #activate(const OsiSolverInterface&,const char*). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Constructor with full solution. + + See #activate(const OsiSolverInterface&,const double*,bool). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const double *solution, + bool enforceOptimality = false) ; + + /// Copy constructor + OsiRowCutDebugger(const OsiRowCutDebugger &); + + /// Assignment operator + OsiRowCutDebugger& operator=(const OsiRowCutDebugger& rhs); + + /// Destructor + virtual ~OsiRowCutDebugger (); + //@} + +private: + + // Private member data + + /**@name Private member data */ + //@{ + /// Value of known solution + double knownValue_; + + /*! \brief Number of columns in known solution + + This must match the number of columns reported by the solver. + */ + int numberColumns_; + + /// array specifying integer variables + bool * integerVariable_; + + /// array specifying known solution + double * knownSolution_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiSolverBranch.hpp b/thirdparty/linux/include/coin/coin/OsiSolverBranch.hpp new file mode 100644 index 0000000..98c4343 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiSolverBranch.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverBranch_H +#define OsiSolverBranch_H + +class OsiSolverInterface; +#include "CoinWarmStartBasis.hpp" + +//############################################################################# + +/** Solver Branch Class + + This provides information on a branch as a set of tighter bounds on both ways +*/ + +class OsiSolverBranch { + +public: + ///@name Add and Get methods + //@{ + /// Add a simple branch (i.e. first sets ub of floor(value), second lb of ceil(value)) + void addBranch(int iColumn, double value); + + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberTighterLower, const int * whichLower, const double * newLower, + int numberTighterUpper, const int * whichUpper, const double * newUpper); + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberColumns,const double * oldLower, const double * newLower, + const double * oldUpper, const double * newUpper); + + /// Apply bounds + void applyBounds(OsiSolverInterface & solver,int way) const; + /// Returns true if current solution satsifies one side of branch + bool feasibleOneWay(const OsiSolverInterface & solver) const; + /// Starts + inline const int * starts() const + { return start_;} + /// Which variables + inline const int * which() const + { return indices_;} + /// Bounds + inline const double * bounds() const + { return bound_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverBranch(); + + /// Copy constructor + OsiSolverBranch(const OsiSolverBranch & rhs); + + /// Assignment operator + OsiSolverBranch & operator=(const OsiSolverBranch & rhs); + + /// Destructor + ~OsiSolverBranch (); + + //@} + +private: + ///@name Private member data + //@{ + /// Start of lower first, upper first, lower second, upper second + int start_[5]; + /// Column numbers (if >= numberColumns treat as rows) + int * indices_; + /// New bounds + double * bound_; + //@} +}; +//############################################################################# + +/** Solver Result Class + + This provides information on a result as a set of tighter bounds on both ways +*/ + +class OsiSolverResult { + +public: + ///@name Add and Get methods + //@{ + /// Create result + void createResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Restore result + void restoreResult(OsiSolverInterface & solver) const; + + /// Get basis + inline const CoinWarmStartBasis & basis() const + { return basis_;} + + /// Objective value (as minimization) + inline double objectiveValue() const + { return objectiveValue_;} + + /// Primal solution + inline const double * primalSolution() const + { return primalSolution_;} + + /// Dual solution + inline const double * dualSolution() const + { return dualSolution_;} + + /// Extra fixed + inline const OsiSolverBranch & fixed() const + { return fixed_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverResult(); + + /// Constructor from solver + OsiSolverResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Copy constructor + OsiSolverResult(const OsiSolverResult & rhs); + + /// Assignment operator + OsiSolverResult & operator=(const OsiSolverResult & rhs); + + /// Destructor + ~OsiSolverResult (); + + //@} + +private: + ///@name Private member data + //@{ + /// Value of objective (if >= OsiSolverInterface::getInfinity() then infeasible) + double objectiveValue_; + /// Warm start information + CoinWarmStartBasis basis_; + /// Primal solution (numberColumns) + double * primalSolution_; + /// Dual solution (numberRows) + double * dualSolution_; + /// Which extra variables have been fixed (only way==-1 counts) + OsiSolverBranch fixed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiSolverInterface.hpp b/thirdparty/linux/include/coin/coin/OsiSolverInterface.hpp new file mode 100644 index 0000000..a581961 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiSolverInterface.hpp @@ -0,0 +1,2143 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverInterface_H +#define OsiSolverInterface_H + +#include <cstdlib> +#include <string> +#include <vector> + +#include "CoinTypes.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinWarmStart.hpp" +#include "CoinFinite.hpp" +#include "CoinError.hpp" + +#include "OsiCollections.hpp" +#include "OsiSolverParameters.hpp" + +class CoinSnapshot; +class CoinLpIO; +class CoinMpsIO; + +class OsiCuts; +class OsiAuxInfo; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinSet; +class CoinBuild; +class CoinModel; +class OsiSolverBranch; +class OsiSolverResult; +class OsiObject; + + +//############################################################################# + +/*! \brief Abstract Base Class for describing an interface to a solver. + + Many OsiSolverInterface query methods return a const pointer to the + requested read-only data. If the model data is changed or the solver + is called, these pointers may no longer be valid and should be + refreshed by invoking the member function to obtain an updated copy + of the pointer. + For example: + \code + OsiSolverInterface solverInterfacePtr ; + const double * ruBnds = solverInterfacePtr->getRowUpper(); + solverInterfacePtr->applyCuts(someSetOfCuts); + // ruBnds is no longer a valid pointer and must be refreshed + ruBnds = solverInterfacePtr->getRowUpper(); + \endcode + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. +*/ + +class OsiSolverInterface { + friend void OsiSolverInterfaceCommonUnitTest( + const OsiSolverInterface* emptySi, + const std::string & mpsDir, + const std::string & netlibDir); + friend void OsiSolverInterfaceMpsUnitTest( + const std::vector<OsiSolverInterface*> & vecSiP, + const std::string & mpsDir); + +public: + + /// Internal class for obtaining status from the applyCuts method + class ApplyCutsReturnCode { + friend class OsiSolverInterface; + friend class OsiClpSolverInterface; + friend class OsiGrbSolverInterface; + + public: + ///@name Constructors and desctructors + //@{ + /// Default constructor + ApplyCutsReturnCode(): + intInconsistent_(0), + extInconsistent_(0), + infeasible_(0), + ineffective_(0), + applied_(0) {} + /// Copy constructor + ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs): + intInconsistent_(rhs.intInconsistent_), + extInconsistent_(rhs.extInconsistent_), + infeasible_(rhs.infeasible_), + ineffective_(rhs.ineffective_), + applied_(rhs.applied_) {} + /// Assignment operator + ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs) + { + if (this != &rhs) { + intInconsistent_ = rhs.intInconsistent_; + extInconsistent_ = rhs.extInconsistent_; + infeasible_ = rhs.infeasible_; + ineffective_ = rhs.ineffective_; + applied_ = rhs.applied_; + } + return *this; + } + /// Destructor + ~ApplyCutsReturnCode(){} + //@} + + /**@name Accessing return code attributes */ + //@{ + /// Number of logically inconsistent cuts + inline int getNumInconsistent() const + {return intInconsistent_;} + /// Number of cuts inconsistent with the current model + inline int getNumInconsistentWrtIntegerModel() const + {return extInconsistent_;} + /// Number of cuts that cause obvious infeasibility + inline int getNumInfeasible() const + {return infeasible_;} + /// Number of redundant or ineffective cuts + inline int getNumIneffective() const + {return ineffective_;} + /// Number of cuts applied + inline int getNumApplied() const + {return applied_;} + //@} + + private: + /**@name Private methods */ + //@{ + /// Increment logically inconsistent cut counter + inline void incrementInternallyInconsistent(){intInconsistent_++;} + /// Increment model-inconsistent counter + inline void incrementExternallyInconsistent(){extInconsistent_++;} + /// Increment infeasible cut counter + inline void incrementInfeasible(){infeasible_++;} + /// Increment ineffective cut counter + inline void incrementIneffective(){ineffective_++;} + /// Increment applied cut counter + inline void incrementApplied(){applied_++;} + //@} + + ///@name Private member data + //@{ + /// Counter for logically inconsistent cuts + int intInconsistent_; + /// Counter for model-inconsistent cuts + int extInconsistent_; + /// Counter for infeasible cuts + int infeasible_; + /// Counter for ineffective cuts + int ineffective_; + /// Counter for applied cuts + int applied_; + //@} + }; + + //--------------------------------------------------------------------------- + + ///@name Solve methods + //@{ + /// Solve initial LP relaxation + virtual void initialSolve() = 0; + + /*! \brief Resolve an LP relaxation after problem modification + + Note the `re-' in `resolve'. initialSolve() should be used to solve the + problem for the first time. + */ + virtual void resolve() = 0; + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound() = 0; + +#ifdef CBC_NEXT_VERSION + /* + Would it make sense to collect all of these routines in a `MIP Helper' + section? It'd make it easier for users and implementors to find them. + */ + /** + Solve 2**N (N==depth) problems and return solutions and bases. + There are N branches each of which changes bounds on both sides + as given by branch. The user should provide an array of (empty) + results which will be filled in. See OsiSolveResult for more details + (in OsiSolveBranch.?pp) but it will include a basis and primal solution. + + The order of results is left to right at feasible leaf nodes so first one + is down, down, ..... + + Returns number of feasible leaves. Also sets number of solves done and number + of iterations. + + This is provided so a solver can do faster. + + If forceBranch true then branch done even if satisfied + */ + virtual int solveBranches(int depth,const OsiSolverBranch * branch, + OsiSolverResult * result, + int & numberSolves, int & numberIterations, + bool forceBranch=false); +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. When a set method returns false, the original value (if + any) should be unchanged. There can be various reasons for failure: the + given parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet + implemented for the solver or simply the value of the parameter is out + of the range the solver accepts. If a parameter setting call returns + false check the details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + \note + There is a default implementation of the set/get + methods, namely to store/retrieve the given value using an array in the + base class. A specific solver implementation can use this feature, for + example, to store parameters that should be used later on. Implementors + of a solver interface should overload these functions to provide the + proper interface to and accurately reflect the capabilities of a + specific solver. + + The format for hints is slightly different in that a boolean specifies + the sense of the hint and an enum specifies the strength of the hint. + Hints should be initialised when a solver is instantiated. + (See OsiSolverParameters.hpp for defined hint parameters and strength.) + When specifying the sense of the hint, a value of true means to work with + the hint, false to work against it. For example, + <ul> + <li> \code setHintParam(OsiDoScale,true,OsiHintTry) \endcode + is a mild suggestion to the solver to scale the constraint + system. + <li> \code setHintParam(OsiDoScale,false,OsiForceDo) \endcode + tells the solver to disable scaling, or throw an exception if + it cannot comply. + </ul> + As another example, a solver interface could use the value and strength + of the \c OsiDoReducePrint hint to adjust the amount of information + printed by the interface and/or solver. The extent to which a solver + obeys hints is left to the solver. The value and strength returned by + \c getHintParam will match the most recent call to \c setHintParam, + and will not necessarily reflect the solver's ability to comply with the + hint. If the hint strength is \c OsiForceDo, the solver is required to + throw an exception if it cannot perform the specified action. + + \note + As with the other set/get methods, there is a default implementation + which maintains arrays in the base class for hint sense and strength. + The default implementation does not store the \c otherInformation + pointer, and always throws an exception for strength \c OsiForceDo. + Implementors of a solver interface should override these functions to + provide the proper interface to and accurately reflect the capabilities + of a specific solver. + */ + //@{ + //! Set an integer parameter + virtual bool setIntParam(OsiIntParam key, int value) { + if (key == OsiLastIntParam) return (false) ; + intParam_[key] = value; + return true; + } + //! Set a double parameter + virtual bool setDblParam(OsiDblParam key, double value) { + if (key == OsiLastDblParam) return (false) ; + dblParam_[key] = value; + return true; + } + //! Set a string parameter + virtual bool setStrParam(OsiStrParam key, const std::string & value) { + if (key == OsiLastStrParam) return (false) ; + strParam_[key] = value; + return true; + } + /*! \brief Set a hint parameter + + The \c otherInformation parameter can be used to pass in an arbitrary + block of information which is interpreted by the OSI and the underlying + solver. Users are cautioned that this hook is solver-specific. + + Implementors: + The default implementation completely ignores \c otherInformation and + always throws an exception for OsiForceDo. This is almost certainly not + the behaviour you want; you really should override this method. + */ + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * /*otherInformation*/ = NULL) { + if (key==OsiLastHintParam) + return false; + hintParam_[key] = yesNo; + hintStrength_[key] = strength; + if (strength == OsiForceDo) + throw CoinError("OsiForceDo illegal", + "setHintParam", "OsiSolverInterface"); + return true; + } + //! Get an integer parameter + virtual bool getIntParam(OsiIntParam key, int& value) const { + if (key == OsiLastIntParam) return (false) ; + value = intParam_[key]; + return true; + } + //! Get a double parameter + virtual bool getDblParam(OsiDblParam key, double& value) const { + if (key == OsiLastDblParam) return (false) ; + value = dblParam_[key]; + return true; + } + //! Get a string parameter + virtual bool getStrParam(OsiStrParam key, std::string& value) const { + if (key == OsiLastStrParam) return (false) ; + value = strParam_[key]; + return true; + } + /*! \brief Get a hint parameter (all information) + + Return all available information for the hint: sense, strength, + and any extra information associated with the hint. + + Implementors: The default implementation will always set + \c otherInformation to NULL. This is almost certainly not the + behaviour you want; you really should override this method. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength, + void *& otherInformation) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + otherInformation=NULL; + return true; + } + /*! \brief Get a hint parameter (sense and strength only) + + Return only the sense and strength of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + return true; + } + /*! \brief Get a hint parameter (sense only) + + Return only the sense (true/false) of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + return true; + } + /*! \brief Copy all parameters in this section from one solver to another + + Note that the current implementation also copies the appData block, + message handler, and rowCutDebugger. Arguably these should have + independent copy methods. + */ + void copyParameters(OsiSolverInterface & rhs); + + /** \brief Return the integrality tolerance of the underlying solver. + + We should be able to get an integrality tolerance, but + until that time just use the primal tolerance + + \todo + This method should be replaced; it's architecturally wrong. This + should be an honest dblParam with a keyword. Underlying solvers + that do not support integer variables should return false for set and + get on this parameter. Underlying solvers that support integrality + should add this to the parameters they support, using whatever + tolerance is appropriate. -lh, 091021- + */ + inline double getIntegerTolerance() const + { return dblParam_[OsiPrimalTolerance];} + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there numerical difficulties? + virtual bool isAbandoned() const = 0; + /// Is optimality proven? + virtual bool isProvenOptimal() const = 0; + /// Is primal infeasibility proven? + virtual bool isProvenPrimalInfeasible() const = 0; + /// Is dual infeasibility proven? + virtual bool isProvenDualInfeasible() const = 0; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const = 0; + //@} + + //--------------------------------------------------------------------------- + /** \name Warm start methods + + Note that the warm start methods return a generic CoinWarmStart object. + The precise characteristics of this object are solver-dependent. Clients + who wish to maintain a maximum degree of solver independence should take + care to avoid unnecessary assumptions about the properties of a warm start + object. + */ + //@{ + /*! \brief Get an empty warm start object + + This routine returns an empty warm start object. Its purpose is + to provide a way for a client to acquire a warm start object of the + appropriate type for the solver, which can then be resized and modified + as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const = 0 ; + + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. + */ + virtual CoinWarmStart* getWarmStart() const = 0; + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /** \brief Set warm start information. + + Return true or false depending on whether the warm start information was + accepted or not. + By definition, a call to setWarmStart with a null parameter should + cause the solver interface to refresh its warm start information + from the underlying solver. + */ + virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0; + //@} + + //--------------------------------------------------------------------------- + /**@name Hot start methods + + Primarily used in strong branching. The user can create a hot start + object --- a snapshot of the optimization process --- then reoptimize + over and over again, starting from the same point. + + \note + <ul> + <li> Between hot started optimizations only bound changes are allowed. + <li> The copy constructor and assignment operator should NOT copy any + hot start information. + <li> The default implementation simply extracts a warm start object in + \c markHotStart, resets to the warm start object in + \c solveFromHotStart, and deletes the warm start object in + \c unmarkHotStart. + <em>Actual solver implementations are encouraged to do better.</em> + </ul> + + */ + //@{ + /// Create a hot start snapshot of the optimization process. + virtual void markHotStart(); + /// Optimize starting from the hot start snapshot. + virtual void solveFromHotStart(); + /// Delete the hot start snapshot. + virtual void unmarkHotStart(); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from the + methods that return vectors. + + Const pointers returned from any data-query method are valid as long as + the data is unchanged and the solver is not called. + */ + //@{ + /// Get the number of columns + virtual int getNumCols() const = 0; + + /// Get the number of rows + virtual int getNumRows() const = 0; + + /// Get the number of nonzero elements + virtual int getNumElements() const = 0; + + /// Get the number of integer variables + virtual int getNumIntegers() const ; + + /// Get a pointer to an array[getNumCols()] of column lower bounds + virtual const double * getColLower() const = 0; + + /// Get a pointer to an array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row constraint senses. + + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row right-hand sides + + <ul> + <li> if getRowSense()[i] == 'L' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'G' then + getRightHandSide()[i] == getRowLower()[i] + <li> if getRowSense()[i] == 'R' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'N' then + getRightHandSide()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row ranges. + + <ul> + <li> if getRowSense()[i] == 'R' then + getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] + <li> if getRowSense()[i] != 'R' then + getRowRange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const = 0; + + /// Get a pointer to an array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const = 0; + + /// Get a pointer to an array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumCols()] of objective + function coefficients. + */ + virtual const double * getObjCoefficients() const = 0; + + /*! \brief Get the objective function sense + + - 1 for minimisation (default) + - -1 for maximisation + */ + virtual double getObjSense() const = 0; + + /// Return true if the variable is continuous + virtual bool isContinuous(int colIndex) const = 0; + + /// Return true if the variable is binary + virtual bool isBinary(int colIndex) const; + + /*! \brief Return true if the variable is integer. + + This method returns true if the variable is binary or general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if the variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if the variable is binary and not fixed + virtual bool isFreeBinary(int colIndex) const; + + /*! \brief Return an array[getNumCols()] of column types + + \deprecated See #getColType + */ + inline const char *columnType(bool refresh=false) const + { return getColType(refresh); } + + /*! \brief Return an array[getNumCols()] of column types + + - 0 - continuous + - 1 - binary + - 2 - general integer + + If \p refresh is true, the classification of integer variables as + binary or general integer will be reevaluated. If the current bounds + are [0,1], or if the variable is fixed at 0 or 1, it will be classified + as binary, otherwise it will be classified as general integer. + */ + virtual const char * getColType(bool refresh=false) const; + + /// Get a pointer to a row-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByRow() const = 0; + + /// Get a pointer to a column-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByCol() const = 0; + + /*! \brief Get a pointer to a mutable row-wise copy of the matrix. + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByRow() const {return NULL;} + + /*! \brief Get a pointer to a mutable column-wise copy of the matrix + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByCol() const {return NULL;} + + /// Get the solver's value for infinity + virtual double getInfinity() const = 0; + //@} + + /**@name Solution query methods */ + //@{ + /// Get a pointer to an array[getNumCols()] of primal variable values + virtual const double * getColSolution() const = 0; + + /** Get a pointer to an array[getNumCols()] of primal variable values + guaranteed to be between the column lower and upper bounds. + */ + virtual const double * getStrictColSolution(); + + /// Get pointer to array[getNumRows()] of dual variable values + virtual const double * getRowPrice() const = 0; + + /// Get a pointer to an array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const = 0; + + /** Get a pointer to array[getNumRows()] of row activity levels. + + The row activity for a row is the left-hand side evaluated at the + current solution. + */ + virtual const double * getRowActivity() const = 0; + + /// Get the objective function value. + virtual double getObjValue() const = 0; + + /** Get the number of iterations it took to solve the problem (whatever + `iteration' means to the solver). + */ + virtual int getIterationCount() const = 0; + + /** Get as many dual rays as the solver can provide. In case of proven + primal infeasibility there should (with high probability) be at least + one. + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumRows() (fullRay = + false) or (getNumRows()+getNumCols()) (fullRay = true) and they should + be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const = 0; + + /** Get as many primal rays as the solver can provide. In case of proven + dual infeasibility there should (with high probability) be at least + one. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumCols() and they + should be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0; + + /** Get vector of indices of primal variables which are integer variables + but have fractional values in the current solution. */ + virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05) + const; + //@} + + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + + For functions which take a set of indices as parameters + (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), + \c setRowSetTypes()), the parameters follow the C++ STL iterator + convention: \c indexFirst points to the first index in the + set, and \c indexLast points to a position one past the last index + in the set. + + */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ) = 0; + + /** Set a set of objective function coefficients */ + virtual void setObjCoeffSet(const int* indexFirst, + const int* indexLast, + const double* coeffList); + + /** Set the objective coefficients for all columns. + + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the objective function sense. + + Use 1 for minimisation (default), -1 for maximisation. + + \note + Implementors note that objective function sense is a parameter of + the OSI, not a property of the problem. Objective sense can be + set prior to problem load and should not be affected by loading a + new problem. + */ + virtual void setObjSense(double s) = 0; + + + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ) = 0; + + /** Set the lower bounds for all columns. + + array [getNumCols()] is an array of values for the lower bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ) = 0; + + /** Set the upper bounds for all columns. + + array [getNumCols()] is an array of values for the upper bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + + + /** Set a single column lower and upper bound. + The default implementation just invokes setColLower() and + setColUpper() */ + virtual void setColBounds( int elementIndex, + double lower, double upper ) { + setColLower(elementIndex, lower); + setColUpper(elementIndex, upper); + } + + /** Set the upper and lower bounds of a set of columns. + + The default implementation just invokes setColBounds() over and over + again. For each column, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ) = 0; + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) = 0; + + /** Set a single row lower and upper bound. + The default implementation just invokes setRowLower() and + setRowUpper() */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) { + setRowLower(elementIndex, lower); + setRowUpper(elementIndex, upper); + } + + /** Set the bounds on a set of rows. + + The default implementation just invokes setRowBounds() over and over + again. For each row, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range) = 0; + + /** Set the type of a set of rows. + The default implementation just invokes setRowType() + over and over again. + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + + /** Set the primal solution variable values + + colsol[getNumCols()] is an array of values for the primal variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getColSolution() until changed by another call to setColSolution() or + by a call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setColSolution(const double *colsol) = 0; + + /** Set dual solution variable values + + rowprice[getNumRows()] is an array of values for the dual variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getRowPrice() until changed by another call to setRowPrice() or by a + call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setRowPrice(const double * rowprice) = 0; + + /** Fix variables at bound based on reduced cost + + For variables currently at bound, fix the variable at bound if the + reduced cost exceeds the gap. Return the number of variables fixed. + + If justInteger is set to false, the routine will also fix continuous + variables, but the test still assumes a delta of 1.0. + */ + virtual int reducedCostFix(double gap, bool justInteger=true); + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index) = 0; + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index) = 0; + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + + /*! \brief Data type for name vectors. */ + typedef std::vector<std::string> OsiNameVec ; + + /*! \name Methods for row and column names + + Osi defines three name management disciplines: `auto names' (0), `lazy + names' (1), and `full names' (2). See the description of + #OsiNameDiscipline for details. Changing the name discipline (via + setIntParam()) will not automatically add or remove name information, + but setting the discipline to auto will make existing information + inaccessible until the discipline is reset to lazy or full. + + By definition, a row index of getNumRows() (<i>i.e.</i>, one larger than + the largest valid row index) refers to the objective function. + + OSI users and implementors: While the OSI base class can define an + interface and provide rudimentary support, use of names really depends + on support by the OsiXXX class to ensure that names are managed + correctly. If an OsiXXX class does not support names, it should return + false for calls to getIntParam() or setIntParam() that reference + OsiNameDiscipline. + */ + //@{ + + /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn + + Set \p rc to 'r' for a row name, 'c' for a column name. + The `nnnnnnn' part is generated from ndx and will contain 7 digits + by default, padded with zeros if necessary. As a special case, + ndx = getNumRows() is interpreted as a request for the name of the + objective function. OBJECTIVE is returned, truncated to digits+1 + characters to match the row and column names. + */ + virtual std::string dfltRowColName(char rc, + int ndx, unsigned digits = 7) const ; + + /*! \brief Return the name of the objective function */ + + virtual std::string getObjName (unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Set the name of the objective function */ + + virtual inline void setObjName (std::string name) + { objName_ = name ; } + + /*! \brief Return the name of the row. + + The routine will <i>always</i> return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of row names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. In particular, the objective name is <i>not</i> + included in the vector for lazy names. If the name discipline is + full, the vector will have getNumRows() names, either supplied or + generated, plus one additional entry for the objective name. + */ + virtual const OsiNameVec &getRowNames() ; + + /*! \brief Set a row name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the row index is invalid. + */ + virtual void setRowName(int ndx, std::string name) ; + + /*! \brief Set multiple row names + + The run of len entries starting at srcNames[srcStart] are installed as + row names starting at row index tgtStart. The base class implementation + makes repeated calls to setRowName. + */ + virtual void setRowNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len row names starting at index tgtStart + + The specified row names are removed and the remaining row names are + copied down to close the gap. + */ + virtual void deleteRowNames(int tgtStart, int len) ; + + /*! \brief Return the name of the column + + The routine will <i>always</i> return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of column names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. If the name discipline is full, the vector will have + getNumCols() names, either supplied or generated. + */ + virtual const OsiNameVec &getColNames() ; + + /*! \brief Set a column name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the column index is invalid. + */ + virtual void setColName(int ndx, std::string name) ; + + /*! \brief Set multiple column names + + The run of len entries starting at srcNames[srcStart] are installed as + column names starting at column index tgtStart. The base class + implementation makes repeated calls to setColName. + */ + virtual void setColNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len column names starting at index tgtStart + + The specified column names are removed and the remaining column names + are copied down to close the gap. + */ + virtual void deleteColNames(int tgtStart, int len) ; + + + /*! \brief Set row and column names from a CoinMpsIO object. + + Also sets the name of the objective function. If the name discipline + is auto, you get what you asked for. This routine does not use + setRowName or setColName. + */ + void setRowColNames(const CoinMpsIO &mps) ; + + /*! \brief Set row and column names from a CoinModel object. + + If the name discipline is auto, you get what you asked for. + This routine does not use setRowName or setColName. + */ + void setRowColNames(CoinModel &mod) ; + + /*! \brief Set row and column names from a CoinLpIO object. + + Also sets the name of the objective function. If the name discipline is + auto, you get what you asked for. This routine does not use setRowName + or setColName. + */ + void setRowColNames(CoinLpIO &mod) ; + + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + /**@name Methods to modify the constraint system. + + Note that new columns are added as continuous variables. + */ + //@{ + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj) = 0; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj) ; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, const int* columnStarts, + const int* rows, const double* elements, + const double* collb, const double* colub, + const double* obj); + + /// Add columns using a CoinBuild object + void addCols(const CoinBuild & buildObject); + + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + */ + int addCols(CoinModel & modelObject); + +#if 0 + /** */ + virtual void addCols(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj); +#endif + + /** \brief Remove a set of columns (primal variables) from the + problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted variables are nonbasic. + */ + virtual void deleteCols(const int num, const int * colIndices) = 0; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + + /*! Add a row (constraint) to the problem. + + Converts to addRow(CoinPackedVectorBase&,const double,const double). + */ + virtual void addRow(int numberElements, + const int *columns, const double *element, + const double rowlb, const double rowub) ; + + /*! Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, const int *rowStarts, + const int *columns, const double *element, + const double *rowlb, const double *rowub); + + /// Add rows using a CoinBuild object + void addRows(const CoinBuild &buildObject); + + /*! Add rows from a CoinModel object. + + Returns -1 if the object is in the wrong state (<i>i.e.</i>, has + column-major information), otherwise the number of errors. + + The modelObject is not const as it can be regularized as part of + the build. + */ + int addRows(CoinModel &modelObject); + +#if 0 + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const char* rowsen, const double* rowrhs, + const double* rowrng); +#endif + + /** \brief Delete a set of rows (constraints) from the problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted rows are loose. + */ + virtual void deleteRows(const int num, const int * rowIndices) = 0; + + /** \brief Replace the constraint matrix + + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would + not matter, e.g. strengthening a matrix for MIP. + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & ) {} + + /** \brief Replace the constraint matrix + + And if it does matter (not used at present) + */ + virtual void replaceMatrix(const CoinPackedMatrix & ) {abort();} + + /** \brief Save a copy of the base model + + If solver wants it can save a copy of "base" (continuous) model here. + */ + virtual void saveBaseModel() {} + + /** \brief Reduce the constraint system to the specified number of + constraints. + + If solver wants it can restore a copy of "base" (continuous) model + here. + + \note + The name is somewhat misleading. Implementors should consider + the opportunity to optimise behaviour in the common case where + \p numberRows is exactly the number of original constraints. Do not, + however, neglect the possibility that \p numberRows does not equal + the number of original constraints. + */ + virtual void restoreBaseModel(int numberRows); + //----------------------------------------------------------------------- + /** Apply a collection of cuts. + + Only cuts which have an <code>effectiveness >= effectivenessLb</code> + are applied. + <ul> + <li> ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + <code>effectiveness < effectivenessLb</code> + <li> ReturnCode.getNuminconsistent() -- number of invalid cuts + <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model + <li> ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible + <li> ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model + <li> cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() + </ul> + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + Would be even more efficient to pass an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + + /** Apply a collection of row cuts which are all effective. + This is passed in as an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + + /// Deletes branching information before columns deleted + void deleteBranchingInfo(int numberDeleted, const int * which); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods for problem input and output */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by lower and upper bounds. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ <code>delete</code> and <code>delete[]</code> functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ <code>delete</code> and <code>delete[]</code> functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadProblem method using rowlb and rowub for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadProblem method using sense/rhs/range for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load a model from a CoinModel object. Return the number of + errors encountered. + + The modelObject parameter cannot be const as it may be changed as part + of process. If keepSolution is true will try and keep warmStart. + */ + virtual int loadFromCoinModel (CoinModel & modelObject, + bool keepSolution=false); + + /*! \brief Read a problem in MPS format from the given filename. + + The default implementation uses CoinMpsIO::readMps() to read + the MPS file and returns the number of errors encountered. + */ + virtual int readMps (const char *filename, + const char *extension = "mps") ; + + /*! \brief Read a problem in MPS format from the given full filename. + + This uses CoinMpsIO::readMps() to read the MPS file and returns the + number of errors encountered. It also may return an array of set + information + */ + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /*! \brief Read a problem in GMPL format from the given filenames. + + The default implementation uses CoinMpsIO::readGMPL(). This capability + is available only if the third-party package Glpk is installed. + */ + virtual int readGMPL (const char *filename, const char *dataname=NULL); + + /*! \brief Write the problem in MPS format to the specified file. + + If objSense is non-zero, a value of -1.0 causes the problem to be + written with a maximization objective; +1.0 forces a minimization + objective. If objSense is zero, the choice is left to the implementation. + */ + virtual void writeMps (const char *filename, + const char *extension = "mps", + double objSense=0.0) const = 0; + + /*! \brief Write the problem in MPS format to the specified file with + more control over the output. + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex + </ul> + + Returns non-zero on I/O error + */ + int writeMpsNative (const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0, int numberSOS=0, + const CoinSet * setInfo=NULL) const ; + +/***********************************************************************/ +// Lp files + + /** Write the problem into an Lp file of the given filename with the + specified extension. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + + The written problem is always a minimization problem. + If the current problem is a maximization problem, the + intended objective function for the written problem is the current + objective function multiplied by -1. If the current problem is a + minimization problem, the intended objective function for the + written problem is the current objective function. + If objSense < 0, the intended objective function is multiplied by -1 + before writing the problem. It is left unchanged otherwise. + + Write objective function name and constraint names if useRowNames is + true. This version calls writeLpNative(). + */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into an Lp file. Parameters are similar to + those of writeLp(), but in addition row names and column names + may be given. + + Parameter rowNames may be NULL, in which case default row names + are used. If rowNames is not NULL, it must have exactly one entry + per row in the problem and one additional + entry (rowNames[getNumRows()] with the objective function name. + These getNumRows()+1 entries must be distinct. If this is not the + case, default row names + are used. In addition, format restrictions are imposed on names + (see CoinLpIO::is_invalid_name() for details). + + Similar remarks can be made for the parameter columnNames which + must either be NULL or have exactly getNumCols() distinct entries. + + Write objective function name and constraint names if + useRowNames is true. */ + int writeLpNative(const char *filename, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLpNative() with first parameter filename. + */ + int writeLpNative(FILE *fp, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + virtual int readLp(const char *filename, const double epsilon = 1e-5); + + /// Read file in LP format from the file pointed to by fp. + /// See class CoinLpIO for description of this format. + int readLp(FILE *fp, const double epsilon = 1e-5); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Miscellaneous */ + //@{ + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + (Note initial version does not check names) + May modify both models by cleaning up + */ + int differentModel(OsiSolverInterface & other, + bool ignoreNames=true); +#ifdef COIN_SNAPSHOT + /// Return a CoinSnapshot + virtual CoinSnapshot * snapshot(bool createArrays=true) const; +#endif +#ifdef COIN_FACTORIZATION_INFO + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + /** Create a clone of an Auxiliary Information object. + The base class just stores an application data pointer + but can be more general. Application data pointer is + designed for one user while this can be extended to cope + with more general extensions. + */ + void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo); + + /// Get application data + void * getApplicationData() const; + /// Get pointer to auxiliary info object + OsiAuxInfo * getAuxiliaryInfo() const; + //@} + //--------------------------------------------------------------------------- + + /**@name Message handling + + See the COIN library documentation for additional information about + COIN message facilities. + + */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Return a pointer to the current message handler + inline CoinMessageHandler * messageHandler() const + {return handler_;} + /// Return the current set of messages + inline CoinMessages messages() + {return messages_;} + /// Return a pointer to the current set of messages + inline CoinMessages * messagesPointer() + {return &messages_;} + /// Return true if default handler + inline bool defaultHandler() const + { return defaultHandler_;} + //@} + //--------------------------------------------------------------------------- + /**@name Methods for dealing with discontinuities other than integers. + + Osi should be able to know about SOS and other types. This is an optional + section where such information can be stored. + + */ + //@{ + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If justCount then no objects created and we just store numberIntegers_ + */ + + void findIntegers(bool justCount); + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + /// Get the number of objects + inline int numberObjects() const { return numberObjects_;} + /// Set the number of objects + inline void setNumberObjects(int number) + { numberObjects_=number;} + + /// Get the array of objects + inline OsiObject ** objects() const { return object_;} + + /// Get the specified object + const inline OsiObject * object(int which) const { return object_[which];} + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { return object_[which];} + + /// Delete all object information + void deleteObjects(); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + /** Use current solution to set bounds so current integer feasible solution will stay feasible. + Only feasible bounds will be used, even if current solution outside bounds. The amount of + such violation will be returned (and if small can be ignored) + */ + double forceFeasible(); + //@} + //--------------------------------------------------------------------------- + + /*! @name Methods related to testing generated cuts + + See the documentation for OsiRowCutDebugger for additional details. + */ + //@{ + /*! \brief Activate the row cut debugger. + + If \p modelName is in the set of known models then all cuts are + checked to see that they do NOT cut off the optimal solution known + to the debugger. + */ + virtual void activateRowCutDebugger (const char *modelName); + + /*! \brief Activate the row cut debugger using a full solution array. + + + Activate the debugger for a model not included in the debugger's + internal database. Cuts will be checked to see that they do NOT + cut off the given solution. + + \p solution must be a full solution vector, but only the integer + variables need to be correct. The debugger will fill in the continuous + variables by solving an lp relaxation with the integer variables + fixed as specified. If the given values for the continuous variables + should be preserved, set \p keepContinuous to true. + */ + virtual void activateRowCutDebugger(const double *solution, + bool enforceOptimality = true); + + /*! \brief Get the row cut debugger provided the solution known to the + debugger is within the feasible region held in the solver. + + If there is a row cut debugger object associated with model AND if + the solution known to the debugger is within the solver's current + feasible region (i.e., the column bounds held in the solver are + compatible with the known solution) then a pointer to the debugger + is returned which may be used to test validity of cuts. + + Otherwise NULL is returned + */ + const OsiRowCutDebugger *getRowCutDebugger() const; + + /*! \brief Get the row cut debugger object + + Return the row cut debugger object if it exists. One common usage of + this method is to obtain a debugger object in order to execute + OsiRowCutDebugger::redoSolution (so that the stored solution is again + compatible with the problem held in the solver). + */ + OsiRowCutDebugger * getRowCutDebuggerAlways() const; + //@} + + /*! \name OsiSimplexInterface + \brief Simplex Interface + + Methods for an advanced interface to a simplex solver. The interface + comprises two groups of methods. Group 1 contains methods for tableau + access. Group 2 contains methods for dictating individual simplex pivots. + */ + //@{ + + /*! \brief Return the simplex implementation level. + + The return codes are: + - 0: the simplex interface is not implemented. + - 1: the Group 1 (tableau access) methods are implemented. + - 2: the Group 2 (pivoting) methods are implemented + + The codes are cumulative - a solver which implements Group 2 also + implements Group 1. + */ + virtual int canDoSimplexInterface() const ; + //@} + + /*! \name OsiSimplex Group 1 + \brief Tableau access methods. + + This group of methods provides access to rows and columns of the basis + inverse and to rows and columns of the tableau. + */ + //@{ + + /*! \brief Prepare the solver for the use of tableau access methods. + + Prepares the solver for the use of the tableau access methods, if + any such preparation is required. + + The \c const attribute is required due to the places this method + may be called (e.g., within CglCutGenerator::generateCuts()). + */ + virtual void enableFactorization() const ; + + /*! \brief Undo the effects of #enableFactorization. */ + virtual void disableFactorization() const ; + + /*! \brief Check if an optimal basis is available. + + Returns true if the problem has been solved to optimality and a + basis is available. This should be used to see if the tableau access + operations are possible and meaningful. + + \note + Implementors please note that this method may be called + before #enableFactorization. + */ + virtual bool basisIsAvailable() const ; + + /// Synonym for #basisIsAvailable + inline bool optimalBasisIsAvailable() const { return basisIsAvailable() ; } + + /*! \brief Retrieve status information for column and row variables. + + This method returns status as integer codes: + <ul> + <li> 0: free + <li> 1: basic + <li> 2: nonbasic at upper bound + <li> 3: nonbasic at lower bound + </ul> + + The #getWarmStart method provides essentially the same functionality + for a simplex-oriented solver, but the implementation details are very + different. + + \note + Logical variables associated with rows are all assumed to have +1 + coefficients, so for a <= constraint the logical will be at lower + bound if the constraint is tight. + + \note + Implementors may choose to implement this method as a wrapper which + converts a CoinWarmStartBasis to the requested representation. + */ + virtual void getBasisStatus(int* cstat, int* rstat) const ; + + /*! \brief Set the status of column and row variables and update + the basis factorization and solution. + + Status information should be coded as documented for #getBasisStatus. + Returns 0 if all goes well, 1 if something goes wrong. + + This method differs from #setWarmStart in the format of the input + and in its immediate effect. Think of it as #setWarmStart immediately + followed by #resolve, but no pivots are allowed. + + \note + Implementors may choose to implement this method as a wrapper that calls + #setWarmStart and #resolve if the no pivot requirement can be satisfied. + */ + virtual int setBasisStatus(const int* cstat, const int* rstat) ; + + /*! \brief Calculate duals and reduced costs for the given objective + coefficients. + + The solver's objective coefficient vector is not changed. + */ + virtual void getReducedGradient(double* columnReducedCosts, + double* duals, const double* c) const ; + + /*! \brief Get a row of the tableau + + If \p slack is not null, it will be loaded with the coefficients for + the artificial (logical) variables (i.e., the row of the basis inverse). + */ + virtual void getBInvARow(int row, double* z, double* slack = NULL) const ; + + /*! \brief Get a row of the basis inverse */ + virtual void getBInvRow(int row, double* z) const ; + + /*! \brief Get a column of the tableau */ + virtual void getBInvACol(int col, double* vec) const ; + + /*! \brief Get a column of the basis inverse */ + virtual void getBInvCol(int col, double* vec) const ; + + /*! \brief Get indices of basic variables + + If the logical (artificial) for row i is basic, the index should be coded + as (#getNumCols + i). + The order of indices must match the order of elements in the vectors + returned by #getBInvACol and #getBInvCol. + */ + virtual void getBasics(int* index) const ; + + //@} + + /*! \name OsiSimplex Group 2 + \brief Pivoting methods + + This group of methods provides for control of individual pivots by a + simplex solver. + */ + //@{ + + /**Enables normal operation of subsequent functions. + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. says whether will be + doing primal or dual + */ + virtual void enableSimplexInterface(bool doingPrimal) ; + + ///Undo whatever setting changes the above method had to make + virtual void disableSimplexInterface() ; + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in outStatus. Where + 1 is to upper bound, -1 to lower bound + Return code was undefined - now for OsiClp is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus) ; + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx) ; + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverInterface(); + + /** Clone + + The result of calling clone(false) is defined to be equivalent to + calling the default constructor OsiSolverInterface(). + */ + virtual OsiSolverInterface * clone(bool copyData = true) const = 0; + + /// Copy constructor + OsiSolverInterface(const OsiSolverInterface &); + + /// Assignment operator + OsiSolverInterface & operator=(const OsiSolverInterface& rhs); + + /// Destructor + virtual ~OsiSolverInterface (); + + /** Reset the solver interface. + + A call to reset() returns the solver interface to the same state as + it would have if it had just been constructed by calling the default + constructor OsiSolverInterface(). + */ + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to the constraint matrix). */ + virtual void applyRowCut( const OsiRowCut & rc ) = 0; + + /** Apply a column cut (adjust the bounds of one or more variables). */ + virtual void applyColCut( const OsiColCut & cc ) = 0; + + /** A quick inlined function to convert from the lb/ub style of + constraint definition to the sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from the sense/rhs/range style + of constraint definition to the lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + /** A quick inlined function to force a value to be between a minimum and + a maximum value */ + template <class T> inline T + forceIntoRange(const T value, const T lower, const T upper) const { + return value < lower ? lower : (value > upper ? upper : value); + } + /** Set OsiSolverInterface object state for default constructor + + This routine establishes the initial values of data fields in the + OsiSolverInterface object when the object is created using the + default constructor. + */ + void setInitialData(); + //@} + + ///@name Protected member data + //@{ + /*! \brief Pointer to row cut debugger object + + Mutable so that we can update the solution held in the debugger while + maintaining const'ness for the Osi object. + */ + mutable OsiRowCutDebugger * rowCutDebugger_; + // Why not just make useful stuff protected? + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the currrent handler is the default handler. + Indicates if the solver interface object is responsible + for destruction of the handler (true) or if the client is + responsible (false). + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Number of integers + int numberIntegers_; + /// Total number of objects + int numberObjects_; + + /// Integer and ... information (integer info normally at beginning) + OsiObject ** object_; + /** Column type + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + mutable char * columnType_; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + /// Pointer to user-defined data structure - and more if user wants + OsiAuxInfo * appDataEtc_; + /// Array of integer parameters + int intParam_[OsiLastIntParam]; + /// Array of double parameters + double dblParam_[OsiLastDblParam]; + /// Array of string parameters + std::string strParam_[OsiLastStrParam]; + /// Array of hint parameters + bool hintParam_[OsiLastHintParam]; + /// Array of hint strengths + OsiHintStrength hintStrength_[OsiLastHintParam]; + /** Warm start information used for hot starts when the default + hot start implementation is used. */ + CoinWarmStart* ws_; + /// Column solution satisfying lower and upper column bounds + std::vector<double> strictColSolution_; + + /// Row names + OsiNameVec rowNames_ ; + /// Column names + OsiNameVec colNames_ ; + /// Objective name + std::string objName_ ; + + //@} +}; + +//############################################################################# +/** A quick inlined function to convert from the lb/ub style of constraint + definition to the sense/rhs/range style */ +inline void +OsiSolverInterface::convertBoundToSense(const double lower, const double upper, + char& sense, double& right, + double& range) const +{ + double inf = getInfinity(); + range = 0.0; + if (lower > -inf) { + if (upper < inf) { + right = upper; + if (upper==lower) { + sense = 'E'; + } else { + sense = 'R'; + range = upper - lower; + } + } else { + sense = 'G'; + right = lower; + } + } else { + if (upper < inf) { + sense = 'L'; + right = upper; + } else { + sense = 'N'; + right = 0.0; + } + } +} + +//----------------------------------------------------------------------------- +/** A quick inlined function to convert from the sense/rhs/range style of + constraint definition to the lb/ub style */ +inline void +OsiSolverInterface::convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const +{ + double inf=getInfinity(); + switch (sense) { + case 'E': + lower = upper = right; + break; + case 'L': + lower = -inf; + upper = right; + break; + case 'G': + lower = right; + upper = inf; + break; + case 'R': + lower = right - range; + upper = right; + break; + case 'N': + lower = -inf; + upper = inf; + break; + } +} + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiSolverParameters.hpp b/thirdparty/linux/include/coin/coin/OsiSolverParameters.hpp new file mode 100644 index 0000000..5f607f5 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiSolverParameters.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverParameters_H +#define OsiSolverParameters_H + +enum OsiIntParam { + /*! \brief Iteration limit for initial solve and resolve. + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the OsiSolverinterface::initialSolve() + and OsiSolverinterface::resolve() methods before terminating. + */ + OsiMaxNumIteration = 0, + /*! \brief Iteration limit for hot start + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the + OsiSolverinterface::solveFromHotStart() method before terminating. + */ + OsiMaxNumIterationHotStart, + /*! \brief Handling of row and column names. + + The name discipline specifies how the solver will handle row and column + names: + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + OsiNameDiscipline, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + integer parameters. + */ + OsiLastIntParam +} ; + +enum OsiDblParam { + /*! \brief Dual objective limit. + + This is to be used as a termination criteria in algorithms where the dual + objective changes monotonically (e.g., dual simplex, volume algorithm). + */ + OsiDualObjectiveLimit = 0, + /*! \brief Primal objective limit. + + This is to be used as a termination criteria in algorithms where the + primal objective changes monotonically (e.g., primal simplex) + */ + OsiPrimalObjectiveLimit, + /*! \brief Dual feasibility tolerance. + + The maximum amount a dual constraint can be violated and still be + considered feasible. + */ + OsiDualTolerance, + /*! \brief Primal feasibility tolerance. + + The maximum amount a primal constraint can be violated and still be + considered feasible. + */ + OsiPrimalTolerance, + /** The value of any constant term in the objective function. */ + OsiObjOffset, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + double parameters. + */ + OsiLastDblParam +}; + + +enum OsiStrParam { + /*! \brief The name of the loaded problem. + + This is the string specified on the Name card of an mps file. + */ + OsiProbName = 0, + /*! \brief The name of the solver. + + This parameter is read-only. + */ + OsiSolverName, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + string parameters. + */ + OsiLastStrParam +}; + +enum OsiHintParam { + /** Whether to do a presolve in initialSolve */ + OsiDoPresolveInInitial = 0, + /** Whether to use a dual algorithm in initialSolve. + The reverse is to use a primal algorithm */ + OsiDoDualInInitial, + /** Whether to do a presolve in resolve */ + OsiDoPresolveInResolve, + /** Whether to use a dual algorithm in resolve. + The reverse is to use a primal algorithm */ + OsiDoDualInResolve, + /** Whether to scale problem */ + OsiDoScale, + /** Whether to create a non-slack basis (only in initialSolve) */ + OsiDoCrash, + /** Whether to reduce amount of printout, e.g., for branch and cut */ + OsiDoReducePrint, + /** Whether we are in branch and cut - so can modify behavior */ + OsiDoInBranchAndCut, + /** Just a marker, so that OsiSolverInterface can allocate a static sized + array to store parameters. */ + OsiLastHintParam +}; + +enum OsiHintStrength { + /** Ignore hint (default) */ + OsiHintIgnore = 0, + /** This means it is only a hint */ + OsiHintTry, + /** This means do hint if at all possible */ + OsiHintDo, + /** And this means throw an exception if not possible */ + OsiForceDo +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiSymSolverInterface.hpp b/thirdparty/linux/include/coin/coin/OsiSymSolverInterface.hpp new file mode 100644 index 0000000..46f6514 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiSymSolverInterface.hpp @@ -0,0 +1,806 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef OsiSymSolverInterface_hpp +#define OsiSymSolverInterface_hpp + +#include "OsiSolverInterface.hpp" +#include "OsiSymSolverParameters.hpp" +#include "SymWarmStart.hpp" + +#include <string> + +typedef struct SYM_ENVIRONMENT sym_environment; + +//############################################################################# + +/** OSI Solver Interface for SYMPHONY + + Many OsiSolverInterface query methods return a const pointer to the + requested read-only data. If the model data is changed or the solver + is called, these pointers may no longer be valid and should be + refreshed by invoking the member function to obtain an updated copy + of the pointer. + For example: + \code + OsiSolverInterface solverInterfacePtr ; + const double * ruBnds = solverInterfacePtr->getRowUpper(); + solverInterfacePtr->applyCuts(someSetOfCuts); + // ruBnds is no longer a valid pointer and must be refreshed + ruBnds = solverInterfacePtr->getRowUpper(); + \endcode + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. +*/ + +class OsiSymSolverInterface : virtual public OsiSolverInterface { + friend void OsiSymSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + ///@name Solve methods + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an IP problem modification + virtual void resolve(); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + + /// Invoke solver's multi-criteria enumeration algorithm + virtual void multiCriteriaBranchAndBound(); + + /// Get a lower bound for the new rhs problem using the warm start tree. + virtual double getLbForNewRhs(int cnt, int *index, + double * value); + /// Get an upper bound for the new rhs problem using the warm start tree. + virtual double getUbForNewRhs(int cnt, int *index, + double * value); +#if 0 + /// Get a lower bound for the new obj problem using the warm start tree. + virtual double getLbForNewObj(int cnt, int *index, + double * value); + /// Get an upper bound for the new obj problem using the warm start tree. +#endif + virtual double getUbForNewObj(int cnt, int *index, + double * value); + + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + */ + //@{ + // Set an integer parameter + virtual bool setIntParam(OsiIntParam key, int value); + + // Set SYMPHONY int parameter + virtual bool setSymParam(OsiSymIntParam key, int value); + + // Set SYMPHONY int parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, int value); + + + // Set an double parameter + virtual bool setDblParam(OsiDblParam key, double value); + + // Set SYMPHONY double parameter + virtual bool setSymParam(OsiSymDblParam key, double value); + + // Set SYMPHONY double parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, double value); + + + + // Set a string parameter + virtual bool setStrParam(OsiStrParam key, const std::string & value); + + // Set SYMPHONY string parameter + virtual bool setSymParam(OsiSymStrParam key, const std::string & value); + + // Set SYMPHONY string parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, const std::string value); + + + + // Get an integer parameter + virtual bool getIntParam(OsiIntParam key, int& value) const; + + // Get SYMPHONY int parameter + virtual bool getSymParam(OsiSymIntParam key, int& value) const; + + // Get SYMPHONY int parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, int& value) const; + + + // Get an double parameter + virtual bool getDblParam(OsiDblParam key, double& value) const; + + // Get SYMPHONY double parameter + virtual bool getSymParam(OsiSymDblParam key, double& value) const; + + // Get SYMPHONY double parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, double& value) const; + + + + // Get a string parameter + virtual bool getStrParam(OsiStrParam key, std::string& value) const; + + // Get SYMPHONY string parameter + virtual bool getSymParam(OsiSymStrParam key, std::string& value) const; + + // Get SYMPHONY string parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, std::string& value) const; + + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there numerical difficulties? + virtual bool isAbandoned() const; + + /// Is optimality proven? + virtual bool isProvenOptimal() const; + + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const { + throw CoinError("Error: Function not implemented", + "isProvenDualInfeasible", "OsiSymSolverInterface"); + } + /// Is the given primal objective limit reached? + //virtual bool isPrimalObjectiveLimitReached() const; + + /// Is the given dual objective limit reached? + //virtual bool isDualObjectiveLimitReached() const{ + // throw CoinError("Error: Function not implemented", + // "isDualObjectiveLimitReached", "OsiSymSolverInterface"); + //} + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + + /// Time limit reached? + virtual bool isTimeLimitReached() const; + + /// Target gap achieved? + virtual bool isTargetGapReached() const; + + //@} + + //--------------------------------------------------------------------------- + /**@name Warm start methods */ + //@{ + /*! \brief Get an empty warm start object + + This routine returns an empty warm start object. Its purpose is + to provide a way to give a client a warm start object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const{ + throw CoinError("Error: Function not implemented", + "getEmptyWarmStart", "OsiSymSolverInterface"); + } + + /** Get warm start information. + + If there is no valid solution, an empty warm start object (0 rows, 0 + columns) wil be returned. + */ + + /* + virtual CoinWarmStart* getWarmStart(bool keepTreeInSymEnv = false) const; + */ + + virtual CoinWarmStart* getWarmStart() const; + + /** Set warm start information. + + Return true/false depending on whether the warm start information was + accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Get pointer to SYMPHONY environment (eventually we won't need this) + sym_environment *getSymphonyEnvironment() const {return env_;} + + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + /// Get number of nonzero elements + virtual int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of row right-hand sides + <ul> + <li> if getRowSense()[i] == 'L' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'G' then + getRightHandSide()[i] == getRowLower()[i] + <li> if getRowSense()[i] == 'R' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'N' then + getRightHandSide()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if getRowSense()[i] == 'R' then + getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] + <li> if getRowSense()[i] != 'R' then + getRowRange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const; + + /** Get pointer to array[getNumCols()] of second + objective function coefficients if loaded before. + */ + virtual const double * getObj2Coefficients() const; + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const; + + /// Return true if variable is continuous + virtual bool isContinuous(int colIndex) const; + + /// Return true if variable is binary + virtual bool isBinary(int colIndex) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if variable is binary and not fixed at either bound + virtual bool isFreeBinary(int colIndex) const; + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + + //@} + + /**@name Solution query methods */ + //@{ + /// Get pointer to array[getNumCols()] of primal variable values + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual variable values + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector). */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /// Get the current upper/lower bound + virtual double getPrimalBound() const; + + /** Get the number of iterations it took to solve the problem (whatever + ``iteration'' means to the solver). */ + virtual int getIterationCount() const; + + /** Get as many dual rays as the solver can provide. In case of proven + primal infeasibility there should be at least one. + + \note + Implementors of solver interfaces note that + the double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. + + \note + Clients of solver interfaces note that + it is the client's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const{ + throw CoinError("Error: Function not implemented", + "getDualRays", "OsiSymSolverInterface"); + } + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const{ + throw CoinError("Error: Function not implemented", + "getPrimalRays", "OsiSymSolverInterface"); + } + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + + For functions which take a set of indices as parameters + (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), + \c setRowSetTypes()), the parameters follow the C++ STL iterator + convention: \c indexFirst points to the first index in the + set, and \c indexLast points to a position one past the last index + in the set. + + */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + /** Set an objective function coefficient for the second objective */ + virtual void setObj2Coeff( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColLower ; + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColUpper ; + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ); + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /// Set the objective function sense. + /// (1 for min (default), -1 for max) + virtual void setObjSense(double s); + + /** Set the primal solution variable values + + colsol[getNumCols()] is an array of values for the primal variables. + These values are copied to memory owned by the solver interface object + or the solver. They will be returned as the result of getColSolution() + until changed by another call to setColSolution() or by a call to any + solver routine. Whether the solver makes use of the solution in any + way is solver-dependent. + */ + virtual void setColSolution(const double *colsol); + + /** Set the a priori upper/lower bound */ + + virtual void setPrimalBound(const double bound); + + /** Set dual solution variable values + + rowprice[getNumRows()] is an array of values for the dual + variables. These values are copied to memory owned by the solver + interface object or the solver. They will be returned as the result of + getRowPrice() until changed by another call to setRowPrice() or by a + call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + + virtual void setRowPrice(const double * rowprice); + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + + using OsiSolverInterface::setContinuous ; + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + + using OsiSolverInterface::setInteger ; + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + + + using OsiSolverInterface::setColName ; + virtual void setColName(char **colname); + + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem. + + Note that new columns are added as continuous variables. + + */ + //@{ + + using OsiSolverInterface::addCol ; + /** Add a column (primal variable) to the problem. */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + + /** Remove a set of columns (primal variables) from the problem. */ + virtual void deleteCols(const int num, const int * colIndices); + + using OsiSolverInterface::addRow ; + /** Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + + /** Delete a set of rows (constraints) from the problem. */ + virtual void deleteRows(const int num, const int * rowIndices); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods to input a problem */ + //@{ + + virtual void loadProblem(); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). + For default values see the previous method. + + \warning + The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. + + \warning + The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Write the problem in MPS format to the specified file. + + If objSense is non-zero, a value of -1.0 causes the problem to be + written with a maximization objective; +1.0 forces a minimization + objective. If objSense is zero, the choice is left to implementation. + */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + + void parseCommandLine(int argc, char **argv); + + using OsiSolverInterface::readMps ; + virtual int readMps(const char * infile, const char *extension = "mps"); + + virtual int readGMPL(const char * modelFile, const char * dataFile=NULL); + + void findInitialBounds(); + + int createPermanentCutPools(); + + //@} + + //--------------------------------------------------------------------------- + + enum keepCachedFlag { + /// discard all cached data (default) + KEEPCACHED_NONE = 0, + /// column information: objective values, lower and upper bounds, variable types + KEEPCACHED_COLUMN = 1, + /// row information: right hand sides, ranges and senses, lower and upper bounds for row + KEEPCACHED_ROW = 2, + /// problem matrix: matrix ordered by column and by row + KEEPCACHED_MATRIX = 4, + /// LP solution: primal and dual solution, reduced costs, row activities + KEEPCACHED_RESULTS = 8, + /// only discard cached LP solution + KEEPCACHED_PROBLEM = KEEPCACHED_COLUMN | KEEPCACHED_ROW | KEEPCACHED_MATRIX, + /// keep all cached data (similar to getMutableLpPtr()) + KEEPCACHED_ALL = KEEPCACHED_PROBLEM | KEEPCACHED_RESULTS, + /// free only cached column and LP solution information + FREECACHED_COLUMN = KEEPCACHED_PROBLEM & ~KEEPCACHED_COLUMN, + /// free only cached row and LP solution information + FREECACHED_ROW = KEEPCACHED_PROBLEM & ~KEEPCACHED_ROW, + /// free only cached matrix and LP solution information + FREECACHED_MATRIX = KEEPCACHED_PROBLEM & ~KEEPCACHED_MATRIX, + /// free only cached LP solution information + FREECACHED_RESULTS = KEEPCACHED_ALL & ~KEEPCACHED_RESULTS + }; + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSymSolverInterface(); + + /** Clone + + The result of calling clone(false) is defined to be equivalent to + calling the default constructor OsiSolverInterface(). + */ + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSymSolverInterface(const OsiSymSolverInterface &); + + /// Assignment operator + OsiSymSolverInterface & operator=(const OsiSymSolverInterface& rhs); + + /// Destructor + virtual ~OsiSymSolverInterface (); + + /** Reset the solver interface. + + A call to reset() returns the solver interface to the same state as + it would have if it had just been constructed by calling the default + constructor OsiSolverInterface(). + */ + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to the constraint matrix). */ + virtual void applyRowCut( const OsiRowCut & rc ); + + /** Apply a column cut (adjust the bounds of one or more variables). */ + virtual void applyColCut( const OsiColCut & cc ); + + /** Set OsiSolverInterface object state for default constructor + + This routine establishes the initial values of data fields in the + OsiSolverInterface object when the object is created using the + default constructor. + */ + + void setInitialData(); + //@} + +private: + + /// The real work of the constructor + void gutsOfConstructor(); + + /// The real work of the destructor + void gutsOfDestructor(); + + /// free cached column rim vectors + void freeCachedColRim(); + + /// free cached row rim vectors + void freeCachedRowRim(); + + /// free cached result vectors + void freeCachedResults(); + + /// free cached matrices + void freeCachedMatrix(); + + /// free all cached data (except specified entries, see getLpPtr()) + void freeCachedData( int keepCached = KEEPCACHED_NONE ); + + /// free all allocated memory + void freeAllMemory(); + + /**@name Private member data */ + //@{ + /// The pointer to the SYMPHONY problem environment + sym_environment *env_; + //@} + + /// Pointer to objective vector + mutable double *obj_; + + /// Pointer to second objective vector to be used in bicriteria solver + mutable double *obj2_; + + /// Pointer to dense vector of variable lower bounds + mutable double *collower_; + + /// Pointer to dense vector of variable lower bounds + mutable double *colupper_; + + /// Pointer to dense vector of variable lower bounds + mutable double *colredcost_; + + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack upper bounds for range constraints + (undefined for non-range rows) + */ + mutable double *rowrange_; + + /// Pointer to dense vector of row lower bounds + mutable double *rowlower_; + + /// Pointer to dense vector of row upper bounds + mutable double *rowupper_; + + /// Pointer to dense vector of row prices + mutable double *rowprice_; + + /// Pointer to primal solution vector + mutable double *colsol_; + + /// Pointer to row activity (slack) vector + mutable double *rowact_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByCol_; + +}; + +//############################################################################# +/** A function that tests the methods in the OsiSymSolverInterface class. */ +void OsiSymSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiSymSolverParameters.hpp b/thirdparty/linux/include/coin/coin/OsiSymSolverParameters.hpp new file mode 100644 index 0000000..041acce --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiSymSolverParameters.hpp @@ -0,0 +1,64 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef OsiSymSolverParameters_hpp +#define OsiSymSolverParameters_hpp + +enum OsiSymIntParam { + /** This controls the level of output */ + OsiSymMaxActiveNodes, + OsiSymVerbosity, + OsiSymNodeLimit, + OsiSymFindFirstFeasible, + OsiSymSearchStrategy, + OsiSymUsePermanentCutPools, + OsiSymKeepWarmStart, + OsiSymDoReducedCostFixing, + OsiSymMCFindSupportedSolutions, + OsiSymSensitivityAnalysis, + OsiSymRandomSeed, + OsiSymDivingStrategy, + OsiSymDivingK, + OsiSymDivingThreshold, + OsiSymTrimWarmTree, + OsiSymGenerateCglGomoryCuts, + OsiSymGenerateCglKnapsackCuts, + OsiSymGenerateCglOddHoleCuts, + OsiSymGenerateCglProbingCuts, + OsiSymGenerateCglFlowAndCoverCuts, + OsiSymGenerateCglRoundingCuts, + OsiSymGenerateCglLiftAndProjectCuts, + OsiSymGenerateCglCliqueCuts +}; + +enum OsiSymDblParam { + /** The granularity is the actual minimum difference in objective function + value for two solutions that actually have do different objective + function values. For integer programs with integral objective function + coefficients, this would be 1, for instance. */ + OsiSymGranularity, + OsiSymTimeLimit, + OsiSymGapLimit, + OsiSymUpperBound, + OsiSymLowerBound +}; + +enum OsiSymStrParam { +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/OsiUnitTests.hpp b/thirdparty/linux/include/coin/coin/OsiUnitTests.hpp new file mode 100644 index 0000000..fbb4fc1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/OsiUnitTests.hpp @@ -0,0 +1,374 @@ +// Copyright (C) 2010 +// All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/*! \file OsiUnitTests.hpp + + Utility methods for OSI unit tests. +*/ + +#ifndef OSISOLVERINTERFACETEST_HPP_ +#define OSISOLVERINTERFACETEST_HPP_ + +#include <cstdio> +#include <cstdlib> +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <list> +#include <map> + +class OsiSolverInterface; +class CoinPackedVectorBase; + +/** A function that tests that a lot of problems given in MPS files (mostly the NETLIB problems) solve properly with all the specified solvers. + * + * The routine creates a vector of NetLib problems (problem name, objective, + * various other characteristics), and a vector of solvers to be tested. + * + * Each solver is run on each problem. The run is deemed successful if the + * solver reports the correct problem size after loading and returns the + * correct objective value after optimization. + + * If multiple solvers are available, the results are compared pairwise against + * the results reported by adjacent solvers in the solver vector. Due to + * limitations of the volume solver, it must be the last solver in vecEmptySiP. + */ +void OsiSolverInterfaceMpsUnitTest + (const std::vector<OsiSolverInterface*> & vecEmptySiP, + const std::string& mpsDir); + +/** A function that tests the methods in the OsiSolverInterface class. + * Some time ago, if this method is compiled with optimization, + * the compilation took 10-15 minutes and the machine pages (has 256M core memory!)... + */ +void OsiSolverInterfaceCommonUnitTest + (const OsiSolverInterface* emptySi, + const std::string& mpsDir, + const std::string& netlibDir); + +/** A function that tests the methods in the OsiColCut class. */ +void OsiColCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCut class. */ +void OsiRowCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCutDebugger class. */ +void OsiRowCutDebuggerUnitTest + (const OsiSolverInterface * siP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiCuts class. */ +void OsiCutsUnitTest(); + +/// A namespace so we can define a few `global' variables to use during tests. +namespace OsiUnitTest { + +class TestOutcomes; + +/*! \brief Verbosity level of unit tests + + 0 (default) for minimal output; larger numbers produce more output +*/ +extern unsigned int verbosity; + +/*! \brief Behaviour on failing a test + + - 0 (= default) continue + - 1 press any key to continue + - 2 stop with abort() +*/ +extern unsigned int haltonerror; + +/*! \brief Test outcomes + + A global TestOutcomes object to store test outcomes during the run of the unit test + for an OSI. + */ +extern TestOutcomes outcomes; + +/*! \brief Print an error message + + Formatted as "XxxSolverInterface testing issue: message" where Xxx is the string + provided as \p solverName. + + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &message) ; +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &message) ; + +/*! \brief Print an error message, specifying the test name and condition + + Formatted as "XxxSolverInterface testing issue: testname failed: testcond" where + Xxx is the OsiStrParam::OsiSolverName parameter of the \p si. + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &testname, const std::string &testcond) ; + +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &testname, const std::string &testcond) ; + +/*! \brief Print a message. + + Prints the message as given. Flushes std::cout before printing to std::cerr. +*/ +void testingMessage(const char *const msg) ; + +/*! \brief Utility method to check equality + + Tests for equality using CoinRelFltEq with tolerance \p tol. Understands the + notion of solver infinity and obtains the value for infinity from the solver + interfaces supplied as parameters. +*/ +bool equivalentVectors(const OsiSolverInterface * si1, + const OsiSolverInterface * si2, + double tol, const double * v1, const double * v2, int size) ; + +/*! \brief Compare two problems for equality + + Compares the problems held in the two solvers: constraint matrix, row and column + bounds, column type, and objective. Rows are checked using upper and lower bounds + and using sense, bound, and range. +*/ +bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ; + +/*! \brief Compare a packed vector with an expanded vector + + Checks that all values present in the packed vector are present in the full vector + and checks that there are no extra entries in the full vector. Uses CoinRelFltEq + with the default tolerance. +*/ +bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ; + +/*! \brief Process command line parameters. + + An unrecognised keyword which is not in the \p ignorekeywords map will trigger the + help message and a return value of false. For each keyword in \p ignorekeywords, you + can specify the number of following parameters that should be ignored. + + This should be replaced with the one of the standard CoinUtils parameter mechanisms. + */ +bool processParameters (int argc, const char **argv, + std::map<std::string,std::string>& parms, + const std::map<std::string,int>& ignorekeywords = std::map<std::string,int>()); + +/// A single test outcome record. +class TestOutcome { + public: + /// Test result + typedef enum { + NOTE = 0, + PASSED = 1, + WARNING = 2, + ERROR = 3, + LAST = 4 + } SeverityLevel; + /// Print strings for SeverityLevel + static std::string SeverityLevelName[LAST]; + /// Name of component under test + std::string component; + /// Name of test + std::string testname; + /// Condition being tested + std::string testcond; + /// Test result + SeverityLevel severity; + /// Set to true if problem is expected + bool expected; + /// Name of code file where test executed + std::string filename; + /// Line number in code file where test executed + int linenumber; + /// Standard constructor + TestOutcome(const std::string& comp, const std::string& tst, + const char* cond, SeverityLevel sev, + const char* file, int line, bool exp = false) + : component(comp),testname(tst),testcond(cond),severity(sev), + expected(exp),filename(file),linenumber(line) + { } + /// Print the test outcome + void print() const; +}; + +/// Utility class to maintain a list of test outcomes. +class TestOutcomes : public std::list<TestOutcome> { + public: + /// Add an outcome to the list + void add(std::string comp, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false) + { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); } + + /*! \brief Add an outcome to the list + + Get the component name from the solver interface. + */ + void add(const OsiSolverInterface& si, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false); + /// Print the list of outcomes + void print() const; + /*! \brief Count total and expected outcomes at given severity level + + Given a severity level, walk the list of outcomes and count the total number + of outcomes at this severity level and the number expected. + */ + void getCountBySeverity(TestOutcome::SeverityLevel sev, + int& total, int& expected) const; +}; + +/// Convert parameter to a string (stringification) +#define OSIUNITTEST_QUOTEME_(x) #x +/// Convert to string with one level of expansion of the parameter +#define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x) + +template <typename Component> +bool OsiUnitTestAssertSeverityExpected( + bool condition, const char * condition_str, const char *filename, + int line, const Component& component, const std::string& testname, + TestOutcome::SeverityLevel severity, bool expected) +{ + if (condition) { + OsiUnitTest::outcomes.add(component, testname, condition_str, + OsiUnitTest::TestOutcome::PASSED, filename, line, false); + if (OsiUnitTest::verbosity >= 2) { + std::ostringstream successmsg; + successmsg << __FILE__ << ":" << __LINE__ << ": " << testname + << " (condition \'" << condition_str << "\') passed.\n"; + OsiUnitTest::testingMessage(successmsg.str().c_str()); + } + return true; + } + OsiUnitTest::outcomes.add(component, testname, condition_str, + severity, filename, line, expected); + OsiUnitTest::failureMessage(component, testname, condition_str); + switch (OsiUnitTest::haltonerror) { + case 2: + { if (severity >= OsiUnitTest::TestOutcome::ERROR ) std::abort(); break; } + case 1: + { std::cout << std::endl << "press any key to continue..." << std::endl; + std::getchar(); + break ; } + default: ; + } + return false; +} + +/// Add a test outcome to the list held in OsiUnitTest::outcomes +#define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \ + OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\ + __FILE__,__LINE__,expected) +/*! \brief Test for a condition and record the result + + Test \p condition and record the result in OsiUnitTest::outcomes. + If it succeeds, record the result as OsiUnitTest::TestOutcome::PASSED and print + a message for OsiUnitTest::verbosity >= 2. + If it fails, record the test as failed with \p severity and \p expected and + react as specified by OsiUnitTest::haltonerror. + + \p failurecode is executed when failure is not fatal. +*/ +#define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\ + testname, severity, expected) \ +{ \ + if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \ + __FILE__, __LINE__, component, testname, severity, expected)) { \ + failurecode; \ + } \ +} + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::ERROR, failure not + expected. +*/ +#define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::ERROR,false) + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::WARNING, failure + not expected. +*/ +#define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::WARNING,false) + +/*! \brief Perform a test surrounded by a try/catch block + + \p trycode is executed in a try/catch block; if there's no throw the test is deemed + to have succeeded and is recorded in OsiUnitTest::outcomes with status + OsiUnitTest::TestOutcome::PASSED. If the \p trycode throws a CoinError, the failure + is recorded with status \p severity and \p expected and the value of + OsiUnitTest::haltonerror is consulted. If the failure is not fatal, \p catchcode is + executed. If any other error is thrown, the failure is recorded as for a CoinError + and \p catchcode is executed (haltonerror is not consulted). +*/ +#define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\ + severity, expected) \ +{ \ + try { \ + trycode; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\ + OsiUnitTest::TestOutcome::PASSED,false); \ + if (OsiUnitTest::verbosity >= 2) { \ + std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \ + successmsg = successmsg + testname; \ + successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \ + successmsg = successmsg + ".\n" ; \ + OsiUnitTest::testingMessage(successmsg.c_str()); \ + } \ + } catch (CoinError& e) { \ + std::stringstream errmsg; \ + errmsg << #trycode " threw CoinError: " << e.message(); \ + if (e.className().length() > 0) \ + errmsg << " in " << e.className(); \ + if (e.methodName().length() > 0) \ + errmsg << " in " << e.methodName(); \ + if (e.lineNumber() >= 0) \ + errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\ + severity,expected); \ + OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \ + switch(OsiUnitTest::haltonerror) { \ + case 2: \ + { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \ + case 1: \ + { std::cout << std::endl << "press any key to continue..." << std::endl; \ + getchar(); \ + break ; } \ + default: ; \ + } \ + catchcode; \ + } catch (...) { \ + std::string errmsg; \ + errmsg = #trycode; \ + errmsg = errmsg + " threw unknown exception"; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \ + OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \ + catchcode; \ + } \ +} + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::ERROR, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false) + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::WARNING, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false) + +} // end namespace OsiUnitTest + +#endif /*OSISOLVERINTERFACETEST_HPP_*/ diff --git a/thirdparty/linux/include/coin/coin/PardisoLoader.h b/thirdparty/linux/include/coin/coin/PardisoLoader.h new file mode 100644 index 0000000..0942521 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/PardisoLoader.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2008 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: PardisoLoader.h 2204 2013-04-13 13:49:26Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef PARDISOLOADER_H_ +#define PARDISOLOADER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + /** Tries to load a dynamically linked library with Pardiso. + * Return a failure if the library cannot be loaded or not all Pardiso symbols are found. + * @param libname The name under which the Pardiso lib can be found, or NULL to use a default name (libpardiso.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadPardisoLib(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded Pardiso library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadPardisoLib(); + + /** Indicates whether a Pardiso library has been successfully loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isPardisoLoaded(); + + /** Returns name of the shared library that should contain Pardiso */ + char* LSL_PardisoLibraryName(); +#ifdef __cplusplus +} +#endif + +#endif /*PARADISOLOADER_H_*/ diff --git a/thirdparty/linux/include/coin/coin/SymConfig.h b/thirdparty/linux/include/coin/coin/SymConfig.h new file mode 100644 index 0000000..08cb201 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/SymConfig.h @@ -0,0 +1,19 @@ +/* include/config_sym.h. Generated by configure. */ +/* include/config_sym.h.in. */ + +#ifndef __CONFIG_SYM_H__ +#define __CONFIG_SYM_H__ + +/* Version number of project */ +#define SYMPHONY_VERSION "5.6.16" + +/* Major Version number of project */ +#define SYMPHONY_VERSION_MAJOR 5 + +/* Minor Version number of project */ +#define SYMPHONY_VERSION_MINOR 6 + +/* Release Version number of project */ +#define SYMPHONY_VERSION_RELEASE 16 + +#endif diff --git a/thirdparty/linux/include/coin/coin/SymWarmStart.hpp b/thirdparty/linux/include/coin/coin/SymWarmStart.hpp new file mode 100644 index 0000000..74089d1 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/SymWarmStart.hpp @@ -0,0 +1,72 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef SymWarmStart_H +#define SymWarmStart_H + +#include "CoinWarmStart.hpp" + +typedef struct WARM_START_DESC warm_start_desc; + +//############################################################################# + +class SymWarmStart : public CoinWarmStart +{ + +public: + + /* Default constructor. Will do nothing! */ + SymWarmStart(){} + + /* Initialize the warmStart_ using the given warm start. If dominate + WarmStart is set, then, SymWarmStart will take the control of the + given description, otherwise, will copy everything. + */ + SymWarmStart(warm_start_desc * ws); + + /*Get the warmStart info from a file*/ + SymWarmStart(char *f); + + /* Copy constructor */ + SymWarmStart(const SymWarmStart & symWS); + + /* Destructor */ + virtual ~SymWarmStart(); + + /* Clone the warmstart */ + virtual CoinWarmStart * clone() const; + + /* Get the pointer to the loaded warmStart_ */ + virtual warm_start_desc * getCopyOfWarmStartDesc(); + + /* Move the pointer to the rootnode of the warmStart to another + node which will change the underlying tree + */ + // virtual void setRoot(bc_node *root) {} //FIX_ME! Ask Prof. Ralphs. + + /* Write the current warm start info to a file */ + virtual int writeToFile(char * f); + +private: + + /* Private warm start desc. to keep everything */ + warm_start_desc *warmStart_; + +}; + +#endif diff --git a/thirdparty/linux/include/coin/coin/ThirdParty/dmumps_c.h b/thirdparty/linux/include/coin/coin/ThirdParty/dmumps_c.h new file mode 100644 index 0000000..1d5c2c9 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ThirdParty/dmumps_c.h @@ -0,0 +1,159 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Mostly written in march 2002 (JYL) */ + +#ifndef DMUMPS_C_H +#define DMUMPS_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mumps_compat.h" +/* Next line defines MUMPS_INT, DMUMPS_COMPLEX and DMUMPS_REAL */ +#include "mumps_c_types.h" + +#ifndef MUMPS_VERSION +/* Protected in case headers of other arithmetics are included */ +#define MUMPS_VERSION "4.10.0" +#endif +#ifndef MUMPS_VERSION_MAX_LEN +#define MUMPS_VERSION_MAX_LEN 14 +#endif + +/* + * Definition of the (simplified) MUMPS C structure. + * NB: DMUMPS_COMPLEX are REAL types in s and d arithmetics. + */ +typedef struct { + + MUMPS_INT sym, par, job; + MUMPS_INT comm_fortran; /* Fortran communicator */ + MUMPS_INT icntl[40]; + DMUMPS_REAL cntl[15]; + MUMPS_INT n; + + MUMPS_INT nz_alloc; /* used in matlab interface to decide if we + free + malloc when we have large variation */ + + /* Assembled entry */ + MUMPS_INT nz; + MUMPS_INT *irn; + MUMPS_INT *jcn; + DMUMPS_COMPLEX *a; + + /* Distributed entry */ + MUMPS_INT nz_loc; + MUMPS_INT *irn_loc; + MUMPS_INT *jcn_loc; + DMUMPS_COMPLEX *a_loc; + + /* Element entry */ + MUMPS_INT nelt; + MUMPS_INT *eltptr; + MUMPS_INT *eltvar; + DMUMPS_COMPLEX *a_elt; + + /* Ordering, if given by user */ + MUMPS_INT *perm_in; + + /* Orderings returned to user */ + MUMPS_INT *sym_perm; /* symmetric permutation */ + MUMPS_INT *uns_perm; /* column permutation */ + + /* Scaling (input only in this version) */ + DMUMPS_REAL *colsca; + DMUMPS_REAL *rowsca; + + /* RHS, solution, ouptput data and statistics */ + DMUMPS_COMPLEX *rhs, *redrhs, *rhs_sparse, *sol_loc; + MUMPS_INT *irhs_sparse, *irhs_ptr, *isol_loc; + MUMPS_INT nrhs, lrhs, lredrhs, nz_rhs, lsol_loc; + MUMPS_INT schur_mloc, schur_nloc, schur_lld; + MUMPS_INT mblock, nblock, nprow, npcol; + MUMPS_INT info[40],infog[40]; + DMUMPS_REAL rinfo[40], rinfog[40]; + + /* Null space */ + MUMPS_INT deficiency; + MUMPS_INT *pivnul_list; + MUMPS_INT *mapping; + + /* Schur */ + MUMPS_INT size_schur; + MUMPS_INT *listvar_schur; + DMUMPS_COMPLEX *schur; + + /* Internal parameters */ + MUMPS_INT instance_number; + DMUMPS_COMPLEX *wk_user; + + /* Version number: length=14 in FORTRAN + 1 for final \0 + 1 for alignment */ + char version_number[MUMPS_VERSION_MAX_LEN + 1 + 1]; + /* For out-of-core */ + char ooc_tmpdir[256]; + char ooc_prefix[64]; + /* To save the matrix in matrix market format */ + char write_problem[256]; + MUMPS_INT lwk_user; + +} DMUMPS_STRUC_C; + + +void MUMPS_CALL +dmumps_c( DMUMPS_STRUC_C * dmumps_par ); + +#ifdef __cplusplus +} +#endif + +#endif /* DMUMPS_C_H */ + diff --git a/thirdparty/linux/include/coin/coin/ThirdParty/mpi.h b/thirdparty/linux/include/coin/coin/ThirdParty/mpi.h new file mode 100644 index 0000000..7ab0c37 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ThirdParty/mpi.h @@ -0,0 +1,77 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +#ifndef MUMPS_MPI_H +#define MUMPS_MPI_H + +/* We define all symbols as extern "C" for users who call MUMPS with its + libseq from a C++ driver. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the minimum to have the C interface of MUMPS work. + * Most of the time, users who need this file have no call to MPI functions in + * their own code. Hence it is not worth declaring all MPI functions here. + * However if some users come to request some more stub functions of the MPI + * standards, we may add them. But it is not worth doing it until then. */ + +typedef int MPI_Comm; /* Simple type for MPI communicator */ +static MPI_Comm MPI_COMM_WORLD=(MPI_Comm)0; + +int MPI_Init(int *pargc, char ***pargv); +int MPI_Comm_rank(int comm, int *rank); +int MPI_Finalize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MUMPS_MPI_H */ diff --git a/thirdparty/linux/include/coin/coin/ThirdParty/mumps_c_types.h b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_c_types.h new file mode 100644 index 0000000..aef6212 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_c_types.h @@ -0,0 +1,92 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + + +#ifndef MUMPS_C_TYPES_H +#define MUMPS_C_TYPES_H + +#define MUMPS_INT int + +#define SMUMPS_COMPLEX float +#define SMUMPS_REAL float + +#define DMUMPS_COMPLEX double +#define DMUMPS_REAL double + +/* Complex datatypes */ +typedef struct {float r,i;} mumps_complex; +typedef struct {double r,i;} mumps_double_complex; + +#define CMUMPS_COMPLEX mumps_complex +#define CMUMPS_REAL float + +#define ZMUMPS_COMPLEX mumps_double_complex +#define ZMUMPS_REAL double + + +#ifndef mumps_ftnlen +/* When passing a string, what is the type of the extra argument + * passed by value ? */ +# define mumps_ftnlen int +#endif + + +#define MUMPS_ARITH_s 1 +#define MUMPS_ARITH_d 2 +#define MUMPS_ARITH_c 4 +#define MUMPS_ARITH_z 8 + +#define MUMPS_ARITH_REAL ( MUMPS_ARITH_s | MUMPS_ARITH_d ) +#define MUMPS_ARITH_CMPLX ( MUMPS_ARITH_c | MUMPS_ARITH_z ) +#define MUMPS_ARITH_SINGLE ( MUMPS_ARITH_s | MUMPS_ARITH_c ) +#define MUMPS_ARITH_DBL ( MUMPS_ARITH_d | MUMPS_ARITH_z ) + + +#endif /* MUMPS_C_TYPES_H */ diff --git a/thirdparty/linux/include/coin/coin/ThirdParty/mumps_compat.h b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_compat.h new file mode 100644 index 0000000..d63120e --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_compat.h @@ -0,0 +1,78 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Compatibility issues between various Windows versions */ +#ifndef MUMPS_COMPAT_H +#define MUMPS_COMPAT_H + + +#if defined(_WIN32) && ! defined(__MINGW32__) +# define MUMPS_WIN32 1 +#endif + +#ifndef MUMPS_CALL +# ifdef MUMPS_WIN32 +/* Modify/choose between next 2 lines depending + * on your Windows calling conventions */ +/* # define MUMPS_CALL __stdcall */ +# define MUMPS_CALL +# else +# define MUMPS_CALL +# endif +#endif + +#if (__STDC_VERSION__ >= 199901L) +# define MUMPS_INLINE static inline +#else +# define MUMPS_INLINE +#endif + + +#endif /* MUMPS_COMPAT_H */ diff --git a/thirdparty/linux/include/coin/coin/ThirdParty/mumps_mpi.h b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_mpi.h new file mode 100644 index 0000000..7ab0c37 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/ThirdParty/mumps_mpi.h @@ -0,0 +1,77 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +#ifndef MUMPS_MPI_H +#define MUMPS_MPI_H + +/* We define all symbols as extern "C" for users who call MUMPS with its + libseq from a C++ driver. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the minimum to have the C interface of MUMPS work. + * Most of the time, users who need this file have no call to MPI functions in + * their own code. Hence it is not worth declaring all MPI functions here. + * However if some users come to request some more stub functions of the MPI + * standards, we may add them. But it is not worth doing it until then. */ + +typedef int MPI_Comm; /* Simple type for MPI communicator */ +static MPI_Comm MPI_COMM_WORLD=(MPI_Comm)0; + +int MPI_Init(int *pargc, char ***pargv); +int MPI_Comm_rank(int comm, int *rank); +int MPI_Finalize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MUMPS_MPI_H */ diff --git a/thirdparty/linux/include/coin/coin/symphony.h b/thirdparty/linux/include/coin/coin/symphony.h new file mode 100644 index 0000000..9106e82 --- /dev/null +++ b/thirdparty/linux/include/coin/coin/symphony.h @@ -0,0 +1,328 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY MILP Solver Framework. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (ted@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2005-2015 Ted Ralphs. All Rights Reserved. */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef _SYM_API_H +#define _SYM_API_H + +#define COMPILING_FOR_MASTER + +#ifdef PROTO +#undef PROTO +#endif +#define PROTO(x) x + +/***************************************************************************** + ***************************************************************************** + ************* ********** + ************* Return Values ********** + ************* ********** + ***************************************************************************** + *****************************************************************************/ + +/*----------------------- Global return codes -------------------------------*/ +#define FUNCTION_TERMINATED_NORMALLY 0 +#define FUNCTION_TERMINATED_ABNORMALLY -1 +#define ERROR__USER -100 + +/*-------------- Return codes for sym_parse_comand_line() -------------------*/ +#define ERROR__OPENING_PARAM_FILE -110 +#define ERROR__PARSING_PARAM_FILE -111 + +/*----------------- Return codes for sym_load_problem() ---------------------*/ +#define ERROR__READING_GMPL_FILE -120 +#define ERROR__READING_WARM_START_FILE -121 +#define ERROR__READING_MPS_FILE -122 +#define ERROR__READING_LP_FILE -123 + +/*-------------------- Return codes for sym_solve() -------------------------*/ +#define TM_NO_PROBLEM 225 +#define TM_NO_SOLUTION 226 +#define TM_OPTIMAL_SOLUTION_FOUND 227 +#define TM_TIME_LIMIT_EXCEEDED 228 +#define TM_NODE_LIMIT_EXCEEDED 229 +#define TM_ITERATION_LIMIT_EXCEEDED 230 +#define TM_TARGET_GAP_ACHIEVED 231 +#define TM_FOUND_FIRST_FEASIBLE 232 +#define TM_FINISHED 233 +#define TM_UNFINISHED 234 +#define TM_FEASIBLE_SOLUTION_FOUND 235 +#define TM_SIGNAL_CAUGHT 236 +#define TM_UNBOUNDED 237 +#define PREP_OPTIMAL_SOLUTION_FOUND 238 +#define PREP_NO_SOLUTION 239 +#define TM_ERROR__NO_BRANCHING_CANDIDATE -250 +#define TM_ERROR__ILLEGAL_RETURN_CODE -251 +#define TM_ERROR__NUMERICAL_INSTABILITY -252 +#define TM_ERROR__COMM_ERROR -253 +#define TM_ERROR__USER -275 +#define PREP_ERROR -276 + +/***************************************************************************** + ***************************************************************************** + ************* ********** + ************* General Constants ********** + ************* ********** + ***************************************************************************** + *****************************************************************************/ + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef ANYONE +#define ANYONE -1 +#endif +#ifndef ANYTHING +#define ANYTHING -1 +#endif + +#define DSIZE sizeof(double) +#define ISIZE sizeof(int) +#define CSIZE sizeof(char) + +#ifndef BITSPERBYTE +#define BITSPERBYTE 8 +#endif +#ifndef BITS +#define BITS(type) (BITSPERBYTE * (int)sizeof (type)) +#endif + +#ifdef HIBITI +#undef HIBITI +#endif +#define HIBITI (1U << (BITS(int) - 1)) +#ifdef MAXINT +#undef MAXINT +#endif +#define MAXINT ((int)(~(HIBITI))) +#ifdef MAXDOUBLE +#undef MAXDOUBLE +#endif +#define MAXDOUBLE 1.79769313486231570e+308 + +#define SYM_INFINITY 1e20 + +#define BIG_DBL 1e40 + +#define SYM_MINIMIZE 0 +#define SYM_MAXIMIZE 1 + +#define MAX_NAME_SIZE 255 + +/*--------------------- return values for user-written functions ------------*/ +#define USER_ERROR -5 +#define USER_SUCCESS -4 +#define USER_NO_PP -3 +#define USER_AND_PP -2 +#define USER_DEFAULT -1 + +/*------------ search order options for multi-criteria problems -------------*/ +#define MC_FIFO 0 +#define MC_LIFO 1 + +/*------------ warm_starting options for multi-criteria problems -------------*/ +#define MC_WS_UTOPIA_FIRST 0 +#define MC_WS_UTOPIA_BOTH_FIXED 1 +#define MC_WS_UTOPIA_BOTH 2 +#define MC_WS_BEST_CLOSE 3 + +/*------------------------ compare_candidates -------------------------------*/ +#define BIGGEST_DIFFERENCE_OBJ 0 +#define LOWEST_LOW_OBJ 1 +#define HIGHEST_LOW_OBJ 2 +#define LOWEST_HIGH_OBJ 3 +#define HIGHEST_HIGH_OBJ 4 +#define HIGH_LOW_COMBINATION 9 + +/*--------------------------- select_child ----------------------------------*/ +#define PREFER_LOWER_OBJ_VALUE 0 +#define PREFER_HIGHER_OBJ_VALUE 1 + +/*-------------------- generate_cuts_in_lp defaults -------------------------*/ +#define GENERATE_CGL_CUTS 20 +#define DO_NOT_GENERATE_CGL_CUTS 21 + +/*-------------------- xxx_cuts_generation_levels ---------------------------*/ +#define DO_NOT_GENERATE -1 +#define GENERATE_DEFAULT 0 +#define GENERATE_IF_IN_ROOT 1 +#define GENERATE_ONLY_IN_ROOT 2 +#define GENERATE_ALWAYS 3 +#define GENERATE_PERIODICALLY 4 + +/*------------------------- node selection rules ----------------------------*/ +#define LOWEST_LP_FIRST 0 +#define HIGHEST_LP_FIRST 1 +#define BREADTH_FIRST_SEARCH 2 +#define DEPTH_FIRST_SEARCH 3 +#define BEST_FIRST_SEARCH 4 +#define DEPTH_FIRST_THEN_BEST_FIRST 5 + +/*-------------------------- diving_strategy --------------------------------*/ +#define BEST_ESTIMATE 0 +#define COMP_BEST_K 1 +#define COMP_BEST_K_GAP 2 + +/*--------------- parameter values for feasibility pump heuristic -----------*/ +#define SYM_FEAS_PUMP_DEFAULT 1 /* use fp using the default rules */ +#define SYM_FEAS_PUMP_REPEATED 2 /* use fp till the end of solve */ +#define SYM_FEAS_PUMP_TILL_SOL 3 /* use fp till a solution is found */ +#define SYM_FEAS_PUMP_DISABLE -1 /* dont use fp */ + +typedef struct MIPDESC MIPdesc; +typedef struct WARM_START_DESC warm_start_desc; +typedef struct SYM_ENVIRONMENT sym_environment; + +/*===========================================================================*/ +/*===================== Interface functions (master.c) ======================*/ +/*===========================================================================*/ + +void sym_version PROTO((void)); +sym_environment *sym_open_environment PROTO((void)); +int sym_close_environment PROTO((sym_environment *env)); +int sym_reset_environment PROTO((sym_environment *env)); +int sym_set_defaults PROTO((sym_environment *env)); +int sym_parse_command_line PROTO((sym_environment *env, int argc, + char **argv)); +int sym_set_user_data PROTO((sym_environment *env, void *user)); +int sym_get_user_data PROTO((sym_environment *env, void **user)); +int sym_read_mps PROTO((sym_environment *env, char *infile)); +int sym_read_lp PROTO((sym_environment *env, char *infile)); +int sym_read_gmpl PROTO((sym_environment *env, char *modelfile, + char *datafile)); +int sym_write_mps PROTO((sym_environment *env, char *infile)); +int sym_write_lp PROTO((sym_environment *env, char *infile)); + +int sym_load_problem PROTO((sym_environment *env)); +int sym_find_initial_bounds PROTO((sym_environment *env)); + +int sym_solve PROTO((sym_environment *env)); +int sym_warm_solve PROTO((sym_environment *env)); +int sym_mc_solve PROTO((sym_environment *env)); + +int sym_create_permanent_cut_pools PROTO((sym_environment *env, int *cp_num)); +int sym_explicit_load_problem PROTO((sym_environment *env, int numcols, + int numrows, int *start, int *index, + double *value, double *collb, + double *colub, char *is_int, double *obj, + double *obj2, char *rowsen, + double *rowrhs, double *rowrng, + char make_copy)); + +int sym_is_abandoned PROTO((sym_environment *env)); +int sym_is_proven_optimal PROTO((sym_environment *env)); +int sym_is_proven_primal_infeasible PROTO((sym_environment *env)); +int sym_is_iteration_limit_reached PROTO((sym_environment *env)); +int sym_is_time_limit_reached PROTO((sym_environment *env)); +int sym_is_target_gap_achieved PROTO((sym_environment *env)); + +int sym_get_status PROTO((sym_environment *env)); +int sym_get_num_cols PROTO((sym_environment *env, int *numcols)); +int sym_get_num_rows PROTO((sym_environment *env, int *numrows)); +int sym_get_num_elements PROTO((sym_environment *env, int *numelems)); +int sym_get_col_lower PROTO((sym_environment *env, double *collb)); +int sym_get_col_upper PROTO((sym_environment *env, double *colub)); +int sym_get_row_sense PROTO((sym_environment *env, char *rowsen)); +int sym_get_rhs PROTO((sym_environment *env, double *rowrhs)); +int sym_get_matrix PROTO((sym_environment *env, int *nz, int *matbeg, + int *matind, double *matval)); +int sym_get_row_range PROTO((sym_environment *env, double *rowrng)); +int sym_get_row_lower PROTO((sym_environment *env, double *rowlb)); +int sym_get_row_upper PROTO((sym_environment *env, double *rowub)); +int sym_get_obj_coeff PROTO((sym_environment *env, double *obj)); +int sym_get_obj2_coeff PROTO((sym_environment *env, double *obj2)); +int sym_get_obj_sense PROTO((sym_environment *env, int *sense)); + +int sym_is_continuous PROTO((sym_environment *env, int index, int *value)); +int sym_is_binary PROTO((sym_environment *env, int index, int *value)); +int sym_is_integer PROTO((sym_environment *env, int index, char *value)); + +double sym_get_infinity PROTO(()); + +int sym_get_col_solution PROTO((sym_environment *env, double *colsol)); +int sym_get_sp_size PROTO((sym_environment *env, int *size)); +int sym_get_sp_solution PROTO((sym_environment *env, int index, + double *colsol, double *objval)); +int sym_get_row_activity PROTO((sym_environment *env, double *rowact)); +int sym_get_obj_val PROTO((sym_environment *env, double *objval)); +int sym_get_primal_bound PROTO((sym_environment *env, double *ub)); +int sym_get_iteration_count PROTO((sym_environment *env, int *numnodes)); + +int sym_set_obj_coeff PROTO((sym_environment *env, int index, double value)); +int sym_set_obj2_coeff PROTO((sym_environment *env, int index, double value)); +int sym_set_col_lower PROTO((sym_environment *env, int index, double value)); +int sym_set_col_upper PROTO((sym_environment *env, int index, double value)); +int sym_set_row_lower PROTO((sym_environment *env, int index, double value)); +int sym_set_row_upper PROTO((sym_environment *env, int index, double value)); +int sym_set_row_type PROTO((sym_environment *env, int index, char rowsense, + double rowrhs, double rowrng)); +int sym_set_obj_sense PROTO((sym_environment *env, int sense)); +int sym_set_col_solution PROTO((sym_environment *env, double * colsol)); +int sym_set_primal_bound PROTO((sym_environment *env, double bound)); +int sym_set_continuous PROTO((sym_environment *env, int index)); +int sym_set_integer PROTO((sym_environment *env, int index)); +int sym_set_col_names PROTO((sym_environment *env, char **colname)); +int sym_add_col PROTO((sym_environment *env, int numelems, int *indices, + double *elements, double collb, double colub, + double obj, char is_int, char *name)); +int sym_add_row PROTO((sym_environment *env, int numelems, int *indices, + double *elements, char rowsen, double rowrhs, + double rowrng)); +int sym_delete_cols PROTO((sym_environment *env, int num, int * indices)); +int sym_delete_rows PROTO((sym_environment *env, int num, int * indices)); + +int sym_write_warm_start_desc PROTO((warm_start_desc *ws, char *file)); +warm_start_desc *sym_read_warm_start PROTO((char *file)); + +void sym_delete_warm_start PROTO((warm_start_desc *ws)); +warm_start_desc *sym_get_warm_start PROTO((sym_environment *env, + int copy_warm_start)); + +int sym_set_warm_start PROTO((sym_environment *env, warm_start_desc *ws)); + +int sym_set_int_param PROTO((sym_environment *env, const char *key, int value)); +int sym_set_dbl_param PROTO((sym_environment *env, const char *key, double value)); +int sym_set_str_param PROTO((sym_environment *env, const char *key, const char *value)); + +int sym_get_int_param PROTO((sym_environment *env, const char *key, int *value)); +int sym_get_dbl_param PROTO((sym_environment *env, const char *key, double *value)); +int sym_get_str_param PROTO((sym_environment *env, const char *key, char **value)); + +int sym_get_lb_for_new_rhs PROTO((sym_environment *env, int cnt, + int *new_rhs_ind, double *new_rhs_val, + double *lb_for_new_rhs)); +int sym_get_ub_for_new_rhs PROTO((sym_environment *env, int cnt, + int *new_rhs_ind, double *new_rhs_val, + double *ub_for_new_rhs)); +#if 0 +int sym_get_lb_for_new_obj PROTO((sym_environment *env, int cnt, + int *new_obj_ind, double *new_obj_val, + double *lb_for_new_obj)); +#endif +int sym_get_ub_for_new_obj PROTO((sym_environment *env, int cnt, + int *new_obj_ind, double *new_obj_val, + double *ub_for_new_obj)); + +warm_start_desc *sym_create_copy_warm_start PROTO((warm_start_desc * ws)); +MIPdesc *sym_create_copy_mip_desc PROTO((sym_environment *env)); +MIPdesc *sym_get_presolved_mip_desc PROTO((sym_environment *env)); +sym_environment * sym_create_copy_environment PROTO((sym_environment *env)); + +int sym_test PROTO((sym_environment *env, int argc, char **argv, + int *test_status)); + +#endif diff --git a/thirdparty/linux/include/coin/cone.h b/thirdparty/linux/include/coin/cone.h new file mode 100644 index 0000000..9fb28e6 --- /dev/null +++ b/thirdparty/linux/include/coin/cone.h @@ -0,0 +1,171 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* cone module */
+
+#ifndef __CONE_H__
+#define __CONE_H__
+
+#include "glblopts.h"
+#include "expcone.h"
+
+#define CONEMODE (0) /* 0: expand to sparse cones (ECOS standard) */
+ /* 1: dense cones (slow for big cones) */
+ /* 2: dense of fixed size */
+
+
+/* LP CONE ------------------------------------------------------------- */
+typedef struct lpcone{
+ idxint p; /* dimension of cone */
+ pfloat* w; /* scalings */
+ pfloat* v; /* = w^2 - saves p multiplications */
+ idxint* kkt_idx; /* indices of KKT matrix to which scalings w^2 map */
+} lpcone;
+
+
+/* SECOND-ORDER CONE --------------------------------------------------- */
+/* (all KKT indices are in compressed column format pointing into Kpr) */
+typedef struct socone{
+ idxint p; /* dimension of cone */
+ pfloat* skbar; /* temporary variables to work with */
+ pfloat* zkbar; /* temporary variables to work with */
+ pfloat a; /* = wbar(1) */
+ pfloat d1; /* first element of D */
+ pfloat w; /* = q'*q */
+ pfloat eta; /* eta = (sres / zres)^(1/4) */
+ pfloat eta_square; /* eta^2 = (sres / zres)^(1/2) */
+ pfloat* q; /* = wbar(2:end) */
+#if CONEMODE == 0
+ idxint* Didx; /* indices for D */
+ pfloat u0; /* eta */
+ pfloat u1; /* u = [u0; u1*q] */
+ pfloat v1; /* v = [0; v1*q] */
+#endif
+#if CONEMODE > 0
+ idxint* colstart; /* colstart[n] gives index in KKT matrix where
+ the nth column of this scaling matrix in (3,3)
+ block starts */
+ pfloat c; /* = 1 + a + w/(1+a) */
+ pfloat d; /* = 1 + 2/(1+a) + w/(1+a)^2 */
+#endif
+
+} socone;
+
+
+/* GENERAL STRUCTURE FOR A CONE ---------------------------------------- */
+typedef struct cone{
+ lpcone* lpc; /* LP cone */
+ socone* soc; /* Second-Order cone */
+ idxint nsoc; /* number of second-order cones */
+#ifdef EXPCONE
+ expcone* expc; /* array of exponential cones*/
+ idxint nexc; /* number of exponential cones*/
+ idxint fexv; /* Index of first slack variable
+ * corresponding to an exponential cone */
+#endif
+} cone;
+
+
+/* ERROR CODES --------------------------------------------------------- */
+#define INSIDE_CONE (0)
+#define OUTSIDE_CONE (1)
+
+
+/* METHODS ------------------------------------------------------------- */
+/**
+ * Scales a conic variable such that it lies strictly in the cone.
+ * If it is already in the cone, r is simply copied to s.
+ * Otherwise s = r + (1+alpha)*e where alpha is the biggest residual.
+ */
+void bring2cone(cone* C, pfloat* r, pfloat* s);
+
+#ifdef EXPCONE
+/* When there are exponential variables in the definition of the problem
+ * the initialization strategy changes to using the central ray for all
+ * cones.
+ */
+void unitInitialization(cone* C, pfloat* s, pfloat* z, pfloat scaling);
+#endif
+
+/**
+ * Update scalings.
+ * Returns OUTSIDE_CONE as soon as any multiplier or slack leaves the cone,
+ * as this indicates severe problems.
+ * When compiled with EXPCONE it calculates the value of muH(z_e) with
+ * z_e the dual slacks for the exponential cone
+ * and stores the Hessian in the cone structure.
+ */
+#ifdef EXPCONE
+idxint updateScalings(cone* C, pfloat* s, pfloat* z, pfloat* lambda, pfloat mu);
+#else
+idxint updateScalings(cone* C, pfloat* s, pfloat* z, pfloat* lambda);
+#endif
+
+#ifdef EXPCONE
+pfloat evalSymmetricBarrierValue(pfloat* siter, pfloat *ziter, pfloat tauIter, pfloat kapIter, cone* C, pfloat D);
+#endif
+
+/**
+ * Fast multiplication by scaling matrix.
+ * Returns lambda = W*z
+ */
+void scale(pfloat* z, cone* C, pfloat* lambda);
+
+
+/**
+ * Fast multiplication with V := W^2.
+ * Computes y += W^2*x;
+ */
+void scale2add(pfloat *x, pfloat* y, cone* C);
+
+/**
+ * Fast left-division by scaling matrix.
+ * Returns z = W\lambda
+ */
+void unscale(pfloat* lambda, cone* C, pfloat* z);
+
+
+/**
+ * Conic product, implements the "o" operator, w = u o v
+ * and returns e'*w (where e is the conic 1-vector)
+ */
+pfloat conicProduct(pfloat* u, pfloat* v, cone* C, pfloat* w);
+
+
+/**
+ * Conic division, implements the "\" operator, w = u \ v
+ */
+void conicDivision(pfloat* u, pfloat* v, cone* C, pfloat* w);
+
+
+/*
+ * Returns details on second order cone
+ * Purpose: cleaner code
+ */
+void getSOCDetails(socone *soc, idxint *conesize, pfloat* eta_square, pfloat* d1, pfloat* u0, pfloat* u1, pfloat* v1, pfloat **q);
+
+
+/*
+ * Returns dx, dy and dz from the expanded and permuted version of
+ * a search direction vector.
+ */
+void unstretch(idxint n, idxint p, cone *C, idxint *Pinv, pfloat *Px, pfloat *dx, pfloat *dy, pfloat *dz);
+
+#endif
diff --git a/thirdparty/linux/include/coin/ctrlc.h b/thirdparty/linux/include/coin/ctrlc.h new file mode 100644 index 0000000..61b717a --- /dev/null +++ b/thirdparty/linux/include/coin/ctrlc.h @@ -0,0 +1,66 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Interface for ECOS signal handling. + * + * This module is (c) Michael Grant, [mcg@cvxr.com] contributed by Github PR #82 + */ + +#ifndef __CTRLC_H__ +#define __CTRLC_H__ + +#include "glblopts.h" + +#if CTRLC > 0 + +#if defined MATLAB_MEX_FILE + +/* No header file available here; define the prototypes ourselves */ +extern bool utIsInterruptPending(void); +extern bool utSetInterruptEnabled(bool); + +#elif (defined _WIN32 || defined _WIN64 || defined _WINDLL ) + +/* Use Windows SetConsoleCtrlHandler for signal handling */ +#include <windows.h> + +#else + +/* Use POSIX clocl_gettime() for timing on non-Windows machines */ +#include <signal.h> + +#endif + +/* METHODS are the same for both */ +void init_ctrlc(void); +void remove_ctrlc(void); +int check_ctrlc(void); + +#else /* CTRLC = 0 */ + +/* No signal handling. */ +#define init_ctrlc() +#define remove_ctrlc() +#define check_ctrlc() 0 + +#endif /* END IF CTRLC > 0 */ + +#endif /* END IFDEF __TIMER_H__ */ + diff --git a/thirdparty/linux/include/coin/data.h b/thirdparty/linux/include/coin/data.h new file mode 100644 index 0000000..e648008 --- /dev/null +++ b/thirdparty/linux/include/coin/data.h @@ -0,0 +1,37 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+idxint n = 223;
+idxint m = 220;
+idxint p = 114;
+idxint l = 201;
+idxint ncones = 6;
+pfloat c[223] = {0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+pfloat h[220] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+idxint q[6] = {3, 3, 3, 3, 3, 4};
+idxint Gjc[224] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220};
+idxint Gir[220] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219};
+pfloat Gpr[220] = {-1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000};
+idxint Ajc[224] = {0, 111, 222, 322, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 539, 540, 541, 564, 565, 566, 589, 590, 591, 618, 619, 620, 632, 633, 634, 635, 636, 637, 638};
+idxint Air[638] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 112, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 110, 113, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 3, 9, 15, 27, 53, 54, 57, 66, 67, 71, 74, 87, 92, 96, 98, 100, 101, 2, 8, 12, 19, 29, 30, 34, 37, 39, 42, 43, 44, 47, 50, 51, 56, 59, 70, 73, 79, 82, 85, 94, 102, 103, 0, 4, 7, 13, 14, 16, 17, 21, 23, 28, 31, 33, 36, 38, 60, 64, 78, 81, 88, 90, 91, 95, 99, 104, 105, 1, 6, 10, 20, 22, 26, 32, 35, 41, 46, 48, 49, 52, 55, 58, 65, 68, 69, 75, 76, 77, 80, 83, 84, 86, 93, 97, 106, 107, 5, 11, 18, 24, 25, 40, 45, 61, 62, 63, 72, 89, 108, 109, 110, 111, 112, 113};
+pfloat Apr[638] = {-6.748099080141577400e-001, 9.587587238674218900e-001, -3.380262965696901900e-001, -6.289006455522118100e-001, 1.458932368908371500e+000, 8.103505672584934100e-001, -8.308676110497204000e-002, 2.638152658681099300e+000, 1.000625209233638700e+000, 1.443285740856571400e-001, 1.198960671699122800e+000, 8.042866751960948700e-001, -2.146877760548437900e-002, 1.252109754253975600e+000, 1.681372772953815700e+000, 1.160558110039982400e+000, 8.971595941547876300e-001, 9.934462168535226300e-001, 4.030425643552826300e-003, 4.520907269135507900e-001, 1.957531681292445900e+000, 8.367513704018149100e-001, -8.919073879004054700e-001, 1.364968014685880000e-001, -5.391443069926015200e-001, 1.218605709809697200e+000, 1.379628849398701500e+000, 7.705722581573115600e-002, -9.721580354507602900e-001, 1.341091680254979900e+000, 1.416856131617781900e+000, 1.367782802004573000e+000, 9.310015370881947700e-001, 1.025960903569425500e+000, 4.418055920652105800e-001, 1.797608571927105100e-001, -1.566236421056189400e+000, -1.293790728779894400e-001, -2.548793507296202000e-001, -1.327158583802827700e+000, 8.378869252146687900e-001, 9.208088134425553900e-001, 8.954835779157467300e-001, 1.872488747783192400e+000, 1.607749082930002300e-001, 1.703097419135647200e+000, 1.485966470102646500e+000, 1.950727391193988900e+000, 1.261282074772785800e+000, 2.116080672704367100e+000, 4.418819171779880300e-001, -6.070414095655145600e-001, 2.236741804227308500e-001, -1.390565074056968600e+000, -3.689063294445240100e-001, 6.275925564016111600e-001, 9.419119351808997700e-001, 2.051844704916749900e-002, -2.055013180419911200e+000, -8.138411920140069500e-001, -1.670986440999406000e+000, -4.312826132928389000e-001, -1.317178055102502500e-001, 4.129877571668971700e-002, -1.178000809237306800e-001, -5.094809536848188300e-002, 4.887140456297478000e-001, -6.048920026011540600e-001, -1.622657687025348600e+000, 9.468924561461561400e-002, -1.076752006167445400e+000, -4.544402225817885700e-001, -1.138681599263542200e+000, 6.297099350763062400e-001, 7.161553122227841700e-001, -2.326213079050594200e-001, -2.421425730439526200e-001, -3.527400894253913700e-001, -5.991000491511071500e-001, -4.501982881436522000e-001, -1.073527618321097300e+000, -1.837831580649836900e+000, -1.093506922417250900e+000, 3.123080272148109900e-002, 4.764624397863112500e-001, -9.744593174286131400e-001, -5.475935551016516400e-001, -1.185577848308040100e+000, -1.512429413719079500e+000, -8.503358079552569800e-001, -1.048119449917124500e+000, -2.950353712891531400e-001, 4.436355670528358600e-001, -1.976143927829304500e+000, -1.154872945269262400e-001, -8.267783537066453200e-001, -2.524533500828647400e-001, -2.934013148063512300e-001, -9.559308197633347200e-001, -5.099545278978906400e-001, 7.104569782287112300e-001, 2.586151051423653000e-001, 9.670875274511733200e-001, -1.580472136196336100e-001, 4.036019169202506600e-001, -4.419329075671284400e-001, 1.335760493316310000e-001, -2.443367984060260100e-001, 5.346171843774407700e-001, 9.240837092450902800e-002, 1.000000000000000000e+000, -7.627629774659758300e+000, -8.317906940770274800e+000, -7.063111046330970300e+000, -8.991213209598194900e+000, -7.132056801314573300e+000, -6.933147988332642300e+000, -8.002850393982971200e+000, -7.763929473153173600e+000, -7.316196508551362500e+000, -6.857489440772187800e+000, -6.933435917031895100e+000, -8.453055934420948600e+000, -7.746956878849250200e+000, -6.987480243537588000e+000, -6.898256465718047200e+000, -7.035033952525910900e+000, -7.332300809407010800e+000, -8.868148466875196000e+000, -7.895445920224761800e+000, -8.477688226774738200e+000, -6.724790281248850500e+000, -8.026080227654171400e+000, -8.247796522362861500e+000, -7.893131787368933100e+000, -7.953077643849715300e+000, -7.085517647070380700e+000, -7.757918623860442500e+000, -9.404980440162075800e+000, -9.111021916635516900e+000, -6.753547752596220200e+000, -6.208328120779675900e+000, -7.460712402671073400e+000, -8.051154905293161700e+000, -6.979795864345947000e+000, -7.285373299414776400e+000, -7.935549231771511300e+000, -7.333663096710840700e+000, -7.549354579130950400e+000, -7.125439770244579300e+000, -8.444455837718113100e+000, -7.607705936847165300e+000, -6.947711222611268100e+000, -7.559561213742542300e+000, -6.633232534378238100e+000, -7.285067573640397100e+000, -7.198034090285221800e+000, -8.301173708858458500e+000, -7.740676955875905200e+000, -8.389317110487786200e+000, -7.030503781850090800e+000, 7.483837125022816400e-001, 9.972172897309477000e-001, 8.635272324715717000e-001, 3.437357445286000600e-001, 1.356057545748600200e+000, 7.747994541454063000e-001, -5.029337660688439900e-001, 7.320209587792132500e-001, 9.007328043370961300e-001, 1.839182838430090300e+000, -1.352604803382542600e+000, 1.440339792882617200e+000, 5.409160633286138600e-001, -9.096356667070149000e-002, 2.145906552675194100e-001, 1.749366326171780000e+000, 1.710862586429138200e+000, 5.617170924142114200e-001, 8.075937970441778900e-001, 5.294053117812258500e-001, 8.007328881544743000e-001, 6.824506852180559600e-001, -4.466422007073587200e-001, 4.125165857556476500e-001, 1.264599468598445900e+000, 1.195482116831558800e+000, 5.815701470999368200e-001, 1.480145121963046200e+000, 1.228974130124139900e+000, -9.887375252743877400e-001, 4.957232610676656800e-001, 2.201242074660017000e-001, -8.949779589135298300e-002, 4.463714750361750200e-001, 1.104458211701637000e+000, 1.146057798756675600e+000, 1.607064328082671100e+000, -3.342540671866551800e-001, -3.733869343080511400e-001, 1.376984209826379600e+000, 1.134842638638303900e+000, 1.578816025652644900e+000, 8.631161307174450800e-003, 6.628552272325566300e-001, -4.235551988694613600e-001, -5.931434773175525700e-002, 1.107744286910284700e+000, 1.308043758809049000e+000, 1.474220016986390400e+000, 6.094036504382410700e-001, 2.586151051423653000e-001, 7.690092056142631100e-001, -1.580472136196336100e-001, 2.410499789745967300e-001, -4.419329075671284400e-001, 6.725262868347948700e-001, -2.443367984060260100e-001, 9.310955439202097700e-001, 9.240837092450902800e-002, 9.816510048711224500e-001, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -5.000000000000000000e-001, -5.000000000000000000e-001, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000};
+idxint K0jc[558] = {0, 112, 224, 325, 329, 332, 335, 338, 341, 344, 347, 350, 353, 356, 359, 362, 365, 368, 371, 374, 377, 380, 383, 386, 389, 392, 395, 398, 401, 404, 407, 410, 413, 416, 419, 422, 425, 428, 431, 434, 437, 440, 443, 446, 449, 452, 455, 458, 461, 464, 467, 470, 473, 476, 479, 482, 485, 488, 491, 494, 497, 500, 503, 506, 509, 512, 515, 518, 521, 524, 527, 530, 533, 536, 539, 542, 545, 548, 551, 554, 557, 560, 563, 566, 569, 572, 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, 617, 620, 623, 626, 629, 632, 635, 638, 641, 644, 647, 650, 653, 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 692, 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791, 794, 797, 800, 803, 806, 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 848, 851, 854, 857, 860, 863, 866, 869, 872, 875, 878, 881, 884, 887, 890, 893, 896, 899, 902, 905, 908, 911, 914, 917, 920, 923, 926, 929, 946, 949, 952, 977, 980, 983, 1008, 1011, 1014, 1043, 1046, 1049, 1063, 1066, 1069, 1072, 1075, 1078, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1414};
+idxint K0ir[1415] = {0, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 334, 1, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 335, 2, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 3, 333, 336, 337, 4, 223, 338, 5, 224, 339, 6, 225, 340, 7, 226, 341, 8, 227, 342, 9, 228, 343, 10, 229, 344, 11, 230, 345, 12, 231, 346, 13, 232, 347, 14, 233, 348, 15, 234, 349, 16, 235, 350, 17, 236, 351, 18, 237, 352, 19, 238, 353, 20, 239, 354, 21, 240, 355, 22, 241, 356, 23, 242, 357, 24, 243, 358, 25, 244, 359, 26, 245, 360, 27, 246, 361, 28, 247, 362, 29, 248, 363, 30, 249, 364, 31, 250, 365, 32, 251, 366, 33, 252, 367, 34, 253, 368, 35, 254, 369, 36, 255, 370, 37, 256, 371, 38, 257, 372, 39, 258, 373, 40, 259, 374, 41, 260, 375, 42, 261, 376, 43, 262, 377, 44, 263, 378, 45, 264, 379, 46, 265, 380, 47, 266, 381, 48, 267, 382, 49, 268, 383, 50, 269, 384, 51, 270, 385, 52, 271, 386, 53, 272, 387, 54, 273, 388, 55, 274, 389, 56, 275, 390, 57, 276, 391, 58, 277, 392, 59, 278, 393, 60, 279, 394, 61, 280, 395, 62, 281, 396, 63, 282, 397, 64, 283, 398, 65, 284, 399, 66, 285, 400, 67, 286, 401, 68, 287, 402, 69, 288, 403, 70, 289, 404, 71, 290, 405, 72, 291, 406, 73, 292, 407, 74, 293, 408, 75, 294, 409, 76, 295, 410, 77, 296, 411, 78, 297, 412, 79, 298, 413, 80, 299, 414, 81, 300, 415, 82, 301, 416, 83, 302, 417, 84, 303, 418, 85, 304, 419, 86, 305, 420, 87, 306, 421, 88, 307, 422, 89, 308, 423, 90, 309, 424, 91, 310, 425, 92, 311, 426, 93, 312, 427, 94, 313, 428, 95, 314, 429, 96, 315, 430, 97, 316, 431, 98, 317, 432, 99, 318, 433, 100, 319, 434, 101, 320, 435, 102, 321, 436, 103, 322, 437, 104, 223, 438, 105, 224, 439, 106, 225, 440, 107, 226, 441, 108, 227, 442, 109, 228, 443, 110, 229, 444, 111, 230, 445, 112, 231, 446, 113, 232, 447, 114, 233, 448, 115, 234, 449, 116, 235, 450, 117, 236, 451, 118, 237, 452, 119, 238, 453, 120, 239, 454, 121, 240, 455, 122, 241, 456, 123, 242, 457, 124, 243, 458, 125, 244, 459, 126, 245, 460, 127, 246, 461, 128, 247, 462, 129, 248, 463, 130, 249, 464, 131, 250, 465, 132, 251, 466, 133, 252, 467, 134, 253, 468, 135, 254, 469, 136, 255, 470, 137, 256, 471, 138, 257, 472, 139, 258, 473, 140, 259, 474, 141, 260, 475, 142, 261, 476, 143, 262, 477, 144, 263, 478, 145, 264, 479, 146, 265, 480, 147, 266, 481, 148, 267, 482, 149, 268, 483, 150, 269, 484, 151, 270, 485, 152, 271, 486, 153, 272, 487, 154, 273, 488, 155, 274, 489, 156, 275, 490, 157, 276, 491, 158, 277, 492, 159, 278, 493, 160, 279, 494, 161, 280, 495, 162, 281, 496, 163, 282, 497, 164, 283, 498, 165, 284, 499, 166, 285, 500, 167, 286, 501, 168, 287, 502, 169, 288, 503, 170, 289, 504, 171, 290, 505, 172, 291, 506, 173, 292, 507, 174, 293, 508, 175, 294, 509, 176, 295, 510, 177, 296, 511, 178, 297, 512, 179, 298, 513, 180, 299, 514, 181, 300, 515, 182, 301, 516, 183, 302, 517, 184, 303, 518, 185, 304, 519, 186, 305, 520, 187, 306, 521, 188, 307, 522, 189, 308, 523, 190, 309, 524, 191, 310, 525, 192, 311, 526, 193, 312, 527, 194, 313, 528, 195, 314, 529, 196, 315, 530, 197, 316, 531, 198, 317, 532, 199, 318, 533, 200, 319, 534, 201, 320, 535, 202, 321, 536, 203, 322, 537, 204, 226, 232, 238, 250, 276, 277, 280, 289, 290, 294, 297, 310, 315, 319, 321, 538, 205, 323, 539, 206, 324, 540, 207, 225, 231, 235, 242, 252, 253, 257, 260, 262, 265, 266, 267, 270, 273, 274, 279, 282, 293, 296, 302, 305, 308, 317, 541, 208, 325, 542, 209, 326, 543, 210, 223, 227, 230, 236, 237, 239, 240, 244, 246, 251, 254, 256, 259, 261, 283, 287, 301, 304, 311, 313, 314, 318, 322, 544, 211, 327, 545, 212, 328, 546, 213, 224, 229, 233, 243, 245, 249, 255, 258, 264, 269, 271, 272, 275, 278, 281, 288, 291, 292, 298, 299, 300, 303, 306, 307, 309, 316, 320, 547, 214, 329, 548, 215, 330, 549, 216, 228, 234, 241, 247, 248, 263, 268, 284, 285, 286, 295, 312, 550, 217, 331, 551, 218, 332, 552, 219, 333, 553, 220, 334, 554, 221, 335, 555, 222, 336, 556, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556};
+pfloat K0pr[1415] = {9.999999999999999500e-008, -6.748099080141577400e-001, 9.587587238674218900e-001, -3.380262965696901900e-001, -6.289006455522118100e-001, 1.458932368908371500e+000, 8.103505672584934100e-001, -8.308676110497204000e-002, 2.638152658681099300e+000, 1.000625209233638700e+000, 1.443285740856571400e-001, 1.198960671699122800e+000, 8.042866751960948700e-001, -2.146877760548437900e-002, 1.252109754253975600e+000, 1.681372772953815700e+000, 1.160558110039982400e+000, 8.971595941547876300e-001, 9.934462168535226300e-001, 4.030425643552826300e-003, 4.520907269135507900e-001, 1.957531681292445900e+000, 8.367513704018149100e-001, -8.919073879004054700e-001, 1.364968014685880000e-001, -5.391443069926015200e-001, 1.218605709809697200e+000, 1.379628849398701500e+000, 7.705722581573115600e-002, -9.721580354507602900e-001, 1.341091680254979900e+000, 1.416856131617781900e+000, 1.367782802004573000e+000, 9.310015370881947700e-001, 1.025960903569425500e+000, 4.418055920652105800e-001, 1.797608571927105100e-001, -1.566236421056189400e+000, -1.293790728779894400e-001, -2.548793507296202000e-001, -1.327158583802827700e+000, 8.378869252146687900e-001, 9.208088134425553900e-001, 8.954835779157467300e-001, 1.872488747783192400e+000, 1.607749082930002300e-001, 1.703097419135647200e+000, 1.485966470102646500e+000, 1.950727391193988900e+000, 1.261282074772785800e+000, 2.116080672704367100e+000, 4.418819171779880300e-001, -6.070414095655145600e-001, 2.236741804227308500e-001, -1.390565074056968600e+000, -3.689063294445240100e-001, 6.275925564016111600e-001, 9.419119351808997700e-001, 2.051844704916749900e-002, -2.055013180419911200e+000, -8.138411920140069500e-001, -1.670986440999406000e+000, -4.312826132928389000e-001, -1.317178055102502500e-001, 4.129877571668971700e-002, -1.178000809237306800e-001, -5.094809536848188300e-002, 4.887140456297478000e-001, -6.048920026011540600e-001, -1.622657687025348600e+000, 9.468924561461561400e-002, -1.076752006167445400e+000, -4.544402225817885700e-001, -1.138681599263542200e+000, 6.297099350763062400e-001, 7.161553122227841700e-001, -2.326213079050594200e-001, -2.421425730439526200e-001, -3.527400894253913700e-001, -5.991000491511071500e-001, -4.501982881436522000e-001, -1.073527618321097300e+000, -1.837831580649836900e+000, -1.093506922417250900e+000, 3.123080272148109900e-002, 4.764624397863112500e-001, -9.744593174286131400e-001, -5.475935551016516400e-001, -1.185577848308040100e+000, -1.512429413719079500e+000, -8.503358079552569800e-001, -1.048119449917124500e+000, -2.950353712891531400e-001, 4.436355670528358600e-001, -1.976143927829304500e+000, -1.154872945269262400e-001, -8.267783537066453200e-001, -2.524533500828647400e-001, -2.934013148063512300e-001, -9.559308197633347200e-001, -5.099545278978906400e-001, 7.104569782287112300e-001, 2.586151051423653000e-001, 9.670875274511733200e-001, -1.580472136196336100e-001, 4.036019169202506600e-001, -4.419329075671284400e-001, 1.335760493316310000e-001, -2.443367984060260100e-001, 5.346171843774407700e-001, 9.240837092450902800e-002, 1.000000000000000000e+000, 9.999999999999999500e-008, -7.627629774659758300e+000, -8.317906940770274800e+000, -7.063111046330970300e+000, -8.991213209598194900e+000, -7.132056801314573300e+000, -6.933147988332642300e+000, -8.002850393982971200e+000, -7.763929473153173600e+000, -7.316196508551362500e+000, -6.857489440772187800e+000, -6.933435917031895100e+000, -8.453055934420948600e+000, -7.746956878849250200e+000, -6.987480243537588000e+000, -6.898256465718047200e+000, -7.035033952525910900e+000, -7.332300809407010800e+000, -8.868148466875196000e+000, -7.895445920224761800e+000, -8.477688226774738200e+000, -6.724790281248850500e+000, -8.026080227654171400e+000, -8.247796522362861500e+000, -7.893131787368933100e+000, -7.953077643849715300e+000, -7.085517647070380700e+000, -7.757918623860442500e+000, -9.404980440162075800e+000, -9.111021916635516900e+000, -6.753547752596220200e+000, -6.208328120779675900e+000, -7.460712402671073400e+000, -8.051154905293161700e+000, -6.979795864345947000e+000, -7.285373299414776400e+000, -7.935549231771511300e+000, -7.333663096710840700e+000, -7.549354579130950400e+000, -7.125439770244579300e+000, -8.444455837718113100e+000, -7.607705936847165300e+000, -6.947711222611268100e+000, -7.559561213742542300e+000, -6.633232534378238100e+000, -7.285067573640397100e+000, -7.198034090285221800e+000, -8.301173708858458500e+000, -7.740676955875905200e+000, -8.389317110487786200e+000, -7.030503781850090800e+000, 7.483837125022816400e-001, 9.972172897309477000e-001, 8.635272324715717000e-001, 3.437357445286000600e-001, 1.356057545748600200e+000, 7.747994541454063000e-001, -5.029337660688439900e-001, 7.320209587792132500e-001, 9.007328043370961300e-001, 1.839182838430090300e+000, -1.352604803382542600e+000, 1.440339792882617200e+000, 5.409160633286138600e-001, -9.096356667070149000e-002, 2.145906552675194100e-001, 1.749366326171780000e+000, 1.710862586429138200e+000, 5.617170924142114200e-001, 8.075937970441778900e-001, 5.294053117812258500e-001, 8.007328881544743000e-001, 6.824506852180559600e-001, -4.466422007073587200e-001, 4.125165857556476500e-001, 1.264599468598445900e+000, 1.195482116831558800e+000, 5.815701470999368200e-001, 1.480145121963046200e+000, 1.228974130124139900e+000, -9.887375252743877400e-001, 4.957232610676656800e-001, 2.201242074660017000e-001, -8.949779589135298300e-002, 4.463714750361750200e-001, 1.104458211701637000e+000, 1.146057798756675600e+000, 1.607064328082671100e+000, -3.342540671866551800e-001, -3.733869343080511400e-001, 1.376984209826379600e+000, 1.134842638638303900e+000, 1.578816025652644900e+000, 8.631161307174450800e-003, 6.628552272325566300e-001, -4.235551988694613600e-001, -5.931434773175525700e-002, 1.107744286910284700e+000, 1.308043758809049000e+000, 1.474220016986390400e+000, 6.094036504382410700e-001, 2.586151051423653000e-001, 7.690092056142631100e-001, -1.580472136196336100e-001, 2.410499789745967300e-001, -4.419329075671284400e-001, 6.725262868347948700e-001, -2.443367984060260100e-001, 9.310955439202097700e-001, 9.240837092450902800e-002, 9.816510048711224500e-001, 1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -5.000000000000000000e-001, -5.000000000000000000e-001, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000};
+pfloat b[114] = {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, -0.5};
diff --git a/thirdparty/linux/include/coin/data1.h b/thirdparty/linux/include/coin/data1.h new file mode 100644 index 0000000..e648008 --- /dev/null +++ b/thirdparty/linux/include/coin/data1.h @@ -0,0 +1,37 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+idxint n = 223;
+idxint m = 220;
+idxint p = 114;
+idxint l = 201;
+idxint ncones = 6;
+pfloat c[223] = {0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+pfloat h[220] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
+idxint q[6] = {3, 3, 3, 3, 3, 4};
+idxint Gjc[224] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220};
+idxint Gir[220] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219};
+pfloat Gpr[220] = {-1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000};
+idxint Ajc[224] = {0, 111, 222, 322, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 539, 540, 541, 564, 565, 566, 589, 590, 591, 618, 619, 620, 632, 633, 634, 635, 636, 637, 638};
+idxint Air[638] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 111, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 112, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 110, 113, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 3, 9, 15, 27, 53, 54, 57, 66, 67, 71, 74, 87, 92, 96, 98, 100, 101, 2, 8, 12, 19, 29, 30, 34, 37, 39, 42, 43, 44, 47, 50, 51, 56, 59, 70, 73, 79, 82, 85, 94, 102, 103, 0, 4, 7, 13, 14, 16, 17, 21, 23, 28, 31, 33, 36, 38, 60, 64, 78, 81, 88, 90, 91, 95, 99, 104, 105, 1, 6, 10, 20, 22, 26, 32, 35, 41, 46, 48, 49, 52, 55, 58, 65, 68, 69, 75, 76, 77, 80, 83, 84, 86, 93, 97, 106, 107, 5, 11, 18, 24, 25, 40, 45, 61, 62, 63, 72, 89, 108, 109, 110, 111, 112, 113};
+pfloat Apr[638] = {-6.748099080141577400e-001, 9.587587238674218900e-001, -3.380262965696901900e-001, -6.289006455522118100e-001, 1.458932368908371500e+000, 8.103505672584934100e-001, -8.308676110497204000e-002, 2.638152658681099300e+000, 1.000625209233638700e+000, 1.443285740856571400e-001, 1.198960671699122800e+000, 8.042866751960948700e-001, -2.146877760548437900e-002, 1.252109754253975600e+000, 1.681372772953815700e+000, 1.160558110039982400e+000, 8.971595941547876300e-001, 9.934462168535226300e-001, 4.030425643552826300e-003, 4.520907269135507900e-001, 1.957531681292445900e+000, 8.367513704018149100e-001, -8.919073879004054700e-001, 1.364968014685880000e-001, -5.391443069926015200e-001, 1.218605709809697200e+000, 1.379628849398701500e+000, 7.705722581573115600e-002, -9.721580354507602900e-001, 1.341091680254979900e+000, 1.416856131617781900e+000, 1.367782802004573000e+000, 9.310015370881947700e-001, 1.025960903569425500e+000, 4.418055920652105800e-001, 1.797608571927105100e-001, -1.566236421056189400e+000, -1.293790728779894400e-001, -2.548793507296202000e-001, -1.327158583802827700e+000, 8.378869252146687900e-001, 9.208088134425553900e-001, 8.954835779157467300e-001, 1.872488747783192400e+000, 1.607749082930002300e-001, 1.703097419135647200e+000, 1.485966470102646500e+000, 1.950727391193988900e+000, 1.261282074772785800e+000, 2.116080672704367100e+000, 4.418819171779880300e-001, -6.070414095655145600e-001, 2.236741804227308500e-001, -1.390565074056968600e+000, -3.689063294445240100e-001, 6.275925564016111600e-001, 9.419119351808997700e-001, 2.051844704916749900e-002, -2.055013180419911200e+000, -8.138411920140069500e-001, -1.670986440999406000e+000, -4.312826132928389000e-001, -1.317178055102502500e-001, 4.129877571668971700e-002, -1.178000809237306800e-001, -5.094809536848188300e-002, 4.887140456297478000e-001, -6.048920026011540600e-001, -1.622657687025348600e+000, 9.468924561461561400e-002, -1.076752006167445400e+000, -4.544402225817885700e-001, -1.138681599263542200e+000, 6.297099350763062400e-001, 7.161553122227841700e-001, -2.326213079050594200e-001, -2.421425730439526200e-001, -3.527400894253913700e-001, -5.991000491511071500e-001, -4.501982881436522000e-001, -1.073527618321097300e+000, -1.837831580649836900e+000, -1.093506922417250900e+000, 3.123080272148109900e-002, 4.764624397863112500e-001, -9.744593174286131400e-001, -5.475935551016516400e-001, -1.185577848308040100e+000, -1.512429413719079500e+000, -8.503358079552569800e-001, -1.048119449917124500e+000, -2.950353712891531400e-001, 4.436355670528358600e-001, -1.976143927829304500e+000, -1.154872945269262400e-001, -8.267783537066453200e-001, -2.524533500828647400e-001, -2.934013148063512300e-001, -9.559308197633347200e-001, -5.099545278978906400e-001, 7.104569782287112300e-001, 2.586151051423653000e-001, 9.670875274511733200e-001, -1.580472136196336100e-001, 4.036019169202506600e-001, -4.419329075671284400e-001, 1.335760493316310000e-001, -2.443367984060260100e-001, 5.346171843774407700e-001, 9.240837092450902800e-002, 1.000000000000000000e+000, -7.627629774659758300e+000, -8.317906940770274800e+000, -7.063111046330970300e+000, -8.991213209598194900e+000, -7.132056801314573300e+000, -6.933147988332642300e+000, -8.002850393982971200e+000, -7.763929473153173600e+000, -7.316196508551362500e+000, -6.857489440772187800e+000, -6.933435917031895100e+000, -8.453055934420948600e+000, -7.746956878849250200e+000, -6.987480243537588000e+000, -6.898256465718047200e+000, -7.035033952525910900e+000, -7.332300809407010800e+000, -8.868148466875196000e+000, -7.895445920224761800e+000, -8.477688226774738200e+000, -6.724790281248850500e+000, -8.026080227654171400e+000, -8.247796522362861500e+000, -7.893131787368933100e+000, -7.953077643849715300e+000, -7.085517647070380700e+000, -7.757918623860442500e+000, -9.404980440162075800e+000, -9.111021916635516900e+000, -6.753547752596220200e+000, -6.208328120779675900e+000, -7.460712402671073400e+000, -8.051154905293161700e+000, -6.979795864345947000e+000, -7.285373299414776400e+000, -7.935549231771511300e+000, -7.333663096710840700e+000, -7.549354579130950400e+000, -7.125439770244579300e+000, -8.444455837718113100e+000, -7.607705936847165300e+000, -6.947711222611268100e+000, -7.559561213742542300e+000, -6.633232534378238100e+000, -7.285067573640397100e+000, -7.198034090285221800e+000, -8.301173708858458500e+000, -7.740676955875905200e+000, -8.389317110487786200e+000, -7.030503781850090800e+000, 7.483837125022816400e-001, 9.972172897309477000e-001, 8.635272324715717000e-001, 3.437357445286000600e-001, 1.356057545748600200e+000, 7.747994541454063000e-001, -5.029337660688439900e-001, 7.320209587792132500e-001, 9.007328043370961300e-001, 1.839182838430090300e+000, -1.352604803382542600e+000, 1.440339792882617200e+000, 5.409160633286138600e-001, -9.096356667070149000e-002, 2.145906552675194100e-001, 1.749366326171780000e+000, 1.710862586429138200e+000, 5.617170924142114200e-001, 8.075937970441778900e-001, 5.294053117812258500e-001, 8.007328881544743000e-001, 6.824506852180559600e-001, -4.466422007073587200e-001, 4.125165857556476500e-001, 1.264599468598445900e+000, 1.195482116831558800e+000, 5.815701470999368200e-001, 1.480145121963046200e+000, 1.228974130124139900e+000, -9.887375252743877400e-001, 4.957232610676656800e-001, 2.201242074660017000e-001, -8.949779589135298300e-002, 4.463714750361750200e-001, 1.104458211701637000e+000, 1.146057798756675600e+000, 1.607064328082671100e+000, -3.342540671866551800e-001, -3.733869343080511400e-001, 1.376984209826379600e+000, 1.134842638638303900e+000, 1.578816025652644900e+000, 8.631161307174450800e-003, 6.628552272325566300e-001, -4.235551988694613600e-001, -5.931434773175525700e-002, 1.107744286910284700e+000, 1.308043758809049000e+000, 1.474220016986390400e+000, 6.094036504382410700e-001, 2.586151051423653000e-001, 7.690092056142631100e-001, -1.580472136196336100e-001, 2.410499789745967300e-001, -4.419329075671284400e-001, 6.725262868347948700e-001, -2.443367984060260100e-001, 9.310955439202097700e-001, 9.240837092450902800e-002, 9.816510048711224500e-001, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -5.000000000000000000e-001, -5.000000000000000000e-001, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 1.000000000000000000e+000};
+idxint K0jc[558] = {0, 112, 224, 325, 329, 332, 335, 338, 341, 344, 347, 350, 353, 356, 359, 362, 365, 368, 371, 374, 377, 380, 383, 386, 389, 392, 395, 398, 401, 404, 407, 410, 413, 416, 419, 422, 425, 428, 431, 434, 437, 440, 443, 446, 449, 452, 455, 458, 461, 464, 467, 470, 473, 476, 479, 482, 485, 488, 491, 494, 497, 500, 503, 506, 509, 512, 515, 518, 521, 524, 527, 530, 533, 536, 539, 542, 545, 548, 551, 554, 557, 560, 563, 566, 569, 572, 575, 578, 581, 584, 587, 590, 593, 596, 599, 602, 605, 608, 611, 614, 617, 620, 623, 626, 629, 632, 635, 638, 641, 644, 647, 650, 653, 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 692, 695, 698, 701, 704, 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, 737, 740, 743, 746, 749, 752, 755, 758, 761, 764, 767, 770, 773, 776, 779, 782, 785, 788, 791, 794, 797, 800, 803, 806, 809, 812, 815, 818, 821, 824, 827, 830, 833, 836, 839, 842, 845, 848, 851, 854, 857, 860, 863, 866, 869, 872, 875, 878, 881, 884, 887, 890, 893, 896, 899, 902, 905, 908, 911, 914, 917, 920, 923, 926, 929, 946, 949, 952, 977, 980, 983, 1008, 1011, 1014, 1043, 1046, 1049, 1063, 1066, 1069, 1072, 1075, 1078, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1326, 1327, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1357, 1358, 1359, 1360, 1361, 1362, 1363, 1364, 1365, 1366, 1367, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1414};
+idxint K0ir[1415] = {0, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 334, 1, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 335, 2, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 3, 333, 336, 337, 4, 223, 338, 5, 224, 339, 6, 225, 340, 7, 226, 341, 8, 227, 342, 9, 228, 343, 10, 229, 344, 11, 230, 345, 12, 231, 346, 13, 232, 347, 14, 233, 348, 15, 234, 349, 16, 235, 350, 17, 236, 351, 18, 237, 352, 19, 238, 353, 20, 239, 354, 21, 240, 355, 22, 241, 356, 23, 242, 357, 24, 243, 358, 25, 244, 359, 26, 245, 360, 27, 246, 361, 28, 247, 362, 29, 248, 363, 30, 249, 364, 31, 250, 365, 32, 251, 366, 33, 252, 367, 34, 253, 368, 35, 254, 369, 36, 255, 370, 37, 256, 371, 38, 257, 372, 39, 258, 373, 40, 259, 374, 41, 260, 375, 42, 261, 376, 43, 262, 377, 44, 263, 378, 45, 264, 379, 46, 265, 380, 47, 266, 381, 48, 267, 382, 49, 268, 383, 50, 269, 384, 51, 270, 385, 52, 271, 386, 53, 272, 387, 54, 273, 388, 55, 274, 389, 56, 275, 390, 57, 276, 391, 58, 277, 392, 59, 278, 393, 60, 279, 394, 61, 280, 395, 62, 281, 396, 63, 282, 397, 64, 283, 398, 65, 284, 399, 66, 285, 400, 67, 286, 401, 68, 287, 402, 69, 288, 403, 70, 289, 404, 71, 290, 405, 72, 291, 406, 73, 292, 407, 74, 293, 408, 75, 294, 409, 76, 295, 410, 77, 296, 411, 78, 297, 412, 79, 298, 413, 80, 299, 414, 81, 300, 415, 82, 301, 416, 83, 302, 417, 84, 303, 418, 85, 304, 419, 86, 305, 420, 87, 306, 421, 88, 307, 422, 89, 308, 423, 90, 309, 424, 91, 310, 425, 92, 311, 426, 93, 312, 427, 94, 313, 428, 95, 314, 429, 96, 315, 430, 97, 316, 431, 98, 317, 432, 99, 318, 433, 100, 319, 434, 101, 320, 435, 102, 321, 436, 103, 322, 437, 104, 223, 438, 105, 224, 439, 106, 225, 440, 107, 226, 441, 108, 227, 442, 109, 228, 443, 110, 229, 444, 111, 230, 445, 112, 231, 446, 113, 232, 447, 114, 233, 448, 115, 234, 449, 116, 235, 450, 117, 236, 451, 118, 237, 452, 119, 238, 453, 120, 239, 454, 121, 240, 455, 122, 241, 456, 123, 242, 457, 124, 243, 458, 125, 244, 459, 126, 245, 460, 127, 246, 461, 128, 247, 462, 129, 248, 463, 130, 249, 464, 131, 250, 465, 132, 251, 466, 133, 252, 467, 134, 253, 468, 135, 254, 469, 136, 255, 470, 137, 256, 471, 138, 257, 472, 139, 258, 473, 140, 259, 474, 141, 260, 475, 142, 261, 476, 143, 262, 477, 144, 263, 478, 145, 264, 479, 146, 265, 480, 147, 266, 481, 148, 267, 482, 149, 268, 483, 150, 269, 484, 151, 270, 485, 152, 271, 486, 153, 272, 487, 154, 273, 488, 155, 274, 489, 156, 275, 490, 157, 276, 491, 158, 277, 492, 159, 278, 493, 160, 279, 494, 161, 280, 495, 162, 281, 496, 163, 282, 497, 164, 283, 498, 165, 284, 499, 166, 285, 500, 167, 286, 501, 168, 287, 502, 169, 288, 503, 170, 289, 504, 171, 290, 505, 172, 291, 506, 173, 292, 507, 174, 293, 508, 175, 294, 509, 176, 295, 510, 177, 296, 511, 178, 297, 512, 179, 298, 513, 180, 299, 514, 181, 300, 515, 182, 301, 516, 183, 302, 517, 184, 303, 518, 185, 304, 519, 186, 305, 520, 187, 306, 521, 188, 307, 522, 189, 308, 523, 190, 309, 524, 191, 310, 525, 192, 311, 526, 193, 312, 527, 194, 313, 528, 195, 314, 529, 196, 315, 530, 197, 316, 531, 198, 317, 532, 199, 318, 533, 200, 319, 534, 201, 320, 535, 202, 321, 536, 203, 322, 537, 204, 226, 232, 238, 250, 276, 277, 280, 289, 290, 294, 297, 310, 315, 319, 321, 538, 205, 323, 539, 206, 324, 540, 207, 225, 231, 235, 242, 252, 253, 257, 260, 262, 265, 266, 267, 270, 273, 274, 279, 282, 293, 296, 302, 305, 308, 317, 541, 208, 325, 542, 209, 326, 543, 210, 223, 227, 230, 236, 237, 239, 240, 244, 246, 251, 254, 256, 259, 261, 283, 287, 301, 304, 311, 313, 314, 318, 322, 544, 211, 327, 545, 212, 328, 546, 213, 224, 229, 233, 243, 245, 249, 255, 258, 264, 269, 271, 272, 275, 278, 281, 288, 291, 292, 298, 299, 300, 303, 306, 307, 309, 316, 320, 547, 214, 329, 548, 215, 330, 549, 216, 228, 234, 241, 247, 248, 263, 268, 284, 285, 286, 295, 312, 550, 217, 331, 551, 218, 332, 552, 219, 333, 553, 220, 334, 554, 221, 335, 555, 222, 336, 556, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556};
+pfloat K0pr[1415] = {9.999999999999999500e-008, -6.748099080141577400e-001, 9.587587238674218900e-001, -3.380262965696901900e-001, -6.289006455522118100e-001, 1.458932368908371500e+000, 8.103505672584934100e-001, -8.308676110497204000e-002, 2.638152658681099300e+000, 1.000625209233638700e+000, 1.443285740856571400e-001, 1.198960671699122800e+000, 8.042866751960948700e-001, -2.146877760548437900e-002, 1.252109754253975600e+000, 1.681372772953815700e+000, 1.160558110039982400e+000, 8.971595941547876300e-001, 9.934462168535226300e-001, 4.030425643552826300e-003, 4.520907269135507900e-001, 1.957531681292445900e+000, 8.367513704018149100e-001, -8.919073879004054700e-001, 1.364968014685880000e-001, -5.391443069926015200e-001, 1.218605709809697200e+000, 1.379628849398701500e+000, 7.705722581573115600e-002, -9.721580354507602900e-001, 1.341091680254979900e+000, 1.416856131617781900e+000, 1.367782802004573000e+000, 9.310015370881947700e-001, 1.025960903569425500e+000, 4.418055920652105800e-001, 1.797608571927105100e-001, -1.566236421056189400e+000, -1.293790728779894400e-001, -2.548793507296202000e-001, -1.327158583802827700e+000, 8.378869252146687900e-001, 9.208088134425553900e-001, 8.954835779157467300e-001, 1.872488747783192400e+000, 1.607749082930002300e-001, 1.703097419135647200e+000, 1.485966470102646500e+000, 1.950727391193988900e+000, 1.261282074772785800e+000, 2.116080672704367100e+000, 4.418819171779880300e-001, -6.070414095655145600e-001, 2.236741804227308500e-001, -1.390565074056968600e+000, -3.689063294445240100e-001, 6.275925564016111600e-001, 9.419119351808997700e-001, 2.051844704916749900e-002, -2.055013180419911200e+000, -8.138411920140069500e-001, -1.670986440999406000e+000, -4.312826132928389000e-001, -1.317178055102502500e-001, 4.129877571668971700e-002, -1.178000809237306800e-001, -5.094809536848188300e-002, 4.887140456297478000e-001, -6.048920026011540600e-001, -1.622657687025348600e+000, 9.468924561461561400e-002, -1.076752006167445400e+000, -4.544402225817885700e-001, -1.138681599263542200e+000, 6.297099350763062400e-001, 7.161553122227841700e-001, -2.326213079050594200e-001, -2.421425730439526200e-001, -3.527400894253913700e-001, -5.991000491511071500e-001, -4.501982881436522000e-001, -1.073527618321097300e+000, -1.837831580649836900e+000, -1.093506922417250900e+000, 3.123080272148109900e-002, 4.764624397863112500e-001, -9.744593174286131400e-001, -5.475935551016516400e-001, -1.185577848308040100e+000, -1.512429413719079500e+000, -8.503358079552569800e-001, -1.048119449917124500e+000, -2.950353712891531400e-001, 4.436355670528358600e-001, -1.976143927829304500e+000, -1.154872945269262400e-001, -8.267783537066453200e-001, -2.524533500828647400e-001, -2.934013148063512300e-001, -9.559308197633347200e-001, -5.099545278978906400e-001, 7.104569782287112300e-001, 2.586151051423653000e-001, 9.670875274511733200e-001, -1.580472136196336100e-001, 4.036019169202506600e-001, -4.419329075671284400e-001, 1.335760493316310000e-001, -2.443367984060260100e-001, 5.346171843774407700e-001, 9.240837092450902800e-002, 1.000000000000000000e+000, 9.999999999999999500e-008, -7.627629774659758300e+000, -8.317906940770274800e+000, -7.063111046330970300e+000, -8.991213209598194900e+000, -7.132056801314573300e+000, -6.933147988332642300e+000, -8.002850393982971200e+000, -7.763929473153173600e+000, -7.316196508551362500e+000, -6.857489440772187800e+000, -6.933435917031895100e+000, -8.453055934420948600e+000, -7.746956878849250200e+000, -6.987480243537588000e+000, -6.898256465718047200e+000, -7.035033952525910900e+000, -7.332300809407010800e+000, -8.868148466875196000e+000, -7.895445920224761800e+000, -8.477688226774738200e+000, -6.724790281248850500e+000, -8.026080227654171400e+000, -8.247796522362861500e+000, -7.893131787368933100e+000, -7.953077643849715300e+000, -7.085517647070380700e+000, -7.757918623860442500e+000, -9.404980440162075800e+000, -9.111021916635516900e+000, -6.753547752596220200e+000, -6.208328120779675900e+000, -7.460712402671073400e+000, -8.051154905293161700e+000, -6.979795864345947000e+000, -7.285373299414776400e+000, -7.935549231771511300e+000, -7.333663096710840700e+000, -7.549354579130950400e+000, -7.125439770244579300e+000, -8.444455837718113100e+000, -7.607705936847165300e+000, -6.947711222611268100e+000, -7.559561213742542300e+000, -6.633232534378238100e+000, -7.285067573640397100e+000, -7.198034090285221800e+000, -8.301173708858458500e+000, -7.740676955875905200e+000, -8.389317110487786200e+000, -7.030503781850090800e+000, 7.483837125022816400e-001, 9.972172897309477000e-001, 8.635272324715717000e-001, 3.437357445286000600e-001, 1.356057545748600200e+000, 7.747994541454063000e-001, -5.029337660688439900e-001, 7.320209587792132500e-001, 9.007328043370961300e-001, 1.839182838430090300e+000, -1.352604803382542600e+000, 1.440339792882617200e+000, 5.409160633286138600e-001, -9.096356667070149000e-002, 2.145906552675194100e-001, 1.749366326171780000e+000, 1.710862586429138200e+000, 5.617170924142114200e-001, 8.075937970441778900e-001, 5.294053117812258500e-001, 8.007328881544743000e-001, 6.824506852180559600e-001, -4.466422007073587200e-001, 4.125165857556476500e-001, 1.264599468598445900e+000, 1.195482116831558800e+000, 5.815701470999368200e-001, 1.480145121963046200e+000, 1.228974130124139900e+000, -9.887375252743877400e-001, 4.957232610676656800e-001, 2.201242074660017000e-001, -8.949779589135298300e-002, 4.463714750361750200e-001, 1.104458211701637000e+000, 1.146057798756675600e+000, 1.607064328082671100e+000, -3.342540671866551800e-001, -3.733869343080511400e-001, 1.376984209826379600e+000, 1.134842638638303900e+000, 1.578816025652644900e+000, 8.631161307174450800e-003, 6.628552272325566300e-001, -4.235551988694613600e-001, -5.931434773175525700e-002, 1.107744286910284700e+000, 1.308043758809049000e+000, 1.474220016986390400e+000, 6.094036504382410700e-001, 2.586151051423653000e-001, 7.690092056142631100e-001, -1.580472136196336100e-001, 2.410499789745967300e-001, -4.419329075671284400e-001, 6.725262868347948700e-001, -2.443367984060260100e-001, 9.310955439202097700e-001, 9.240837092450902800e-002, 9.816510048711224500e-001, 1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -5.000000000000000000e-001, -5.000000000000000000e-001, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, 9.999999999999999500e-008, 1.000000000000000000e+000, -1.000000000000000000e+000, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -9.999999999999999500e-008, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000, -1.000000000000000000e+000};
+pfloat b[114] = {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, -0.5};
diff --git a/thirdparty/linux/include/coin/ecos.h b/thirdparty/linux/include/coin/ecos.h new file mode 100644 index 0000000..49d2b25 --- /dev/null +++ b/thirdparty/linux/include/coin/ecos.h @@ -0,0 +1,323 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#ifndef __ECOS_H__ +#define __ECOS_H__ + +#include "glblopts.h" +#include "spla.h" +#include "cone.h" +#include "kkt.h" + +#if PROFILING > 0 +#include "timer.h" +#endif + +#if CTRLC > 0 +#include "ctrlc.h" +#endif + +/* ECOS VERSION NUMBER - FORMAT: X.Y.Z --------------------------------- */ +#define ECOS_VERSION ("2.0.4") + +/* DEFAULT SOLVER PARAMETERS AND SETTINGS STRUCT ----------------------- */ +#define MAXIT (100) /* maximum number of iterations */ +#define FEASTOL (1E-8) /* primal/dual infeasibility tolerance */ +#define ABSTOL (1E-8) /* absolute tolerance on duality gap */ +#define RELTOL (1E-8) /* relative tolerance on duality gap */ +#define FTOL_INACC (1E-4) /* inaccurate solution feasibility tol. */ +#define ATOL_INACC (5E-5) /* inaccurate solution absolute tol. */ +#define RTOL_INACC (5E-5) /* inaccurate solution relative tol. */ +#define GAMMA (0.99) /* scaling the final step length */ +#define STATICREG (1) /* static regularization: 0:off, 1:on */ +#define DELTASTAT (7E-8) /* regularization parameter */ +#define DELTA (2E-7) /* dyn. regularization parameter */ +#define EPS (1E-13) /* dyn. regularization threshold (do not 0!) */ +#define VERBOSE (1) /* bool for verbosity; PRINTLEVEL < 3 */ +#define NITREF (9) /* number of iterative refinement steps */ +#define IRERRFACT (6) /* factor by which IR should reduce err */ +#define LINSYSACC (1E-14) /* rel. accuracy of search direction */ +#define SIGMAMIN (1E-4) /* always do some centering */ +#define SIGMAMAX (1.0) /* never fully center */ +#define STEPMIN (1E-6) /* smallest step that we do take */ +#define STEPMAX (0.999) /* largest step allowed, also in affine dir. */ +#define SAFEGUARD (500) /* Maximum increase in PRES before + ECOS_NUMERICS is thrown. */ +/*Ecos exponential cone default settings*/ +#ifdef EXPCONE +#define MAX_BK (90) /*Maximum backtracking steps*/ +#define BK_SCALE (0.8) /*Backtracking constant*/ +#define MIN_DISTANCE (0.1) /* dont let sqrt(r), sqrt(-u) or sqrt(v) + become smaller than + MIN_DISTANCE*mu*/ +#define CENTRALITY (1) /*Centrality requirement*/ +#endif + + + +/* EQUILIBRATION METHOD ------------------------------------------------ */ +#define EQUILIBRATE (1) /* use equlibration of data matrices? >0: yes */ +#define EQUIL_ITERS (3) /* number of equilibration iterations */ +#define RUIZ_EQUIL /* define algorithm to use - if both are ... */ +/*#define ALTERNATING_EQUIL*/ /* ... commented out no equlibration is used */ + + +/* EXITCODES ----------------------------------------------------------- */ +#define ECOS_OPTIMAL (0) /* Problem solved to optimality */ +#define ECOS_PINF (1) /* Found certificate of primal infeasibility */ +#define ECOS_DINF (2) /* Found certificate of dual infeasibility */ +#define ECOS_INACC_OFFSET (10) /* Offset exitflag at inaccurate results */ +#define ECOS_MAXIT (-1) /* Maximum number of iterations reached */ +#define ECOS_NUMERICS (-2) /* Search direction unreliable */ +#define ECOS_OUTCONE (-3) /* s or z got outside the cone, numerics? */ +#define ECOS_SIGINT (-4) /* solver interrupted by a signal/ctrl-c */ +#define ECOS_FATAL (-7) /* Unknown problem in solver */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* SETTINGS STRUCT ----------------------------------------------------- */ +typedef struct settings{ + pfloat gamma; /* scaling the final step length */ + pfloat delta; /* regularization parameter */ + pfloat eps; /* regularization threshold */ + pfloat feastol; /* primal/dual infeasibility tolerance */ + pfloat abstol; /* absolute tolerance on duality gap */ + pfloat reltol; /* relative tolerance on duality gap */ + pfloat feastol_inacc; /* primal/dual infeasibility relaxed tolerance */ + pfloat abstol_inacc; /* absolute relaxed tolerance on duality gap */ + pfloat reltol_inacc; /* relative relaxed tolerance on duality gap */ + idxint nitref; /* number of iterative refinement steps */ + idxint maxit; /* maximum number of iterations */ + idxint verbose; /* verbosity bool for PRINTLEVEL < 3 */ +#ifdef EXPCONE /*Exponential cone settings*/ + idxint max_bk_iter; /* Maximum backtracking iterations */ + pfloat bk_scale; /* Backtracking scaling */ + pfloat centrality; /* Centrality bound, ignored when centrality vars = 0*/ +#endif +} settings; + + +/* INFO STRUCT --------------------------------------------------------- */ +typedef struct stats{ + pfloat pcost; + pfloat dcost; + pfloat pres; + pfloat dres; + pfloat pinf; + pfloat dinf; + pfloat pinfres; + pfloat dinfres; + pfloat gap; + pfloat relgap; + pfloat sigma; + pfloat mu; + pfloat step; + pfloat step_aff; + pfloat kapovert; + idxint iter; + idxint nitref1; + idxint nitref2; + idxint nitref3; +#if PROFILING > 0 + pfloat tsetup; + pfloat tsolve; +#endif +#if PROFILING > 1 + pfloat tfactor; + pfloat tkktsolve; + pfloat torder; + pfloat tkktcreate; + pfloat ttranspose; + pfloat tperm; + pfloat tfactor_t1; + pfloat tfactor_t2; +#endif +#ifdef EXPCONE + /* Counters for backtracking, each of these counts + * one condition that can fail and cause a backtrack + */ + idxint pob; /* Potential decreases */ + idxint cb; /* Centrality violations */ + idxint cob; /* The s'z of one cone is too small w.r.t. mu */ + idxint pb; /* Primal infeasibility */ + idxint db; /* Dual infeasibility */ + idxint affBack; /* Total affine backtracking steps */ + idxint cmbBack; /* Total combined backtracking steps */ + + pfloat centrality; /*Centrality at the end of the backtracking*/ +#endif + +} stats; + + +/* ALL DATA NEEDED BY SOLVER ------------------------------------------- */ +typedef struct pwork{ + /* dimensions */ + idxint n; /* number of primal variables x */ + idxint m; /* number of conically constrained variables s */ + idxint p; /* number of equality constraints */ + idxint D; /* degree of the cone */ + + /* variables */ + pfloat* x; /* primal variables */ + pfloat* y; /* multipliers for equality constaints */ + pfloat* z; /* multipliers for conic inequalities */ + pfloat* s; /* slacks for conic inequalities */ + pfloat* lambda; /* scaled variable */ + pfloat kap; /* kappa (homogeneous embedding) */ + pfloat tau; /* tau (homogeneous embedding) */ + + /* best iterate seen so far */ + /* variables */ + pfloat* best_x; /* primal variables */ + pfloat* best_y; /* multipliers for equality constaints */ + pfloat* best_z; /* multipliers for conic inequalities */ + pfloat* best_s; /* slacks for conic inequalities */ + pfloat best_kap; /* kappa (homogeneous embedding) */ + pfloat best_tau; /* tau (homogeneous embedding) */ + pfloat best_cx; + pfloat best_by; + pfloat best_hz; + stats* best_info; /* info of best iterate */ + + /* temporary stuff holding search direction etc. */ + pfloat* dsaff; + pfloat* dzaff; + pfloat* W_times_dzaff; + pfloat* dsaff_by_W; + pfloat* saff; + pfloat* zaff; + + /* cone */ + cone* C; + + /* problem data */ + spmat* A; spmat* G; pfloat* c; pfloat* b; pfloat* h; + + /* indices that map entries of A and G to the KKT matrix */ + idxint *AtoK; idxint *GtoK; + +#if defined EQUILIBRATE && EQUILIBRATE > 0 + /* equilibration vector */ + pfloat *xequil; + pfloat *Aequil; + pfloat *Gequil; +#endif + + /* scalings of problem data */ + pfloat resx0; pfloat resy0; pfloat resz0; + + /* residuals */ + pfloat *rx; pfloat *ry; pfloat *rz; pfloat rt; + pfloat hresx; pfloat hresy; pfloat hresz; + + /* norm iterates */ + pfloat nx,ny,nz,ns; + + /* temporary storage */ + pfloat cx; pfloat by; pfloat hz; pfloat sz; + + /* KKT System */ + kkt* KKT; + + /* info struct */ + stats* info; + + /* settings struct */ + settings* stgs; + +} pwork; + + +/* SOME USEFUL MACROS -------------------------------------------------- */ +#define MAX(X,Y) ((X) < (Y) ? (Y) : (X)) /* maximum of 2 expressions */ +/* safe division x/y where y is assumed to be positive! */ +#define SAFEDIV_POS(X,Y) ( (Y) < EPS ? ((X)/EPS) : (X)/(Y) ) + + +/* METHODS */ + +/* set up work space */ +/* could be done by codegen */ +pwork* ECOS_setup(idxint n, idxint m, idxint p, idxint l, idxint ncones, idxint* q, idxint nex, + pfloat* Gpr, idxint* Gjc, idxint* Gir, + pfloat* Apr, idxint* Ajc, idxint* Air, + pfloat* c, pfloat* h, pfloat* b); + + +#ifdef EXPCONE +pfloat expConeLineSearch(pwork* w, pfloat dtau, pfloat dkappa, idxint affine); +#endif + +/* solve */ +idxint ECOS_solve(pwork* w); + +/** + * Cleanup: free memory (not used for embedded solvers, only standalone) + * + * Use the second argument to give the number of variables to NOT free. + * This is useful if you want to use the result of the optimization without + * copying over the arrays. One use case is the MEX interface, where we + * do not want to free x,y,s,z (depending on the number of LHS). + */ +void ECOS_cleanup(pwork* w, idxint keepvars); + + +/** + * Version: returns the current version number + * Use a character array of length 7 to obtain the version number + * in the format + * x.y.zzz + * where x is the major, y the minor and zzz the build number + */ +const char* ECOS_ver(void); + + +/* ------------------- EXPERT LEVEL INTERFACES ---------------------- */ + +/* + * Updates one element of the RHS vector h of inequalities + * After the call, w->h[idx] = value (but equilibrated) + */ +void ecos_updateDataEntry_h(pwork* w, idxint idx, pfloat value); + +/* + * Updates one element of the OBJ vector c of inequalities + * After the call, w->c[idx] = value (but equilibrated) + */ +void ecos_updateDataEntry_c(pwork* w, idxint idx, pfloat value); + +/* + * Updates numerical data for G, A, c, h, and b, + * and re-equilibrates. + * Then updates the corresponding KKT entries. + */ +void ECOS_updateData(pwork *w, pfloat *Gpr, pfloat *Apr, + pfloat* c, pfloat* h, pfloat* b); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/thirdparty/linux/include/coin/ecos_bb.h b/thirdparty/linux/include/coin/ecos_bb.h new file mode 100644 index 0000000..aec8743 --- /dev/null +++ b/thirdparty/linux/include/coin/ecos_bb.h @@ -0,0 +1,204 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +/* + * The branch and bound module is (c) Han Wang, Stanford University, + * [hanwang2@stanford.edu] + */ + +#ifndef __ecos_bb_H__ +#define __ecos_bb_H__ + +#include "ecos.h" +#include "spla.h" +#include "glblopts.h" + +/* Print verbosity */ +#define MI_PRINTLEVEL (1) + +/* ecos_bb configuration settings */ +#define MI_ABS_EPS (1E-6) +#define MI_REL_EPS (1E-3) +#define MI_MAXITER (1000) +#define MI_INT_TOL (FTOL_INACC) + +/* Flags */ +#define MI_SOLVED_NON_BRANCHABLE (3) +#define MI_SOLVED_BRANCHABLE (2) +#define MI_NOT_SOLVED (1) +#define MI_FREE (0) + +#define MI_ONE (1) +#define MI_ZERO (0) +#define MI_STAR (-1) + +/*** Exit flags ***/ +/*ECOS_BB found optimal solution*/ +#define MI_OPTIMAL_SOLN (ECOS_OPTIMAL) +/*ECOS_BB proved problem is infeasible*/ +#define MI_INFEASIBLE (ECOS_PINF) +/*ECOS_BB proved problem is unbounded*/ +#define MI_UNBOUNDED (ECOS_DINF) +/*ECOS_BB hit maximum iterations but a feasible solution was found and the best seen feasible solution was returned*/ +#define MI_MAXITER_FEASIBLE_SOLN (ECOS_OPTIMAL + ECOS_INACC_OFFSET) +/*ECOS_BB hit maximum iterations without finding a feasible solution*/ +#define MI_MAXITER_NO_SOLN (ECOS_PINF + ECOS_INACC_OFFSET) +/*ECOS_BB hit maximum iterations without finding a feasible solution that was unbounded*/ +#define MI_MAXITER_UNBOUNDED (ECOS_DINF + ECOS_INACC_OFFSET) + +/* Max integer and all smaller integer representable by single precision */ +#define MAX_FLOAT_INT (8388608) + +/* define INFINITY and isinf for MSFT */ +#ifdef _MSC_VER +#include "float.h" +#define INFINITY (DBL_MAX+DBL_MAX) +/* this will also return true if x is nan, but we don't check that anyway */ +#define isinf(x) (!_finite(x)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct settings_bb{ + idxint maxit; /* maximum number of iterations */ + idxint verbose; /* verbosity bool for PRINTLEVEL < 3 */ + pfloat abs_tol_gap; /* termination criteria |U-L| */ + pfloat rel_tol_gap; /* termination criteria for |U-L|/|L| < 3 */ + pfloat integer_tol; /* integer rounding tolerance */ +} settings_bb; + +typedef struct node { + char status; + pfloat L; + pfloat U; + idxint split_idx; + pfloat split_val; +} node; + +/* Wrapper for mixed integer module */ +typedef struct ecos_bb_pwork{ + /* Mixed integer data */ + idxint num_bool_vars; + idxint num_int_vars; + + node* nodes; + char* bool_node_ids; + pfloat* int_node_ids; + + idxint* bool_vars_idx; + idxint* int_vars_idx; + + /* ECOS data */ + pwork* ecos_prob; + + /* Modified pointers to ecos internals */ + /* Use these to edit or reset the h variables */ + spmat* A; + spmat* G; + pfloat* c; + pfloat* b; + pfloat* h; + + /* best iterate seen so far */ + /* variables */ + pfloat* x; /* primal variables */ + pfloat* y; /* multipliers for equality constaints */ + pfloat* z; /* multipliers for conic inequalities */ + pfloat* s; /* slacks for conic inequalities */ + pfloat kap; /* kappa (homogeneous embedding) */ + pfloat tau; /* tau (homogeneous embedding) */ + stats* info; /* info of best iterate */ + pfloat global_U; + pfloat global_L; + + /* Tmp data */ + char* tmp_bool_node_id; + pfloat* tmp_int_node_id; + idxint iter; + + /* Stored pointers to prevent memory leaks */ + pfloat* Gpr_new; + idxint* Gjc_new; + idxint* Gir_new; + pfloat* h_new; + + /* settings struct */ + settings* ecos_stgs; + settings_bb* stgs; + idxint default_settings; + +} ecos_bb_pwork; + +ecos_bb_pwork* ECOS_BB_setup( + idxint n, idxint m, idxint p, + idxint l, idxint ncones, idxint* q, idxint nex, + pfloat* Gpr, idxint* Gjc, idxint* Gir, + pfloat* Apr, idxint* Ajc, idxint* Air, + pfloat* c, pfloat* h, pfloat* b, + idxint num_bool_vars, idxint* bool_vars_idx, + idxint num_int_vars, idxint* int_vars_idx, + settings_bb* stgs); + +idxint ECOS_BB_solve(ecos_bb_pwork* prob); + +void ECOS_BB_cleanup(ecos_bb_pwork* prob, idxint num_vars_keep); + +void updateDataEntry_h(ecos_bb_pwork* w, idxint idx, pfloat value); + +void updateDataEntry_c(ecos_bb_pwork* w, idxint idx, pfloat value); + +settings_bb* get_default_ECOS_BB_settings(); + +/* Calculate the offset into the node_id array */ +static inline char* get_bool_node_id(idxint idx, ecos_bb_pwork* prob){ + return &prob->bool_node_ids[prob->num_bool_vars * idx]; +} + +static inline pfloat* get_int_node_id(idxint idx, ecos_bb_pwork* prob){ + return &prob->int_node_ids[prob->num_int_vars * idx * 2]; +} + +static inline pfloat abs_2(pfloat number){ + return number < 0.0 ? -number : number; +} + +static inline pfloat pfloat_round(pfloat number){ + return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5); +} + +static inline pfloat pfloat_ceil(pfloat number, pfloat integer_tol){ + return (pfloat) (number < 0 ? (int) number : (int) (number+(1-integer_tol)) ); +} + +static inline pfloat pfloat_floor(pfloat number, pfloat integer_tol){ + return (pfloat) (number < 0 ? (int) (number-(1-integer_tol)) : (int) number); +} + +static inline idxint float_eqls(pfloat a, pfloat b, pfloat integer_tol){ + return abs_2(a - b) < integer_tol; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/thirdparty/linux/include/coin/equil.h b/thirdparty/linux/include/coin/equil.h new file mode 100644 index 0000000..d758f8b --- /dev/null +++ b/thirdparty/linux/include/coin/equil.h @@ -0,0 +1,50 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Equilibration module (c) Eric Chu, March 2014 */ + +/** + * used predominantly in preproc.c + */ + +#include "ecos.h" + +#if defined EQUILIBRATE && EQUILIBRATE > 0 + +#ifndef __EQUIL_H__ +#define __EQUIL_H__ + +#include "glblopts.h" +#include "ecos.h" + +/** + * set_equilibration: This routine takes the workspace and sets + * the equilibration vectors. + */ +void set_equilibration(pwork *w); + +/** + * unset_equilibration: This routine takes the workspace and + * undoes the equilibration. + */ +void unset_equilibration(pwork *w); + + +#endif +#endif diff --git a/thirdparty/linux/include/coin/expcone.h b/thirdparty/linux/include/coin/expcone.h new file mode 100644 index 0000000..4c5fa81 --- /dev/null +++ b/thirdparty/linux/include/coin/expcone.h @@ -0,0 +1,87 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * The exponental cone module is (c) Santiago Akle, Stanford University, + * [akle@stanford.edu] + * + */ + +#include "cone.h" +#include "glblopts.h" +#include "wright_omega.h" +#include <math.h> +#ifndef __ECOS_EXP_H__ +#define __ECOS_EXP_H__ + +#if defined EXPCONE +/* + * Exponential cone structure: We save the index where each expcone Hessian + * column starts in the csr format. For each cone we also allocate space for + * the gradient of the barrier at each cone and the values of entries of the + * Hessian matrix + */ +typedef struct expcone +{ + idxint colstart[3]; /* All cones are fixed size, we store the index + * where the column of the hessian starts in the + * permuted Newton system. + */ + pfloat v[6]; /* Uper triangular section of the hessian */ + pfloat g[3]; /* Gradient of the barrier */ +} expcone; + +/* + * Evaluates the Hessian of the exponential dual cone barrier at the triplet + * w[0],w[1],w[2], and stores the upper triangular part of the matrix mu*H(w) + * at v[0],...,v[5]. The entries of the Hessian are arranged columnwise into v + */ +void evalExpHessian(pfloat* w, pfloat* v, pfloat mu); + +/* + * Evaluates the gradient of the dual exponential cone barrier g^\star(z) at the triplet + * w[0],w[1],w[2], and stores the result at g[0],..,g[2]. + */ +void evalExpGradient(pfloat* w, pfloat* g); + +/* + * Computes f_e(s_e) + f^\star_e(z_e) + */ +pfloat evalBarrierValue(pfloat* siter, pfloat *ziter, idxint fc, idxint nexc); + +/* + * Multiplies by y+=muH*x + */ +void scaleToAddExpcone(pfloat* y, pfloat* x, expcone* expcones, idxint nexc, idxint fc); + +/* + * Returns 1 if s is primal feasible w.r.t the primal exponential + * cone and 0 i.o.c + */ +idxint evalExpPrimalFeas(pfloat *s, idxint nexc); + +/* + * Returns 1 if s is dual feasible w.r.t the dual exponential + * cone and 0 i.o.c + */ +idxint evalExpDualFeas(pfloat *s, idxint nexc); + +#endif +#endif /* End ifndef __ECOS_EXP_H__ */ + diff --git a/thirdparty/linux/include/coin/glblopts.h b/thirdparty/linux/include/coin/glblopts.h new file mode 100644 index 0000000..824570a --- /dev/null +++ b/thirdparty/linux/include/coin/glblopts.h @@ -0,0 +1,105 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* data type definitions used with ECOS */
+
+#ifndef __GLBLOPTS_H__
+#define __GLBLOPTS_H__
+
+/* DATA TYPES ---------------------------------------------------------- */
+typedef double pfloat; /* for numerical values */
+
+/* SET PRINT LEVEL ----------------------------------------------------- */
+#define PRINTLEVEL (2) /* 0: no prints */
+ /* 1: only final info */
+ /* 2: progress print per iteration */
+ /* 3: debug level, enables print & dump fcns. */
+
+#define MATLAB_FLUSH_PRINTS
+ /* print each iteration directly to Matlab. */
+ /* this options considerably slows down the */
+ /* solver, but is useful if you solve big */
+ /* problems. */
+
+/* SET PROFILING LEVEL ------------------------------------------------- */
+#define PROFILING (1) /* 0: no timing information */
+ /* 1: runtime (divided in setup and solve) */
+ /* 2: detailed profiling */
+
+/* SET DEBUG LEVEL ----------------------------------------------------- */
+#define DEBUG (0) /* 0: no debugging information */
+ /* 1: debug info & dump intermediate results */
+ /* (flag used only for development) */
+
+/* NAN ----------------------------------------------------------------- */
+#ifndef NAN
+#define NAN ((double)0x7ff8000000000000)
+#endif
+
+/* INF ---------------------------------------------------------------- */
+#ifndef INFINITY
+#define INFINITY ((double)0x7ff0000000000000)
+#endif
+
+/* Exponential cone */
+#define EXPCONE /*When defined the exponential cone solver code is enabled*/
+
+/* SYSTEM INCLUDES FOR PRINTING ---------------------------------------- */
+#if PRINTLEVEL > 0
+#ifdef MATLAB_MEX_FILE
+#include "mex.h"
+#define PRINTTEXT mexPrintf
+#elif defined PYTHON
+#include <Python.h>
+#define PRINTTEXT PySys_WriteStdout
+#else
+#define PRINTTEXT printf
+#endif
+#include <stdio.h>
+#else
+#define PRINTTEXT(...)
+#endif
+
+#include "SuiteSparse_config.h"
+
+/* use this if pfloat is float: */
+/* #define NAN ((float)0x7fc00000) */
+
+/* USE SAME NUMBER REPRESENTATION FOR INDEXING AS AMD AND LDL ---------- */
+typedef SuiteSparse_long idxint;
+
+/* SYSTEM INCLUDE IF COMPILING FOR MATLAB ------------------------------ */
+#ifdef MATLAB_MEX_FILE
+#include "mex.h"
+#endif
+
+/* CHOOSE RIGHT MEMORY MANAGER ----------------------------------------- */
+#ifdef MATLAB_MEX_FILE
+#define MALLOC mxMalloc
+#define FREE mxFree
+#else
+#define MALLOC malloc
+#define FREE free
+#endif
+
+/* Other commonly used macros ----------------------------------------- */
+#define inline __inline
+
+#endif
diff --git a/thirdparty/linux/include/coin/kkt.h b/thirdparty/linux/include/coin/kkt.h new file mode 100644 index 0000000..a2f58f6 --- /dev/null +++ b/thirdparty/linux/include/coin/kkt.h @@ -0,0 +1,135 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/* The KKT module.
+ * Handles all computation related to KKT matrix:
+ * - updating the matrix
+ * - its factorization
+ * - solving for search directions
+ * - etc.
+ */
+
+
+#ifndef __KKT_H__
+#define __KKT_H__
+
+#include "glblopts.h"
+#include "spla.h"
+#include "cone.h"
+
+typedef struct kkt{
+ spmat* PKPt; /* Permuted KKT matrix, upper part only */
+ spmat* L; /* LDL factor L */
+
+ pfloat* D; /* diagonal matrix D */
+ pfloat* work1; /* workspace needed for factorization */
+ pfloat* work2; /* workspace needed for factorization */
+ pfloat* work3; /* workspace needed for factorization */
+ pfloat* work4; /* workspace needed for factorization */
+ pfloat* work5; /* workspace needed for factorization */
+ pfloat* work6; /* workspace needed for factorization */
+ pfloat* RHS1; /* Right hand side 1 */
+ pfloat* RHS2; /* Right hand side 2 */
+ pfloat* dx1; /* search direction of size n */
+ pfloat* dx2; /* search direction of size n */
+ pfloat* dy1; /* search direction of size p */
+ pfloat* dy2; /* search direction of size p */
+ pfloat* dz1; /* search direction of size m */
+ pfloat* dz2; /* search direction of size m */
+
+ idxint* P; /* permutation */
+ idxint* Pinv; /* reverse permutation */
+ idxint* PK; /* permutation of row indices of KKT matrix */
+ idxint* Parent; /* Elimination tree of factorization */
+ idxint* Sign; /* Permuted sign vector for regularization */
+ idxint* Pattern; /* idxint workspace needed for factorization */
+ idxint* Flag; /* idxint workspace needed for factorization */
+ idxint* Lnz; /* idxint workspace needed for factorization */
+
+ pfloat delta; /* size of regularization */
+} kkt;
+
+/* Return codes */
+#define KKT_PROBLEM (0)
+#define KKT_OK (1)
+
+/* METHODS */
+
+/**
+ * Factorization of KKT matrix. Just a convenient wrapper for the LDL call.
+ * The second argument delta determindes the threshold of dynamic regularization,
+ * while the last argument is the regularization parameter if it becomes active.
+ *
+ * If detailed profiling is turned on, the function returns the accumulated times
+ * for sparsity pattern computation in t1 and for numerical solve in t2.
+ */
+#if PROFILING > 1
+idxint kkt_factor(kkt* KKT, pfloat eps, pfloat delta, pfloat *t1, pfloat *t2);
+#else
+idxint kkt_factor(kkt* KKT, pfloat eps, pfloat delta);
+#endif
+
+
+/**
+ * Solves the permuted KKT system and returns the unpermuted search directions.
+ *
+ * On entry, the factorization of the permuted KKT matrix, PKPt,
+ * is assumed to be up to date (call kkt_factor beforehand to achieve this).
+ * The right hand side, Pb, is assumed to be already permuted.
+ *
+ * On exit, the resulting search directions are written into dx, dy and dz,
+ * where these variables are permuted back to the original ordering.
+ *
+ * KKT->nitref iterative refinement steps are applied to solve the linear system.
+ *
+ * Returns the number of iterative refinement steps really taken.
+ */
+idxint kkt_solve(kkt* KKT,
+ spmat* A, spmat* G,
+ pfloat* Pb,
+ pfloat* dx, pfloat* dy, pfloat* dz,
+ idxint n, idxint p, idxint m,
+ cone* C,
+ idxint isinit,
+ idxint nitref);
+
+
+/**
+ * Updates the permuted KKT matrix by copying in the new scalings.
+ */
+void kkt_update(spmat* PKP, idxint* P, cone *C);
+
+
+/**
+ * Initializes the (3,3) block of the KKT matrix to produce the matrix
+ *
+ * [0 A' G']
+ * K = [A 0 0 ]
+ * [G 0 -I ]
+ *
+ * It is assumed that the A,G have been already copied in appropriately,
+ * and that enough memory has been allocated (this is done in preproc.c module).
+ *
+ * Note that the function works on the permuted KKT matrix.
+ */
+void kkt_init(spmat* PKP, idxint* P, cone *C);
+
+
+#endif
diff --git a/thirdparty/linux/include/coin/ldl.h b/thirdparty/linux/include/coin/ldl.h new file mode 100644 index 0000000..e468818 --- /dev/null +++ b/thirdparty/linux/include/coin/ldl.h @@ -0,0 +1,98 @@ +/* ========================================================================== */ +/* === ldl.h: include file for the LDL package ============================= */ +/* ========================================================================== */ + +/* Copyright (c) Timothy A Davis, http://www.suitesparse.com. + * All Rights Reserved. See README for the License. + * + * Stripped down by Alexander Domahidi, 2012. + */ + +#include "../../include/glblopts.h" +#include "../../include/ecos.h" + +#include "SuiteSparse_config.h" + +#ifdef LDL_LONG +#define LDL_int SuiteSparse_long +#define LDL_ID SuiteSparse_long_id + +#define LDL_symbolic2 ldl_l_symbolic2 +#define LDL_numeric2 ldl_l_numeric2 +#define LDL_lsolve ldl_l_lsolve +#define LDL_lsolve2 ldl_l_lsolve2 +#define LDL_dsolve ldl_l_dsolve +#define LDL_ltsolve ldl_l_ltsolve + +#else +#define LDL_int int +#define LDL_ID "%d" + +#define LDL_symbolic2 ldl_symbolic2 +#define LDL_numeric2 ldl_numeric2 +#define LDL_lsolve ldl_lsolve +#define LDL_lsolve2 ldl_lsolve2 +#define LDL_dsolve ldl_dsolve +#define LDL_ltsolve ldl_ltsolve + +#endif + +/* ========================================================================== */ +/* === int version ========================================================== */ +/* ========================================================================== */ + +void ldl_symbolic2 (int n, int Ap [ ], int Ai [ ], int Lp [ ], int Parent [ ], int Lnz [ ], int Flag [ ]) ; + +int ldl_numeric2 (int n, int Ap [ ], int Ai [ ], double Ax [ ], + int Lp [ ], int Parent [ ], int Sign[], double eps, double delta, int Lnz [ ], int Li [ ], double Lx [ ], + double D [ ], double Y [ ], int Pattern [ ], int Flag [ ] +#if PROFILING > 1 + ,double *t1, double *t2 +#endif + ) ; + +void ldl_lsolve (int n, double B [], int Lp [ ], int Li [ ], double Lx [ ]) ; +void ldl_lsolve2 (int n, double B [], int Lp [ ], int Li [ ], double Lx [ ], double X [ ]) ; + +void ldl_dsolve (int n, double X [ ], double D [ ]) ; + +void ldl_ltsolve (int n, double X [ ], int Lp [ ], int Li [ ], + double Lx [ ]) ; + +/* ========================================================================== */ +/* === long version ========================================================= */ +/* ========================================================================== */ + +void ldl_l_symbolic2 (SuiteSparse_long n, SuiteSparse_long Ap [ ], + SuiteSparse_long Ai [ ], SuiteSparse_long Lp [ ], + SuiteSparse_long Parent [ ], SuiteSparse_long Lnz [ ], + SuiteSparse_long Flag [ ]); + +SuiteSparse_long ldl_l_numeric2 (SuiteSparse_long n, SuiteSparse_long Ap [ ], + SuiteSparse_long Ai [ ], double Ax [ ], SuiteSparse_long Lp [ ], + SuiteSparse_long Parent [ ], SuiteSparse_long Sign [ ], double eps, double delta, SuiteSparse_long Lnz [ ], + SuiteSparse_long Li [ ], double Lx [ ], double D [ ], double Y [ ], + SuiteSparse_long Pattern [ ], SuiteSparse_long Flag [ ] +#if PROFILING > 1 + ,double *t1, double *t2 +#endif + ) ; + +void ldl_l_lsolve (SuiteSparse_long n, double B [ ], SuiteSparse_long Lp [ ], SuiteSparse_long Li [ ], double Lx [ ]) ; +void ldl_l_lsolve2 (SuiteSparse_long n, double B [ ], SuiteSparse_long Lp [ ], SuiteSparse_long Li [ ], double Lx [ ], double X [ ]) ; + +void ldl_l_dsolve (SuiteSparse_long n, double X [ ], double D [ ]) ; + +void ldl_l_ltsolve (SuiteSparse_long n, double X [ ], SuiteSparse_long Lp [ ], + SuiteSparse_long Li [ ], double Lx [ ]) ; + +/* ========================================================================== */ +/* === LDL version ========================================================== */ +/* ========================================================================== */ + +#define LDL_DATE "April 6, 2013, with dynamic regularization by A. Domahidi" +#define LDL_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) +#define LDL_MAIN_VERSION 2 +#define LDL_SUB_VERSION 1 +#define LDL_SUBSUB_VERSION 0 +#define LDL_VERSION LDL_VERSION_CODE(LDL_MAIN_VERSION,LDL_SUB_VERSION) diff --git a/thirdparty/linux/include/coin/spla.h b/thirdparty/linux/include/coin/spla.h new file mode 100644 index 0000000..5e8e173 --- /dev/null +++ b/thirdparty/linux/include/coin/spla.h @@ -0,0 +1,98 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Sparse linear algebra library for solver, i.e. no memory manager
+ * such as malloc is accessed by this module.
+ */
+
+#ifndef __SPLA_H__
+#define __SPLA_H__
+
+#include "glblopts.h"
+
+/* Data structure for sparse matrices */
+typedef struct spmat{
+ idxint* jc;
+ idxint* ir;
+ pfloat* pr;
+ idxint n;
+ idxint m;
+ idxint nnz;
+} spmat;
+
+
+/* SPARSE MATRIX OPERATIONS PROVIDED BY THIS MODULE -------------------- */
+
+/*
+ * Sparse matrix-vector multiply for operations
+ *
+ * y = A*x (if a > 0 && newVector == 1)
+ * y += A*x (if a > 0 && newVector == 0)
+ * y = -A*x (if a < 0 && newVector == 1)
+ * y -= A*x (if a < 0 && newVector == 0)
+ *
+ * where A is a sparse matrix and both x and y are assumed to be dense.
+ */
+void sparseMV(spmat* A, pfloat* x, pfloat* y, idxint a, idxint newVector);
+
+
+/*
+ * Sparse matrix-transpose-vector multiply with subtraction.
+ *
+ * If newVector > 0, then this computes y = -A'*x,
+ * otherwise y -= A'*x,
+ *
+ * where A is a sparse matrix and both x and y are assumed to be dense.
+ * If skipDiagonal == 1, then the contributions of diagonal elements are
+ * not counted.
+ *
+ * NOTE: The product is calculating without explicitly forming the
+ * transpose.
+ */
+void sparseMtVm(spmat* A, pfloat* x, pfloat* y, idxint newVector, idxint skipDiagonal);
+
+
+/*
+ * Vector addition y += x of size n.
+ */
+void vadd(idxint n, pfloat* x, pfloat* y);
+
+/*
+ * Vector subtraction with scaling: y -= a*x of size n.
+ */
+void vsubscale(idxint n, pfloat a, pfloat* x, pfloat* y);
+
+/*
+ * 2-norm of a vector.
+ */
+pfloat norm2(pfloat* v, idxint n);
+
+/*
+ * inf-norm of a vector.
+ */
+pfloat norminf(pfloat* v, idxint n);
+
+/*
+ * ECOS dot product z = x'*y of size n.
+ */
+pfloat eddot(idxint n, pfloat* x, pfloat* y);
+
+
+#endif
diff --git a/thirdparty/linux/include/coin/splamm.h b/thirdparty/linux/include/coin/splamm.h new file mode 100644 index 0000000..b3be9c3 --- /dev/null +++ b/thirdparty/linux/include/coin/splamm.h @@ -0,0 +1,123 @@ +/*
+ * ECOS - Embedded Conic Solver.
+ * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com],
+ * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Sparse linear algebra library for setup phase, i.e. this module
+ * accesses malloc and hence should not go on an embedded platform.
+ */
+
+#ifndef __SPLAMM_H__
+#define __SPLAMM_H__
+
+#include "glblopts.h"
+#include "spla.h"
+
+
+/**
+ * Create a sparse matrix from existing arrays.
+ */
+spmat* createSparseMatrix(idxint m, idxint n, idxint nnz, idxint* jc, idxint* ir, pfloat* pr);
+
+
+/**
+ * Create a new sparse matrix (uses MALLOC!)
+ */
+spmat* newSparseMatrix(idxint m, idxint n, idxint nnz);
+
+/**
+ * Create a new sparse matrix (uses FREE!)
+ */
+void freeSparseMatrix(spmat* M);
+
+
+/**
+ * Transpose a matrix; returns A = M' (uses malloc!)
+ */
+spmat* transposeSparseMatrix(spmat* M, idxint* MtoMt);
+
+
+/**
+ * Permutes a symmetric matrix with only the upper triangular part stored.
+ * Writes the upper triangular part of C = A(p,p) in column compressed
+ * storage format.
+ *
+ * The function additionally returns the mapping PK that maps the row indices
+ * of the sparse matrix A on the row indices of C, such that C[P[k]] = A[k].
+ *
+ * NOTE: The matrix C and the vector PK are NOT created within this function
+ * - you need to allocate them beforehand!!
+ *
+ * If PK is NULL then the last output argument is ignored.
+ */
+void permuteSparseSymmetricMatrix(spmat* A, idxint* pinv, spmat* C, idxint* PK);
+
+
+/**
+ * Returns the inverse of permutation p of length n.
+ */
+void pinv(idxint n, idxint* p, idxint* pinv);
+
+
+/**
+ * Returns a copy of a sparse matrix A.
+ */
+spmat* copySparseMatrix(spmat* A);
+
+/* ============================= DEBUG FUNCTIONS ======================= */
+#if PRINTLEVEL > 0
+
+/**
+ * Prints a dense matrix.
+ */
+void printDenseMatrix(pfloat *M, idxint dim1, idxint dim2, char *name);
+
+
+/**
+ * Prints a dense integer matrix.
+ */
+void printDenseMatrix_i(idxint *M, idxint dim1, idxint dim2, char *name);
+
+
+/**
+ * Prints a sparse matrix.
+ */
+void printSparseMatrix(spmat* M);
+
+
+/**
+ * Dumps a sparse matrix in Matlab format.
+ * Use SPCONVERT to read in the file.
+ */
+void dumpSparseMatrix(spmat* M, char* fn);
+
+
+/**
+ * Dumps a dense matrix of doubles to a CSV file.
+ */
+void dumpDenseMatrix(pfloat *M, int dim1, int dim2, char *fn);
+
+/**
+ * Dumps a dense matrix of integers to a CSV file.
+ */
+void dumpDenseMatrix_i(idxint *M, int dim1, int dim2, char *fn);
+
+#endif
+
+#endif
diff --git a/thirdparty/linux/include/coin/symphony.h b/thirdparty/linux/include/coin/symphony.h index d9ddace..9106e82 100644 --- a/thirdparty/linux/include/coin/symphony.h +++ b/thirdparty/linux/include/coin/symphony.h @@ -193,6 +193,8 @@ typedef struct SYM_ENVIRONMENT sym_environment; void sym_version PROTO((void)); sym_environment *sym_open_environment PROTO((void)); +int sym_close_environment PROTO((sym_environment *env)); +int sym_reset_environment PROTO((sym_environment *env)); int sym_set_defaults PROTO((sym_environment *env)); int sym_parse_command_line PROTO((sym_environment *env, int argc, char **argv)); @@ -213,7 +215,6 @@ int sym_warm_solve PROTO((sym_environment *env)); int sym_mc_solve PROTO((sym_environment *env)); int sym_create_permanent_cut_pools PROTO((sym_environment *env, int *cp_num)); -int sym_close_environment PROTO((sym_environment *env)); int sym_explicit_load_problem PROTO((sym_environment *env, int numcols, int numrows, int *start, int *index, double *value, double *collb, diff --git a/thirdparty/linux/include/coin/timer.h b/thirdparty/linux/include/coin/timer.h new file mode 100644 index 0000000..7da68ff --- /dev/null +++ b/thirdparty/linux/include/coin/timer.h @@ -0,0 +1,75 @@ +/* + * ECOS - Embedded Conic Solver. + * Copyright (C) 2012-2015 A. Domahidi [domahidi@embotech.com], + * Automatic Control Lab, ETH Zurich & embotech GmbH, Zurich, Switzerland. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * Interface for the built-in timer of ECOS. + */ +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include "glblopts.h" + +#if PROFILING > 0 + +#if (defined _WIN32 || defined _WIN64 || defined _WINDLL ) + +/* Use Windows QueryPerformanceCounter for timing */ +#include <windows.h> + +typedef struct timer{ + LARGE_INTEGER tic; + LARGE_INTEGER toc; + LARGE_INTEGER freq; +} timer; + + +#elif (defined __APPLE__) + +#include <mach/mach_time.h> + +/* Use MAC OSX mach_time for timing */ +typedef struct timer{ + uint64_t tic; + uint64_t toc; + mach_timebase_info_data_t tinfo; +} timer; + + + +#else + +/* Use POSIX clocl_gettime() for timing on non-Windows machines */ +#include <time.h> +#include <sys/time.h> + +typedef struct timer{ + struct timespec tic; + struct timespec toc; +} timer; + +#endif + +/* METHODS are the same for both */ +void tic(timer* t); +pfloat toc(timer* t); + +#endif /* END IF PROFILING > 0 */ + +#endif +/* END IFDEF __TIMER_H__ */ diff --git a/thirdparty/linux/include/coin/wright_omega.h b/thirdparty/linux/include/coin/wright_omega.h new file mode 100644 index 0000000..dd50a77 --- /dev/null +++ b/thirdparty/linux/include/coin/wright_omega.h @@ -0,0 +1,26 @@ +/** + * Santiago Akle + * ICME Stanford University 2014 + * + * Computes the value \omega(z) defined as the solution y to + * the equation y+log(y) = z for z real and z>=1. + * Follows the recommendations by + * PIERS W. LAWRENCE, ROBERT M. CORLESS, and DAVID J. JEFFREY. + * Published in: + * Algorithm 917: Complex Double-Precision Evaluation of the Wright \omega Function + * ACM Transactions on Mathematical Software (TOMS) TOMS Homepage table of contents archive + * Volume 38 Issue 3, April 2012 + * Article No. 20 + * Publication Date 2012-04-01 (yyyy-mm-dd) + * Publisher ACM New York, NY, USA + * ISSN: 0098-3500 EISSN: 1557-7295 doi>10.1145/2168773.2168779 + */ + +#include "glblopts.h" + +#if (defined _WIN32 || defined _WIN64 || defined _WINDLL ) +#define _USE_MATH_DEFINES +#endif +#include <math.h> + +pfloat wrightOmega(pfloat z); diff --git a/thirdparty/linux/include/coin1/CbcOrClpParam.cpp b/thirdparty/linux/include/coin1/CbcOrClpParam.cpp new file mode 100644 index 0000000..b434fe0 --- /dev/null +++ b/thirdparty/linux/include/coin1/CbcOrClpParam.cpp @@ -0,0 +1,4104 @@ +/* $Id: CbcOrClpParam.cpp 2079 2015-01-05 13:11:35Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#include "CoinPragma.hpp" +#include "CoinTime.hpp" +#include "CbcOrClpParam.hpp" + +#include <string> +#include <iostream> +#include <cassert> + +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_CLP +#include "OsiClpSolverInterface.hpp" +#include "ClpSimplex.hpp" +#endif +#include "CbcModel.hpp" +#endif +#include "CoinHelperFunctions.hpp" +#ifdef COIN_HAS_CLP +#include "ClpSimplex.hpp" +#include "ClpFactorization.hpp" +#endif +#ifdef COIN_HAS_READLINE +#include <readline/readline.h> +#include <readline/history.h> +#endif +#ifdef COIN_HAS_CBC +// from CoinSolve +static char coin_prompt[] = "Coin:"; +#else +static char coin_prompt[] = "Clp:"; +#endif +#ifdef CLP_CILK +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#if defined(COIN_HAS_WSMP) && ! defined(USE_EKKWSSMP) +#ifndef CBC_THREAD +#define CBC_THREAD +#endif +#endif +#include "ClpConfig.h" +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +#endif +static bool doPrinting = true; +std::string afterEquals = ""; +static char printArray[200]; +#if COIN_INT_MAX==0 +#undef COIN_INT_MAX +#define COIN_INT_MAX 2147483647 +#endif +void setCbcOrClpPrinting(bool yesNo) +{ + doPrinting = yesNo; +} +//############################################################################# +// Constructors / Destructor / Assignment +//############################################################################# + +//------------------------------------------------------------------- +// Default Constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam () + : type_(CBC_PARAM_NOTUSED_INVALID), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + lengthName_(0), + lengthMatch_(0), + definedKeyWords_(), + name_(), + shortHelp_(), + longHelp_(), + action_(CBC_PARAM_NOTUSED_INVALID), + currentKeyWord_(-1), + display_(0), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ +} +// Other constructors +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + lowerDoubleValue_ = lower; + upperDoubleValue_ = upper; + gutsOfConstructor(); +} +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(7), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + lowerIntValue_ = lower; + upperIntValue_ = upper; +} +// Other strings will be added by append +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + std::string firstValue, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(0), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + whereUsed_(whereUsed), + fakeKeyWord_(-1), + fakeValue_(0) +{ + gutsOfConstructor(); + definedKeyWords_.push_back(firstValue); +} +// Action +CbcOrClpParam::CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed, + int display) + : type_(type), + lowerDoubleValue_(0.0), + upperDoubleValue_(0.0), + lowerIntValue_(0), + upperIntValue_(0), + definedKeyWords_(), + name_(name), + shortHelp_(help), + longHelp_(), + action_(type), + currentKeyWord_(-1), + display_(display), + intValue_(-1), + doubleValue_(-1.0), + stringValue_(""), + fakeKeyWord_(-1), + fakeValue_(0) +{ + whereUsed_ = whereUsed; + gutsOfConstructor(); +} + +//------------------------------------------------------------------- +// Copy constructor +//------------------------------------------------------------------- +CbcOrClpParam::CbcOrClpParam (const CbcOrClpParam & rhs) +{ + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; +} + +//------------------------------------------------------------------- +// Destructor +//------------------------------------------------------------------- +CbcOrClpParam::~CbcOrClpParam () +{ +} + +//---------------------------------------------------------------- +// Assignment operator +//------------------------------------------------------------------- +CbcOrClpParam & +CbcOrClpParam::operator=(const CbcOrClpParam & rhs) +{ + if (this != &rhs) { + type_ = rhs.type_; + lowerDoubleValue_ = rhs.lowerDoubleValue_; + upperDoubleValue_ = rhs.upperDoubleValue_; + lowerIntValue_ = rhs.lowerIntValue_; + upperIntValue_ = rhs.upperIntValue_; + lengthName_ = rhs.lengthName_; + lengthMatch_ = rhs.lengthMatch_; + definedKeyWords_ = rhs.definedKeyWords_; + name_ = rhs.name_; + shortHelp_ = rhs.shortHelp_; + longHelp_ = rhs.longHelp_; + action_ = rhs.action_; + currentKeyWord_ = rhs.currentKeyWord_; + display_ = rhs.display_; + intValue_ = rhs.intValue_; + doubleValue_ = rhs.doubleValue_; + stringValue_ = rhs.stringValue_; + whereUsed_ = rhs.whereUsed_; + fakeKeyWord_ = rhs.fakeKeyWord_; + fakeValue_ = rhs.fakeValue_; + } + return *this; +} +void +CbcOrClpParam::gutsOfConstructor() +{ + std::string::size_type shriekPos = name_.find('!'); + lengthName_ = static_cast<unsigned int>(name_.length()); + if ( shriekPos == std::string::npos ) { + //does not contain '!' + lengthMatch_ = lengthName_; + } else { + lengthMatch_ = static_cast<unsigned int>(shriekPos); + name_ = name_.substr(0, shriekPos) + name_.substr(shriekPos + 1); + lengthName_--; + } +} +// Sets value of fake keyword to current size of keywords +void +CbcOrClpParam::setFakeKeyWord(int fakeValue) +{ + fakeKeyWord_ = static_cast<int>(definedKeyWords_.size()); + assert (fakeKeyWord_>0); + fakeValue_ = fakeValue; + assert (fakeValue_>=0); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ +*/ +int +CbcOrClpParam::currentOptionAsInteger ( ) const +{ + int fakeInteger; + return currentOptionAsInteger(fakeInteger); +} +/* Returns current parameter option position + but if fake keyword returns fakeValue_ and sets + fakeInteger to value +*/ +int +CbcOrClpParam::currentOptionAsInteger ( int & fakeInteger ) const +{ + fakeInteger=-COIN_INT_MAX; + if (fakeKeyWord_<0) { + return currentKeyWord_; + } else if (currentKeyWord_>=0&¤tKeyWord_<fakeKeyWord_){ + return currentKeyWord_; + } else { + // fake + if (currentKeyWord_<0) + fakeInteger = currentKeyWord_ + 1000; + else + fakeInteger = currentKeyWord_ - 1000; + return fakeValue_; + } +} +// Returns length of name for printing +int +CbcOrClpParam::lengthMatchName ( ) const +{ + if (lengthName_ == lengthMatch_) + return lengthName_; + else + return lengthName_ + 2; +} +// Insert string (only valid for keywords) +void +CbcOrClpParam::append(std::string keyWord) +{ + definedKeyWords_.push_back(keyWord); +} + +int +CbcOrClpParam::matches (std::string input) const +{ + // look up strings to do more elegantly + if (input.length() > lengthName_) { + return 0; + } else { + unsigned int i; + for (i = 0; i < input.length(); i++) { + if (tolower(name_[i]) != tolower(input[i])) + break; + } + if (i < input.length()) { + return 0; + } else if (i >= lengthMatch_) { + return 1; + } else { + // matched but too short + return 2; + } + } +} +// Returns name which could match +std::string +CbcOrClpParam::matchName ( ) const +{ + if (lengthMatch_ == lengthName_) + return name_; + else + return name_.substr(0, lengthMatch_) + "(" + name_.substr(lengthMatch_) + ")"; +} + +// Returns parameter option which matches (-1 if none) +int +CbcOrClpParam::parameterOption ( std::string check ) const +{ + int numberItems = static_cast<int>(definedKeyWords_.size()); + if (!numberItems) { + return -1; + } else { + int whichItem = 0; + unsigned int it; + for (it = 0; it < definedKeyWords_.size(); it++) { + std::string thisOne = definedKeyWords_[it]; + std::string::size_type shriekPos = thisOne.find('!'); + size_t length1 = thisOne.length(); + size_t length2 = length1; + if ( shriekPos != std::string::npos ) { + //contains '!' + length2 = shriekPos; + thisOne = thisOne.substr(0, shriekPos) + + thisOne.substr(shriekPos + 1); + length1 = thisOne.length(); + } + if (check.length() <= length1 && length2 <= check.length()) { + unsigned int i; + for (i = 0; i < check.length(); i++) { + if (tolower(thisOne[i]) != tolower(check[i])) + break; + } + if (i < check.length()) { + whichItem++; + } else if (i >= length2) { + break; + } + } else { + whichItem++; + } + } + if (whichItem < numberItems) { + return whichItem; + } else { + if (fakeKeyWord_<=0) + return -1; + // allow plus or minus + int n; + if (check.substr(0,4)=="plus"||check.substr(0,4)=="PLUS") { + n = 4; + } else if (check.substr(0,5)=="minus"||check.substr(0,5)=="MINUS") { + n = 5; + } else { + return -1; + } + int value = 0; + std::string field=check.substr(n); + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = static_cast<int>(strtol(start, &endPointer, 10)); + if (*endPointer != '\0') { + return -1; + } + if (n==4) + return value + 1000; + else + return -value - 1000; + } else { + return -1; + } + } + } +} +// Prints parameter options +void +CbcOrClpParam::printOptions ( ) const +{ + std::cout << "<Possible options for " << name_ << " are:"; + unsigned int it; + for (it = 0; it < definedKeyWords_.size(); it++) { + std::string thisOne = definedKeyWords_[it]; + std::string::size_type shriekPos = thisOne.find('!'); + if ( shriekPos != std::string::npos ) { + //contains '!' + thisOne = thisOne.substr(0, shriekPos) + + "(" + thisOne.substr(shriekPos + 1) + ")"; + } + std::cout << " " << thisOne; + } + assert (currentKeyWord_ >= 0 && currentKeyWord_ < static_cast<int>(definedKeyWords_.size())); + std::string current = definedKeyWords_[currentKeyWord_]; + std::string::size_type shriekPos = current.find('!'); + if ( shriekPos != std::string::npos ) { + //contains '!' + current = current.substr(0, shriekPos) + + "(" + current.substr(shriekPos + 1) + ")"; + } + std::cout << ";\n\tcurrent " << current << ">" << std::endl; +} +// Print action and string +void +CbcOrClpParam::printString() const +{ + if (name_ == "directory") + std::cout << "Current working directory is " << stringValue_ << std::endl; + else if (name_.substr(0, 6) == "printM") + std::cout << "Current value of printMask is " << stringValue_ << std::endl; + else + std::cout << "Current default (if $ as parameter) for " << name_ + << " is " << stringValue_ << std::endl; +} +void CoinReadPrintit(const char * input) +{ + int length = static_cast<int>(strlen(input)); + char temp[101]; + int i; + int n = 0; + for (i = 0; i < length; i++) { + if (input[i] == '\n') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n >= 65 && input[i] == ' ') { + temp[n] = '\0'; + std::cout << temp << std::endl; + n = 0; + } else if (n || input[i] != ' ') { + temp[n++] = input[i]; + } + } + if (n) { + temp[n] = '\0'; + std::cout << temp << std::endl; + } +} +// Print Long help +void +CbcOrClpParam::printLongHelp() const +{ + if (type_ >= 1 && type_ < 400) { + CoinReadPrintit(longHelp_.c_str()); + if (type_ < CLP_PARAM_INT_SOLVERLOGLEVEL) { + printf("<Range of values is %g to %g;\n\tcurrent %g>\n", lowerDoubleValue_, upperDoubleValue_, doubleValue_); + assert (upperDoubleValue_ > lowerDoubleValue_); + } else if (type_ < CLP_PARAM_STR_DIRECTION) { + printf("<Range of values is %d to %d;\n\tcurrent %d>\n", lowerIntValue_, upperIntValue_, intValue_); + assert (upperIntValue_ > lowerIntValue_); + } else if (type_ < CLP_PARAM_ACTION_DIRECTORY) { + printOptions(); + } + } +} +#ifdef COIN_HAS_CBC +int +CbcOrClpParam::setDoubleParameter (OsiSolverInterface * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->getDblParam(OsiDualTolerance, oldValue); + model->setDblParam(OsiDualTolerance, value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->getDblParam(OsiPrimalTolerance, oldValue); + model->setDblParam(OsiPrimalTolerance, value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +#endif +#ifdef COIN_HAS_CLP +int +CbcOrClpParam::setDoubleParameter (ClpSimplex * model, double value) +{ + int returnCode; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode) +{ + double oldValue = doubleValue_; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + doubleValue_ = value; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + model->setDualTolerance(value); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + model->setPrimalTolerance(value); + break; + case CLP_PARAM_DBL_ZEROTOLERANCE: + model->setSmallElementValue(value); + break; + case CLP_PARAM_DBL_DUALBOUND: + model->setDualBound(value); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + model->setInfeasibilityCost(value); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + model->setMaximumSeconds(value); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + model->setObjectiveScale(value); + break; + case CLP_PARAM_DBL_RHSSCALE: + model->setRhsScale(value); + break; + case CLP_PARAM_DBL_PRESOLVETOLERANCE: + model->setDblParam(ClpPresolveTolerance, value); + break; + default: + break; + } + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (ClpSimplex * model) const +{ + double value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_DUALTOLERANCE: + value = model->dualTolerance(); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = model->primalTolerance(); + break; +#endif + case CLP_PARAM_DBL_ZEROTOLERANCE: + value = model->getSmallElementValue(); + break; + case CLP_PARAM_DBL_DUALBOUND: + value = model->dualBound(); + break; + case CLP_PARAM_DBL_PRIMALWEIGHT: + value = model->infeasibilityCost(); + break; +#ifndef COIN_HAS_CBC + case CLP_PARAM_DBL_TIMELIMIT: + value = model->maximumSeconds(); + break; +#endif + case CLP_PARAM_DBL_OBJSCALE: + value = model->objectiveScale(); + break; + case CLP_PARAM_DBL_RHSSCALE: + value = model->rhsScale(); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (ClpSimplex * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode) +{ + int oldValue = intValue_; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + intValue_ = value; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->setLogLevel(value); + if (value > 2) + model->factorization()->messageLevel(8); + else + model->factorization()->messageLevel(0); + break; + case CLP_PARAM_INT_MAXFACTOR: + model->factorization()->maximumPivots(value); + break; + case CLP_PARAM_INT_PERTVALUE: + model->setPerturbation(value); + break; + case CLP_PARAM_INT_MAXITERATION: + model->setMaximumIterations(value); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + model->setSpecialOptions(value); + break; + case CLP_PARAM_INT_RANDOMSEED: + { + if (value==0) { + double time = fabs(CoinGetTimeOfDay()); + while (time>=COIN_INT_MAX) + time *= 0.5; + value = static_cast<int>(time); + sprintf(printArray, "using time of day %s was changed from %d to %d", + name_.c_str(), oldValue, value); + } + model->setRandomSeed(value); + } + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + model->setMoreSpecialOptions(value); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + model->setNumberThreads(value); + break; +#endif +#endif + default: + break; + } + } + return printArray; +} +int +CbcOrClpParam::intParameter (ClpSimplex * model) const +{ + int value; + switch (type_) { +#ifndef COIN_HAS_CBC + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->logLevel(); + break; +#endif + case CLP_PARAM_INT_MAXFACTOR: + value = model->factorization()->maximumPivots(); + break; + break; + case CLP_PARAM_INT_PERTVALUE: + value = model->perturbation(); + break; + case CLP_PARAM_INT_MAXITERATION: + value = model->maximumIterations(); + break; + case CLP_PARAM_INT_SPECIALOPTIONS: + value = model->specialOptions(); + break; + case CLP_PARAM_INT_RANDOMSEED: + value = model->randomNumberGenerator()->getSeed(); + break; + case CLP_PARAM_INT_MORESPECIALOPTIONS: + value = model->moreSpecialOptions(); + break; +#ifndef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model->numberThreads(); + break; +#endif +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +int +CbcOrClpParam::checkDoubleParameter (double value) const +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + return 1; + } else { + return 0; + } +} +#ifdef COIN_HAS_CBC +double +CbcOrClpParam::doubleParameter (OsiSolverInterface * +#ifndef NDEBUG + model +#endif + ) const +{ + double value = 0.0; + switch (type_) { + case CLP_PARAM_DBL_DUALTOLERANCE: + assert(model->getDblParam(OsiDualTolerance, value)); + break; + case CLP_PARAM_DBL_PRIMALTOLERANCE: + assert(model->getDblParam(OsiPrimalTolerance, value)); + break; + default: + return doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (OsiSolverInterface * model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + int oldValue = intValue_; + intValue_ = oldValue; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + model->messageHandler()->setLogLevel(value); + break; + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (OsiSolverInterface * model) const +{ + int value = 0; + switch (type_) { + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model->messageHandler()->logLevel(); + break; + default: + value = intValue_; + break; + } + return value; +} +int +CbcOrClpParam::setDoubleParameter (CbcModel &model, double value) +{ + int returnCode=0; + setDoubleParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets double parameter and returns printable string and error code +const char * +CbcOrClpParam::setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value, name_.c_str(), lowerDoubleValue_, upperDoubleValue_); + returnCode = 1; + } else { + double oldValue = doubleValue_; + doubleValue_ = value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + oldValue = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + model.setDblParam(CbcModel::CbcInfeasibilityWeight, value); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + oldValue = model.getDblParam(CbcModel::CbcIntegerTolerance); + model.setDblParam(CbcModel::CbcIntegerTolerance, value); + break; + case CBC_PARAM_DBL_INCREMENT: + oldValue = model.getDblParam(CbcModel::CbcCutoffIncrement); + model.setDblParam(CbcModel::CbcCutoffIncrement, value); + case CBC_PARAM_DBL_ALLOWABLEGAP: + oldValue = model.getDblParam(CbcModel::CbcAllowableGap); + model.setDblParam(CbcModel::CbcAllowableGap, value); + break; + case CBC_PARAM_DBL_GAPRATIO: + oldValue = model.getDblParam(CbcModel::CbcAllowableFractionGap); + model.setDblParam(CbcModel::CbcAllowableFractionGap, value); + break; + case CBC_PARAM_DBL_CUTOFF: + oldValue = model.getCutoff(); + model.setCutoff(value); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + oldValue = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + { + //OsiClpSolverInterface * clpSolver = dynamic_cast< OsiClpSolverInterface*> (model.solver()); + //ClpSimplex * lpSolver = clpSolver->getModelPtr(); + //lpSolver->setMaximumSeconds(value); + model.setDblParam(CbcModel::CbcMaximumSeconds, value) ; + } + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + setDoubleParameter(model.solver(), value); + return 0; // to avoid message + default: + break; + } + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +double +CbcOrClpParam::doubleParameter (CbcModel &model) const +{ + double value; + switch (type_) { + case CBC_PARAM_DBL_INFEASIBILITYWEIGHT: + value = model.getDblParam(CbcModel::CbcInfeasibilityWeight); + break; + case CBC_PARAM_DBL_INTEGERTOLERANCE: + value = model.getDblParam(CbcModel::CbcIntegerTolerance); + break; + case CBC_PARAM_DBL_INCREMENT: + value = model.getDblParam(CbcModel::CbcCutoffIncrement); + break; + case CBC_PARAM_DBL_ALLOWABLEGAP: + value = model.getDblParam(CbcModel::CbcAllowableGap); + break; + case CBC_PARAM_DBL_GAPRATIO: + value = model.getDblParam(CbcModel::CbcAllowableFractionGap); + break; + case CBC_PARAM_DBL_CUTOFF: + value = model.getCutoff(); + break; + case CBC_PARAM_DBL_TIMELIMIT_BAB: + value = model.getDblParam(CbcModel::CbcMaximumSeconds) ; + break ; + case CLP_PARAM_DBL_DUALTOLERANCE: + case CLP_PARAM_DBL_PRIMALTOLERANCE: + value = doubleParameter(model.solver()); + break; + default: + value = doubleValue_; + break; + } + return value; +} +int +CbcOrClpParam::setIntParameter (CbcModel &model, int value) +{ + int returnCode; + setIntParameterWithMessage(model, value, returnCode); + if (doPrinting && strlen(printArray)) + std::cout << printArray << std::endl; + return returnCode; +} +// Sets int parameter and returns printable string and error code +const char * +CbcOrClpParam::setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value, name_.c_str(), lowerIntValue_, upperIntValue_); + returnCode = 1; + } else { + printArray[0] = '\0'; + if (value==intValue_) + return printArray; + int oldValue = intValue_; + intValue_ = value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + oldValue = model.messageHandler()->logLevel(); + model.messageHandler()->setLogLevel(CoinAbs(value)); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + oldValue = model.solver()->messageHandler()->logLevel(); + model.solver()->messageHandler()->setLogLevel(value); + break; + case CBC_PARAM_INT_MAXNODES: + oldValue = model.getIntParam(CbcModel::CbcMaxNumNode); + model.setIntParam(CbcModel::CbcMaxNumNode, value); + break; + case CBC_PARAM_INT_MAXSOLS: + oldValue = model.getIntParam(CbcModel::CbcMaxNumSol); + model.setIntParam(CbcModel::CbcMaxNumSol, value); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + oldValue = model.maximumSavedSolutions(); + model.setMaximumSavedSolutions(value); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + oldValue = model.numberStrong(); + model.setNumberStrong(value); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + oldValue = model.numberBeforeTrust(); + model.setNumberBeforeTrust(value); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + oldValue = model.numberAnalyzeIterations(); + model.setNumberAnalyzeIterations(value); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + oldValue = model.getMaximumCutPasses(); + model.setMaximumCutPasses(value); + break; + case CBC_PARAM_INT_CUTPASS: + oldValue = model.getMaximumCutPassesAtRoot(); + model.setMaximumCutPassesAtRoot(value); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + oldValue = model.getNumberThreads(); + model.setNumberThreads(value); + break; +#endif + case CBC_PARAM_INT_RANDOMSEED: + oldValue = model.getRandomSeed(); + model.setRandomSeed(value); + break; +#endif + default: + break; + } + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), oldValue, value); + returnCode = 0; + } + return printArray; +} +int +CbcOrClpParam::intParameter (CbcModel &model) const +{ + int value; + switch (type_) { + case CLP_PARAM_INT_LOGLEVEL: + value = model.messageHandler()->logLevel(); + break; + case CLP_PARAM_INT_SOLVERLOGLEVEL: + value = model.solver()->messageHandler()->logLevel(); + break; + case CBC_PARAM_INT_MAXNODES: + value = model.getIntParam(CbcModel::CbcMaxNumNode); + break; + case CBC_PARAM_INT_MAXSOLS: + value = model.getIntParam(CbcModel::CbcMaxNumSol); + break; + case CBC_PARAM_INT_MAXSAVEDSOLS: + value = model.maximumSavedSolutions(); + break; + case CBC_PARAM_INT_STRONGBRANCHING: + value = model.numberStrong(); + break; + case CBC_PARAM_INT_NUMBERBEFORE: + value = model.numberBeforeTrust(); + break; + case CBC_PARAM_INT_NUMBERANALYZE: + value = model.numberAnalyzeIterations(); + break; + case CBC_PARAM_INT_CUTPASSINTREE: + value = model.getMaximumCutPasses(); + break; + case CBC_PARAM_INT_CUTPASS: + value = model.getMaximumCutPassesAtRoot(); + break; +#ifdef COIN_HAS_CBC +#ifdef CBC_THREAD + case CBC_PARAM_INT_THREADS: + value = model.getNumberThreads(); +#endif + case CBC_PARAM_INT_RANDOMSEED: + value = model.getRandomSeed(); + break; +#endif + default: + value = intValue_; + break; + } + return value; +} +#endif +// Sets current parameter option using string +void +CbcOrClpParam::setCurrentOption ( const std::string value ) +{ + int action = parameterOption(value); + if (action >= 0) + currentKeyWord_ = action; +} +// Sets current parameter option +void +CbcOrClpParam::setCurrentOption ( int value , bool printIt) +{ + if (printIt && value != currentKeyWord_) + std::cout << "Option for " << name_ << " changed from " + << definedKeyWords_[currentKeyWord_] << " to " + << definedKeyWords_[value] << std::endl; + + currentKeyWord_ = value; +} +// Sets current parameter option and returns printable string +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( int value ) +{ + if (value != currentKeyWord_) { + char current[100]; + char newString[100]; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) + strcpy(current,definedKeyWords_[currentKeyWord_].c_str()); + else if (currentKeyWord_<0) + sprintf(current,"minus%d",-currentKeyWord_-1000); + else + sprintf(current,"plus%d",currentKeyWord_-1000); + if (value>=0&&(fakeKeyWord_<=0||value<fakeKeyWord_) ) + strcpy(newString,definedKeyWords_[value].c_str()); + else if (value<0) + sprintf(newString,"minus%d",-value-1000); + else + sprintf(newString,"plus%d",value-1000); + sprintf(printArray, "Option for %s changed from %s to %s", + name_.c_str(), current, newString); + currentKeyWord_ = value; + } else { + printArray[0] = '\0'; + } + return printArray; +} +// Sets current parameter option using string with message +const char * +CbcOrClpParam::setCurrentOptionWithMessage ( const std::string value ) +{ + int action = parameterOption(value); + char current[100]; + printArray[0] = '\0'; + if (action >= 0) { + if (action == currentKeyWord_) + return NULL; + if (currentKeyWord_>=0&&(fakeKeyWord_<=0||currentKeyWord_<fakeKeyWord_)) + strcpy(current,definedKeyWords_[currentKeyWord_].c_str()); + else if (currentKeyWord_<0) + sprintf(current,"minus%d",-currentKeyWord_-1000); + else + sprintf(current,"plus%d",currentKeyWord_-1000); + sprintf(printArray, "Option for %s changed from %s to %s", + name_.c_str(), current, value.c_str()); + currentKeyWord_ = action; + } else { + sprintf(printArray, "Option for %s given illegal value %s", + name_.c_str(), value.c_str()); + } + return printArray; +} +void +CbcOrClpParam::setIntValue ( int value ) +{ + if (value < lowerIntValue_ || value > upperIntValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerIntValue_ << " to " << + upperIntValue_ << std::endl; + } else { + intValue_ = value; + } +} +const char * +CbcOrClpParam::setIntValueWithMessage ( int value ) +{ + printArray[0] = '\0'; + if (value < lowerIntValue_ || value > upperIntValue_) { + sprintf(printArray, "%d was provided for %s - valid range is %d to %d", + value,name_.c_str(),lowerIntValue_,upperIntValue_); + } else { + if (value==intValue_) + return NULL; + sprintf(printArray, "%s was changed from %d to %d", + name_.c_str(), intValue_, value); + intValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setDoubleValue ( double value ) +{ + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + std::cout << value << " was provided for " << name_ << + " - valid range is " << lowerDoubleValue_ << " to " << + upperDoubleValue_ << std::endl; + } else { + doubleValue_ = value; + } +} +const char * +CbcOrClpParam::setDoubleValueWithMessage ( double value ) +{ + printArray[0] = '\0'; + if (value < lowerDoubleValue_ || value > upperDoubleValue_) { + sprintf(printArray, "%g was provided for %s - valid range is %g to %g", + value,name_.c_str(),lowerDoubleValue_,upperDoubleValue_); + } else { + if (value==doubleValue_) + return NULL; + sprintf(printArray, "%s was changed from %g to %g", + name_.c_str(), doubleValue_, value); + doubleValue_ = value; + } + return printArray; +} +void +CbcOrClpParam::setStringValue ( std::string value ) +{ + stringValue_ = value; +} +static char line[1000]; +static char * where = NULL; +extern int CbcOrClpRead_mode; +int CbcOrClpEnvironmentIndex = -1; +static size_t fillEnv() +{ +#if defined(_MSC_VER) || defined(__MSVCRT__) + return 0; +#else + // Don't think it will work on Windows + char * environ = getenv("CBC_CLP_ENVIRONMENT"); + size_t length = 0; + if (environ) { + length = strlen(environ); + if (CbcOrClpEnvironmentIndex < static_cast<int>(length)) { + // find next non blank + char * whereEnv = environ + CbcOrClpEnvironmentIndex; + // munch white space + while (*whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ') + whereEnv++; + // copy + char * put = line; + while ( *whereEnv != '\0' ) { + if ( *whereEnv == ' ' || *whereEnv == '\t' || *whereEnv < ' ' ) { + break; + } + *put = *whereEnv; + put++; + assert (put - line < 1000); + whereEnv++; + } + CbcOrClpEnvironmentIndex = static_cast<int>(whereEnv - environ); + *put = '\0'; + length = strlen(line); + } else { + length = 0; + } + } + if (!length) + CbcOrClpEnvironmentIndex = -1; + return length; +#endif +} +extern FILE * CbcOrClpReadCommand; +// Simple read stuff +std::string +CoinReadNextField() +{ + std::string field; + if (!where) { + // need new line +#ifdef COIN_HAS_READLINE + if (CbcOrClpReadCommand == stdin) { + // Get a line from the user. + where = readline (coin_prompt); + + // If the line has any text in it, save it on the history. + if (where) { + if ( *where) + add_history (where); + strcpy(line, where); + free(where); + } + } else { + where = fgets(line, 1000, CbcOrClpReadCommand); + } +#else + if (CbcOrClpReadCommand == stdin) { + fputs(coin_prompt,stdout); + fflush(stdout); + } + where = fgets(line, 1000, CbcOrClpReadCommand); +#endif + if (!where) + return field; // EOF + where = line; + // clean image + char * lastNonBlank = line - 1; + while ( *where != '\0' ) { + if ( *where != '\t' && *where < ' ' ) { + break; + } else if ( *where != '\t' && *where != ' ') { + lastNonBlank = where; + } + where++; + } + where = line; + *(lastNonBlank + 1) = '\0'; + } + // munch white space + while (*where == ' ' || *where == '\t') + where++; + char * saveWhere = where; + while (*where != ' ' && *where != '\t' && *where != '\0') + where++; + if (where != saveWhere) { + char save = *where; + *where = '\0'; + //convert to string + field = saveWhere; + *where = save; + } else { + where = NULL; + field = "EOL"; + } + return field; +} + +std::string +CoinReadGetCommand(int argc, const char *argv[]) +{ + std::string field = "EOL"; + // say no = + afterEquals = ""; + while (field == "EOL") { + if (CbcOrClpRead_mode > 0) { + if ((CbcOrClpRead_mode < argc && argv[CbcOrClpRead_mode]) || + CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + field = argv[CbcOrClpRead_mode++]; + } else { + if (fillEnv()) { + field = line; + } else { + // not there + continue; + } + } + if (field == "-") { + std::cout << "Switching to line mode" << std::endl; + CbcOrClpRead_mode = -1; + field = CoinReadNextField(); + } else if (field[0] != '-') { + if (CbcOrClpRead_mode != 2) { + // now allow std::cout<<"skipping non-command "<<field<<std::endl; + // field="EOL"; // skip + } else if (CbcOrClpEnvironmentIndex < 0) { + // special dispensation - taken as -import name + CbcOrClpRead_mode--; + field = "import"; + } + } else { + if (field != "--") { + // take off - + field = field.substr(1); + } else { + // special dispensation - taken as -import -- + CbcOrClpRead_mode--; + field = "import"; + } + } + } else { + field = ""; + } + } else { + field = CoinReadNextField(); + } + } + // if = then modify and save + std::string::size_type found = field.find('='); + if (found != std::string::npos) { + afterEquals = field.substr(found + 1); + field = field.substr(0, found); + } + //std::cout<<field<<std::endl; + return field; +} +std::string +CoinReadGetString(int argc, const char *argv[]) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + if (argv[CbcOrClpRead_mode][0] != '-') { + field = argv[CbcOrClpRead_mode++]; + } else if (!strcmp(argv[CbcOrClpRead_mode], "--")) { + field = argv[CbcOrClpRead_mode++]; + // -- means import from stdin + field = "-"; + } + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + //std::cout<<field<<std::endl; + return field; +} +// valid 0 - okay, 1 bad, 2 not there +int +CoinReadGetIntField(int argc, const char *argv[], int * valid) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + long int value = 0; + //std::cout<<field<<std::endl; + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = strtol(start, &endPointer, 10); + if (*endPointer == '\0') { + *valid = 0; + } else { + *valid = 1; + std::cout << "String of " << field; + } + } else { + *valid = 2; + } + return static_cast<int>(value); +} +double +CoinReadGetDoubleField(int argc, const char *argv[], int * valid) +{ + std::string field = "EOL"; + if (afterEquals == "") { + if (CbcOrClpRead_mode > 0) { + if (CbcOrClpRead_mode < argc || CbcOrClpEnvironmentIndex >= 0) { + if (CbcOrClpEnvironmentIndex < 0) { + // may be negative value so do not check for - + field = argv[CbcOrClpRead_mode++]; + } else { + fillEnv(); + field = line; + } + } + } else { + field = CoinReadNextField(); + } + } else { + field = afterEquals; + afterEquals = ""; + } + double value = 0.0; + //std::cout<<field<<std::endl; + if (field != "EOL") { + const char * start = field.c_str(); + char * endPointer = NULL; + // check valid + value = strtod(start, &endPointer); + if (*endPointer == '\0') { + *valid = 0; + } else { + *valid = 1; + std::cout << "String of " << field; + } + } else { + *valid = 2; + } + return value; +} +/* + Subroutine to establish the cbc parameter array. See the description of + class CbcOrClpParam for details. Pulled from C..Main() for clarity. +*/ +void +establishParams (int &numberParameters, CbcOrClpParam *const parameters) +{ + numberParameters = 0; + parameters[numberParameters++] = + CbcOrClpParam("?", "For help", CBC_PARAM_GENERALQUERY, 7, 0); + parameters[numberParameters++] = + CbcOrClpParam("???", "For help", CBC_PARAM_FULLGENERALQUERY, 7, 0); + parameters[numberParameters++] = + CbcOrClpParam("-", "From stdin", + CLP_PARAM_ACTION_STDIN, 3, 0); +#ifdef ABC_INHERIT + parameters[numberParameters++] = + CbcOrClpParam("abc", "Whether to visit Aboca", + "off", CLP_PARAM_STR_ABCWANTED, 7, 0); + parameters[numberParameters-1].append("one"); + parameters[numberParameters-1].append("two"); + parameters[numberParameters-1].append("three"); + parameters[numberParameters-1].append("four"); + parameters[numberParameters-1].append("five"); + parameters[numberParameters-1].append("six"); + parameters[numberParameters-1].append("seven"); + parameters[numberParameters-1].append("eight"); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("decide"); + parameters[numberParameters-1].setFakeKeyWord(10); + parameters[numberParameters-1].setLonghelp + ( + "Decide whether to use A Basic Optimization Code (Accelerated?) \ +and whether to try going parallel!" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("allC!ommands", "Whether to print less used commands", + "no", CLP_PARAM_STR_ALLCOMMANDS); + parameters[numberParameters-1].append("more"); + parameters[numberParameters-1].append("all"); + parameters[numberParameters-1].setLonghelp + ( + "For the sake of your sanity, only the more useful and simple commands \ +are printed out on ?." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("allow!ableGap", "Stop when gap between best possible and \ +best less than this", + 0.0, 1.0e20, CBC_PARAM_DBL_ALLOWABLEGAP); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "If the gap between best solution and best possible solution is less than this \ +then the search will be terminated. Also see ratioGap." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("allS!lack", "Set basis back to all slack and reset solution", + CLP_PARAM_ACTION_ALLSLACK, 3); + parameters[numberParameters-1].setLonghelp + ( + "Mainly useful for tuning purposes. Normally the first dual or primal will be using an all slack \ +basis anyway." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("artif!icialCost", "Costs >= this treated as artificials in feasibility pump", + 0.0, COIN_DBL_MAX, CBC_PARAM_DBL_ARTIFICIALCOST, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise variables with costs >= this are treated as artificials and fixed to lower bound in feasibility pump" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("auto!Scale", "Whether to scale objective, rhs and bounds of problem if they look odd", + "off", CLP_PARAM_STR_AUTOSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If you think you may get odd objective values or large equality rows etc then\ + it may be worth setting this true. It is still experimental and you may prefer\ + to use objective!Scale and rhs!Scale." + ); + parameters[numberParameters++] = + CbcOrClpParam("barr!ier", "Solve using primal dual predictor corrector algorithm", + CLP_PARAM_ACTION_BARRIER); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the current model using the primal dual predictor \ +corrector algorithm. You may want to link in an alternative \ +ordering and factorization. It will also solve models \ +with quadratic objectives." + + ); + parameters[numberParameters++] = + CbcOrClpParam("basisI!n", "Import basis from bas file", + CLP_PARAM_ACTION_BASISIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format basis file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libz then it can read compressed\ + files 'xxxxxxxx.gz' or xxxxxxxx.bz2." + ); + parameters[numberParameters++] = + CbcOrClpParam("basisO!ut", "Export basis as bas file", + CLP_PARAM_ACTION_BASISOUT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format basis file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.bas'." + ); + parameters[numberParameters++] = + CbcOrClpParam("biasLU", "Whether factorization biased towards U", + "UU", CLP_PARAM_STR_BIASLU, 2, 0); + parameters[numberParameters-1].append("UX"); + parameters[numberParameters-1].append("LX"); + parameters[numberParameters-1].append("LL"); + parameters[numberParameters-1].setCurrentOption("LX"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("branch!AndCut", "Do Branch and Cut", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "This does branch and cut. There are many parameters which can affect the performance. \ +First just try with default settings and look carefully at the log file. Did cuts help? Did they take too long? \ +Look at output to see which cuts were effective and then do some tuning. You will see that the \ +options for cuts are off, on, root and ifmove, forceon. Off is \ +obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \ +'depth'). Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \ +look as if they are doing some good and moving the objective value. Forceon is same as on but forces code to use \ +cut generator at every node. For probing forceonbut just does fixing probing in tree - not strengthening etc. \ +If pre-processing reduced the size of the \ +problem or strengthened many coefficients then it is probably wise to leave it on. Switch off heuristics \ +which did not provide solutions. The other major area to look at is the search. Hopefully good solutions \ +were obtained fairly early in the search so the important point is to select the best variable to branch on. \ +See whether strong branching did a good job - or did it just take a lot of iterations. Adjust the strongBranching \ +and trustPseudoCosts parameters. If cuts did a good job, then you may wish to \ +have more rounds of cuts - see passC!uts and passT!ree." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("bscale", "Whether to scale in barrier (and ordering speed)", + "off", CLP_PARAM_STR_BARRIERSCALE, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("off1"); + parameters[numberParameters-1].append("on1"); + parameters[numberParameters-1].append("off2"); + parameters[numberParameters-1].append("on2"); + parameters[numberParameters++] = + CbcOrClpParam("chol!esky", "Which cholesky algorithm", + "native", CLP_PARAM_STR_CHOLESKY, 7); + parameters[numberParameters-1].append("dense"); + //#ifdef FOREIGN_BARRIER +#ifdef COIN_HAS_WSMP + parameters[numberParameters-1].append("fudge!Long"); + parameters[numberParameters-1].append("wssmp"); +#else + parameters[numberParameters-1].append("fudge!Long_dummy"); + parameters[numberParameters-1].append("wssmp_dummy"); +#endif +#if defined(COIN_HAS_AMD) || defined(COIN_HAS_CHOLMOD) || defined(COIN_HAS_GLPK) + parameters[numberParameters-1].append("Uni!versityOfFlorida"); +#else + parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy"); +#endif +#ifdef TAUCS_BARRIER + parameters[numberParameters-1].append("Taucs"); +#else + parameters[numberParameters-1].append("Taucs_dummy"); +#endif +#ifdef COIN_HAS_MUMPS + parameters[numberParameters-1].append("Mumps"); +#else + parameters[numberParameters-1].append("Mumps_dummy"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "For a barrier code to be effective it needs a good Cholesky ordering and factorization. \ +The native ordering and factorization is not state of the art, although acceptable. \ +You may want to link in one from another source. See Makefile.locations for some \ +possibilities." + ); + //#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("clique!Cuts", "Whether to use Clique cuts", + "off", CBC_PARAM_STR_CLIQUECUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on clique cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("combine!Solutions", "Whether to use combine solution heuristic", + "off", CBC_PARAM_STR_COMBINE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("onquick"); + parameters[numberParameters-1].append("bothquick"); + parameters[numberParameters-1].append("beforequick"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by just \ +using variables which have appeared in one or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("combine2!Solutions", "Whether to use crossover solution heuristic", + "off", CBC_PARAM_STR_CROSSOVER2); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which does branch and cut on the problem given by \ +fixing variables which have same value in two or more solutions. \ +It obviously only tries after two or more solutions. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("constraint!fromCutoff", "Whether to use cutoff as constraint", + "off", CBC_PARAM_STR_CUTOFF_CONSTRAINT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("variable"); + parameters[numberParameters-1].append("forcevariable"); + parameters[numberParameters-1].append("conflict"); + parameters[numberParameters-1].setLonghelp + ( + "This adds the objective as a constraint with best solution as RHS" + ); + parameters[numberParameters++] = + CbcOrClpParam("cost!Strategy", "How to use costs as priorities", + "off", CBC_PARAM_STR_COSTSTRATEGY); + parameters[numberParameters-1].append("pri!orities"); + parameters[numberParameters-1].append("column!Order?"); + parameters[numberParameters-1].append("01f!irst?"); + parameters[numberParameters-1].append("01l!ast?"); + parameters[numberParameters-1].append("length!?"); + parameters[numberParameters-1].append("singletons"); + parameters[numberParameters-1].append("nonzero"); + parameters[numberParameters-1].append("general!Force?"); + parameters[numberParameters-1].setLonghelp + ( + "This orders the variables in order of their absolute costs - with largest cost ones being branched on \ +first. This primitive strategy can be surprsingly effective. The column order\ + option is obviously not on costs but easy to code here." + ); + parameters[numberParameters++] = + CbcOrClpParam("cplex!Use", "Whether to use Cplex!", + "off", CBC_PARAM_STR_CPX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + " If the user has Cplex, but wants to use some of Cbc's heuristics \ +then you can! If this is on, then Cbc will get to the root node and then \ +hand over to Cplex. If heuristics find a solution this can be significantly \ +quicker. You will probably want to switch off Cbc's cuts as Cplex thinks \ +they are genuine constraints. It is also probable that you want to switch \ +off preprocessing, although for difficult problems it is worth trying \ +both." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("cpp!Generate", "Generates C++ code", + -1, 50000, CLP_PARAM_INT_CPP, 1); + parameters[numberParameters-1].setLonghelp + ( + "Once you like what the stand-alone solver does then this allows \ +you to generate user_driver.cpp which approximates the code. \ +0 gives simplest driver, 1 generates saves and restores, 2 \ +generates saves and restores even for variables at default value. \ +4 bit in cbc generates size dependent code rather than computed values. \ +This is now deprecated as you can call stand-alone solver - see \ +Cbc/examples/driver4.cpp." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("crash", "Whether to create basis for problem", + "off", CLP_PARAM_STR_CRASH); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("so!low_halim"); + parameters[numberParameters-1].append("lots"); +#ifdef CLP_INHERIT_MODE + parameters[numberParameters-1].append("dual"); + parameters[numberParameters-1].append("dw"); + parameters[numberParameters-1].append("idiot"); +#else + parameters[numberParameters-1].append("idiot1"); + parameters[numberParameters-1].append("idiot2"); + parameters[numberParameters-1].append("idiot3"); + parameters[numberParameters-1].append("idiot4"); + parameters[numberParameters-1].append("idiot5"); + parameters[numberParameters-1].append("idiot6"); + parameters[numberParameters-1].append("idiot7"); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If crash is set on and there is an all slack basis then Clp will flip or put structural\ + variables into basis with the aim of getting dual feasible. On the whole dual seems to be\ + better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \ +I have also added a variant due to Solow and Halim which is as on but just flip."); + parameters[numberParameters++] = + CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier", + "on", CLP_PARAM_STR_CROSSOVER); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("maybe"); + parameters[numberParameters-1].append("presolve"); + parameters[numberParameters-1].setLonghelp + ( + "Interior point algorithms do not obtain a basic solution (and \ +the feasibility criterion is a bit suspect (JJF)). This option will crossover \ +to a basic solution suitable for ranging or branch and cut. With the current state \ +of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \ +presolve as well) - the option maybe does this." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("csv!Statistics", "Create one line of statistics", + CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1); + parameters[numberParameters-1].setLonghelp + ( + "This appends statistics to given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. Adds header if file empty or does not exist." + ); + parameters[numberParameters++] = + CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts", + -1, 999999, CBC_PARAM_INT_CUTDEPTH); + parameters[numberParameters-1].setLonghelp + ( + "Cut generators may be - off, on only at root, on if they look possible \ +and on. If they are done every node then that is that, but it may be worth doing them \ +every so often. The original method was every so many nodes but it is more logical \ +to do it whenever depth in tree is a multiple of K. This option does that and defaults \ +to -1 (off -> code decides)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cutL!ength", "Length of a cut", + -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH); + parameters[numberParameters-1].setLonghelp + ( + "At present this only applies to Gomory cuts. -1 (default) leaves as is. \ +Any value >0 says that all cuts <= this length can be generated both at \ +root node and in tree. 0 says to use some dynamic lengths. If value >=10,000,000 \ +then the length in tree is value%10000000 - so 10000100 means unlimited length \ +at root and 100 in tree." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("cuto!ff", "All solutions must be better than this", + -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF); + parameters[numberParameters-1].setDoubleValue(1.0e50); + parameters[numberParameters-1].setLonghelp + ( + "All solutions must be better than this value (in a minimization sense). \ +This is also set by code whenever it obtains a solution and is set to value of \ +objective for solution minus cutoff increment." + ); + parameters[numberParameters++] = + CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off", + "off", CBC_PARAM_STR_CUTSSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all cuts (apart from Reduce and Split). Then you can do \ +individual ones off or on \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("debug!In", "read valid solution from file", + CLP_PARAM_ACTION_DEBUG, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will read a solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set.\n\n\ +If set to create it will create a file called debug.file after search.\n\n\ +The idea is that if you suspect a bad cut generator \ +you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \ +re-run with debug set to 'debug.file' The create case has same effect as saveSolution." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("decomp!ose", "Whether to try decomposition", + -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1); + parameters[numberParameters-1].setLonghelp + ( + "0 - off, 1 choose blocks >1 use as blocks \ +Dantzig Wolfe if primal, Benders if dual \ +- uses sprint pass for number of passes" + ); + parameters[numberParameters-1].setIntValue(0); +#if CLP_MULTIPLE_FACTORIZATIONS >0 + parameters[numberParameters++] = + CbcOrClpParam("dense!Threshold", "Whether to use dense factorization", + -1, 10000, CBC_PARAM_INT_DENSE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use dense factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "Rather a complicated parameter but can be useful. -1 means off for large problems but on as if -12 for problems where rows+columns<500, -2 \ +means use Cplex if it is linked in. Otherwise if negative then go into depth first complete search fast branch and bound when depth>= -value-2 (so -3 will use this at depth>=1). This mode is only switched on after 500 nodes. If you really want to switch it off for small problems then set this to -999. If >=0 the value doesn't matter very much. The code will do approximately 100 nodes of fast branch and bound every now and then at depth>=5. The actual logic is too twisted to describe here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dextra3", "Extra double parameter 3", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra4", "Extra double parameter 4", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("dextra5", "Extra double parameter 5", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters++] = + CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search", + "off", CBC_PARAM_STR_DINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Distance induced neighborhood Search. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("direction", "Minimize or Maximize", + "min!imize", CLP_PARAM_STR_DIRECTION); + parameters[numberParameters-1].append("max!imize"); + parameters[numberParameters-1].append("zero"); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'direction maximize' for maximization.\n\ +You can also use the parameters 'maximize' or 'minimize'." + ); + parameters[numberParameters++] = + CbcOrClpParam("directory", "Set Default directory for import etc.", + CLP_PARAM_ACTION_DIRECTORY); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory which import, export, saveModel, restoreModel etc will use.\ + It is initialized to './'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.", + CLP_PARAM_ACTION_DIRSAMPLE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the COIN-OR sample problems reside. It is\ + used only when -unitTest is passed to clp. clp will pick up the test problems\ + from this directory.\ + It is initialized to '../../Data/Sample'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.", + CLP_PARAM_ACTION_DIRNETLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the netlib problems reside. One can get\ + the netlib problems from COIN-OR or from the main netlib site. This\ + parameter is used only when -netlib is passed to clp. clp will pick up the\ + netlib problems from this directory. If clp is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/Netlib'" + ); + parameters[numberParameters++] = + CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.", + CBC_PARAM_ACTION_DIRMIPLIB, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This sets the directory where the miplib 2003 problems reside. One can\ + get the miplib problems from COIN-OR or from the main miplib site. This\ + parameter is used only when -miplib is passed to cbc. cbc will pick up the\ + miplib problems from this directory. If cbc is built without zlib support\ + then the problems must be uncompressed.\ + It is initialized to '../../Data/miplib3'" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("diveO!pt", "Diving options", + -1, 200000, CBC_PARAM_INT_DIVEOPT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >2 && <20 then modify diving options - \ + \n\t3 only at root and if no solution, \ + \n\t4 only at root and if this heuristic has not got solution, \ + \n\t5 decay only if no solution, \ + \n\t6 if depth <3 or decay, \ + \n\t7 run up to 2 times if solution found 4 otherwise, \ + \n\t>10 All only at root (DivingC normal as value-10), \ + \n\t>20 All with value-20)." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("diveS!olves", "Diving solve option", + -1, 200000, CBC_PARAM_INT_DIVEOPTSOLVES, 1); + parameters[numberParameters-1].setLonghelp + ( + "If >0 then do up to this many solves. Last digit is ignored \ +and used for extra options - \ + \n\t1-3 allow fixing of satisfied integers (but not at bound) \ + \n\t1 switch off above for that dive if goes infeasible \ + \n\t2 switch off above permanently if goes infeasible" + ); + parameters[numberParameters-1].setIntValue(100); + parameters[numberParameters++] = + CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics", + "off", CBC_PARAM_STR_DIVINGS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a random diving heuristic at various times. \ +C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \ +You may prefer to use individual on/off \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient", + "off", CBC_PARAM_STR_DIVINGC); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional", + "off", CBC_PARAM_STR_DIVINGF); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided", + "off", CBC_PARAM_STR_DIVINGG); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch", + "off", CBC_PARAM_STR_DIVINGL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost", + "off", CBC_PARAM_STR_DIVINGP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength", + "off", CBC_PARAM_STR_DIVINGV); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters++] = + CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing", + CBC_PARAM_ACTION_DOHEURISTIC, 3); + parameters[numberParameters-1].setLonghelp + ( + "Normally heuristics are done in branch and bound. It may be useful to do them outside. \ +Only those heuristics with 'both' or 'before' set will run. \ +Doing this may also set cutoff, which can help with preprocessing." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \ +gap between bounds exceeds this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND); + parameters[numberParameters-1].setLonghelp + ( + "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. If a problem has both upper and\ + lower bounds then it is trivial to get dual feasible by setting non basic variables\ + to correct bound. If the gap between the upper and lower bounds of a variable is more\ + than the value of dualBound Clp introduces fake bounds so that it can make the problem\ + dual feasible. This has the same effect as a composite objective function in the\ + primal algorithm. Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the bounds. OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualize", "Solves dual reformulation", + 0, 4, CLP_PARAM_INT_DUALIZE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Don't even think about it." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("partial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Steepest is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while automatic decides at each iteration based on information\ + about the factorization." + ); + parameters[numberParameters++] = + CbcOrClpParam("dualS!implex", "Do dual simplex algorithm", + CLP_PARAM_ACTION_DUALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\ +The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by dual pivot method, fake bound on variables and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("dualT!olerance", "For an optimal solution \ +no dual infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a dual run seems to be having a hard time. One method which can be faster is \ +to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \ +correct tolerance (remembering to switch off presolve for this final short clean up phase)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic", + "off", CBC_PARAM_STR_DW); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "See Rounding for meaning of on,both,before" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\ + based on a dubious analysis of model." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("end", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops execution ; end, exit, quit and stop are synonyms" + ); + parameters[numberParameters++] = + CbcOrClpParam("environ!ment", "Read commands from environment", + CLP_PARAM_ACTION_ENVIRONMENT, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "This starts reading from environment variable CBC_CLP_ENVIRONMENT." + ); + parameters[numberParameters++] = + CbcOrClpParam("error!sAllowed", "Whether to allow import errors", + "off", CLP_PARAM_STR_ERRORSALLOWED, 3); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "The default is not to use any model which had errors when reading the mps file.\ + Setting this to 'on' will allow all errors from which the code can recover\ + simply by ignoring the error. There are some errors from which the code can not recover \ +e.g. no ENDATA. This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("exit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("exper!iment", "Whether to use testing features", + -1, 200, CBC_PARAM_INT_EXPERIMENT, 0); + parameters[numberParameters-1].setLonghelp + ( + "Defines how adventurous you want to be in using new ideas. \ +0 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!" + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0); + parameters[numberParameters-1].setLonghelp + ( + "Strategy for extra strong branching \n\ +\n\t0 - normal\n\ +\n\twhen to do all fractional\n\ +\n\t1 - root node\n\ +\n\t2 - depth less than modifier\n\ +\n\t4 - if objective == best possible\n\ +\n\t6 - as 2+4\n\ +\n\twhen to do all including satisfied\n\ +\n\t10 - root node etc.\n\ +\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)" + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("export", "Export model as mps file", + CLP_PARAM_ACTION_EXPORT); + parameters[numberParameters-1].setLonghelp + ( + "This will write an MPS format file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.mps'. \ +It can be useful to get rid of the original names and go over to using Rnnnnnnn and Cnnnnnnn. This can be done by setting 'keepnames' off before importing mps file." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("extra1", "Extra integer parameter 1", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra2", "Extra integer parameter 2", + -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra3", "Extra integer parameter 3", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("extra4", "Extra integer parameter 4", + -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on yet more special options!! \ +The bottom digit is a strategy when to used shadow price stuff e.g. 3 \ +means use until a solution is found. The next two digits say what sort \ +of dual information to use. After that it goes back to powers of 2 so -\n\ +\n\t1000 - switches on experimental hotstart\n\ +\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\ +\n\t8000 - increase minimum drop gradually\n\ +\n\t16000 - switches on alternate gomory criterion" + ); + parameters[numberParameters++] = + CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "This switches on creation of extra integer variables \ +to gather all variables with same cost." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("fact!orization", "Which factorization to use", + "normal", CLP_PARAM_STR_FACTORIZATION); + parameters[numberParameters-1].append("dense"); + parameters[numberParameters-1].append("simple"); + parameters[numberParameters-1].append("osl"); + parameters[numberParameters-1].setLonghelp + ( +#ifndef ABC_INHERIT + "The default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems." +#else + "Normally the default is to use the normal CoinFactorization, but \ +other choices are a dense one, osl's or one designed for small problems. \ +However if at Aboca then the default is CoinAbcFactorization and other choices are \ +a dense one, one designed for small problems or if enabled a long factorization." +#endif + ); + parameters[numberParameters++] = + CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG", + 1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump", + "off", CBC_PARAM_STR_FPUMP); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \ +and uses a sequence of Lps to try and get an integer feasible solution. \ +Some fine tuning is available by passFeasibilityPump and also pumpTune. \ +See Rounding for meaning of on,both,before" + ); + parameters[numberParameters++] = + CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \ +reduced costs greater than this", + -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1); + parameters[numberParameters-1].setLonghelp + ( + "If this is set integer variables with reduced costs greater than this will be fixed \ +before branch and bound - use with extreme caution!" + ); + parameters[numberParameters++] = + CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts", + "off", CBC_PARAM_STR_FLOWCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setFakeKeyWord(3); + parameters[numberParameters-1].setLonghelp + ( + "This switches on flow cover cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +Can also enter testing values by plusnn (==ifmove)" + ); + parameters[numberParameters++] = + CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB", + -1, 20000000, CLP_PARAM_INT_USESOLUTION); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters-1].setLonghelp + ( + "-1 off. If 1 then tries to branch to solution given by AMPL or priorities file. \ +If 0 then just tries to set as best solution \ +If >1 then also does that many nodes on fixed problem." + ); + parameters[numberParameters++] = + CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump", + 1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1); + parameters[numberParameters-1].setDoubleValue(0.5); + parameters[numberParameters-1].setLonghelp + ( + "After a pass in feasibility pump, variables which have not moved \ +about are fixed and if the preprocessed model is small enough a few nodes \ +of branch and bound are done on reduced problem. Small problem has to be less than this fraction of original." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier", + "off", CLP_PARAM_STR_GAMMA, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("gamma"); + parameters[numberParameters-1].append("delta"); + parameters[numberParameters-1].append("onstrong"); + parameters[numberParameters-1].append("gammastrong"); + parameters[numberParameters-1].append("deltastrong"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts", + "off", CBC_PARAM_STR_GMICUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].append("longroot"); + parameters[numberParameters-1].append("longifmove"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("longendonly"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on an alternative Gomory cut generator (either at root or in entire tree) \ +This version is by Giacomo Nannicini and may be more robust \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts", + "off", CBC_PARAM_STR_GOMORYCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].append("long"); + parameters[numberParameters-1].setLonghelp + ( + "The original cuts - beware of imitations! Having gone out of favor, they are now more \ +fashionable as LP solvers are more robust and they interact well with other cuts. They will almost always \ +give cuts (although in this executable they are limited as to number of variables in cut). \ +However the cuts may be dense so it is worth experimenting (Long allows any length). \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic", + "off", CBC_PARAM_STR_GREEDY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + //parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].setLonghelp + ( + "Switches on a greedy heuristic which will try and obtain a solution. It may just fix a \ +percentage of variables and then try a small branch and cut run. \ +See Rounding for meaning of on,both,before" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("gsolu!tion", "Puts glpk solution to file", + CLP_PARAM_ACTION_GMPL_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "Will write a glpk solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout' (this defaults to ordinary solution if stdout). \ +If problem created from gmpl model - will do any reports." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off", + "off", CBC_PARAM_STR_HEURISTICSTRATEGY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This can be used to switch on or off all heuristics. Then you can do \ +individual ones off or on. CbcTreeLocal is not included as it dramatically \ +alters search." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("help", "Print out version, non-standard options and some help", + CLP_PARAM_ACTION_HELP, 3); + parameters[numberParameters-1].setLonghelp + ( + "This prints out some help to get user started. If you have printed this then \ +you should be past that stage:-)" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("hOp!tions", "Heuristic options", + -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1); + parameters[numberParameters-1].setLonghelp + ( + "1 says stop heuristic immediately allowable gap reached. \ +Others are for feasibility pump - \ +2 says do exact number of passes given, \ +4 only applies if initial cutoff given and says relax after 50 passes, \ +while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start", + 0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("idiot!Crash", "Whether to try idiot crash", + -1, 99999999, CLP_PARAM_INT_IDIOT); + parameters[numberParameters-1].setLonghelp + ( + "This is a type of 'crash' which works well on some homogeneous problems.\ + It works best on problems with unit elements and rhs but will do something to any model. It should only be\ + used before primal. It can be set to -1 when the code decides for itself whether to use it,\ + 0 to switch off or n > 0 to do n passes." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("import", "Import model from mps file", + CLP_PARAM_ACTION_IMPORT, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read an MPS format file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. If you have libgz then it can read compressed\ + files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'. \ +If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("inc!rement", "A valid solution must be at least this \ +much better than last integer solution", + -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT); + parameters[numberParameters-1].setLonghelp + ( + "Whenever a solution is found the bound on solutions is set to solution (in a minimization\ +sense) plus this. If it is not set then the code will try and work one out e.g. if \ +all objective coefficients are multiples of 0.01 and only integer variables have entries in \ +objective then this can be set to 0.01. Be careful if you set this negative!" + ); + parameters[numberParameters++] = + CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \ +to cost this much", + 0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1); + parameters[numberParameters-1].setLonghelp + ( + "A primitive way of deciding which node to explore next. Satisfying each integer infeasibility is \ +expected to cost this much." + ); + parameters[numberParameters++] = + CbcOrClpParam("initialS!olve", "Solve to continuous", + CLP_PARAM_ACTION_SOLVECONTINUOUS); + parameters[numberParameters-1].setLonghelp + ( + "This just solves the problem to continuous - without adding any cuts" + ); + parameters[numberParameters++] = + CbcOrClpParam("integerT!olerance", "For an optimal solution \ +no integer variable may be this away from an integer value", + 1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Beware of setting this smaller than the primal tolerance." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("keepN!ames", "Whether to keep names from import", + "on", CLP_PARAM_STR_KEEPNAMES); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "It saves space to get rid of names so if you need to you can set this to off. \ +This needs to be set before the import of model - so -keepnames off -import xxxxx.mps." + ); + parameters[numberParameters++] = + CbcOrClpParam("KKT", "Whether to use KKT factorization", + "off", CLP_PARAM_STR_KKT, 7, 1); + parameters[numberParameters-1].append("on"); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts", + "off", CBC_PARAM_STR_KNAPSACKCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on knapsack cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts", + "off", CBC_PARAM_STR_LAGOMORYCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].append("onlyaswellroot"); + parameters[numberParameters-1].append("cleanaswellroot"); + parameters[numberParameters-1].append("bothaswellroot"); + parameters[numberParameters-1].setLonghelp + ( + "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \ +by Matteo Fischetti & Domenico Salvagnin. This simplification \ +just uses original constraints while modifying objective using other cuts. \ +So you don't use messy constraints generated by Gomory etc. \ +A variant is to allow non messy cuts e.g. clique cuts. \ +So 'only' does this while clean also allows integral valued cuts. \ +'End' is recommended which waits until other cuts have finished and then \ +does a few passes. \ +The length options for gomory cuts are used." + ); + parameters[numberParameters++] = + CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts", + "off", CBC_PARAM_STR_LATWOMIRCUTS); + parameters[numberParameters-1].append("endonlyroot"); + parameters[numberParameters-1].append("endcleanroot"); + parameters[numberParameters-1].append("endbothroot"); + parameters[numberParameters-1].append("endonly"); + parameters[numberParameters-1].append("endclean"); + parameters[numberParameters-1].append("endboth"); + parameters[numberParameters-1].append("onlyaswell"); + parameters[numberParameters-1].append("cleanaswell"); + parameters[numberParameters-1].append("bothaswell"); + parameters[numberParameters-1].append("onlyinstead"); + parameters[numberParameters-1].append("cleaninstead"); + parameters[numberParameters-1].append("bothinstead"); + parameters[numberParameters-1].setLonghelp + ( + "This is a lagrangean relaxation for TwoMir cuts. See \ +lagomoryCuts for description of options." + ); + parameters[numberParameters++] = + CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts", + "off", CBC_PARAM_STR_LANDPCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Lift and project cuts. \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch", + "off", CBC_PARAM_STR_LOCALTREE); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a local search algorithm when a solution is found. This is from \ +Fischetti and Lodi and is not really a heuristic although it can be used as one. \ +When used from Coin solve it has limited functionality. It is not switched on when \ +heuristics are switched on." + ); +#endif +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Solver output", + -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL); +#else + parameters[numberParameters++] = + CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output", + -63, 63, CLP_PARAM_INT_LOGLEVEL); + parameters[numberParameters-1].setIntValue(1); +#endif + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information." + ); + parameters[numberParameters++] = + CbcOrClpParam("max!imize", "Set optimization direction to maximize", + CLP_PARAM_ACTION_MAXIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +You can also use the parameters 'direction maximize'." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("maxF!actor", "Maximum number of iterations between \ +refactorizations", + 1, 999999, CLP_PARAM_INT_MAXFACTOR); + parameters[numberParameters-1].setLonghelp + ( + "If this is at its initial value of 200 then in this executable clp will guess at a\ + value to use. Otherwise the user can set a value. The code may decide to re-factorize\ + earlier for accuracy." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \ +stopping", + 0, 2147483647, CLP_PARAM_INT_MAXITERATION); + parameters[numberParameters-1].setLonghelp + ( + "This can be used for testing purposes. The corresponding library call\n\ + \tsetMaximumIterations(value)\n can be useful. If the code stops on\ + seconds or by an interrupt this will be treated as stopping on maximum iterations. This is ignored in branchAndCut - use maxN!odes." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("maxN!odes", "Maximum number of nodes to do", + -1, 2147483647, CBC_PARAM_INT_MAXNODES); + parameters[numberParameters-1].setLonghelp + ( + "This is a repeatable way to limit search. Normally using time is easier \ +but then the results may not be repeatable." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save", + 0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS); + parameters[numberParameters-1].setLonghelp + ( + "Number of solutions to save." + ); + parameters[numberParameters++] = + CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get", + 1, 2147483647, CBC_PARAM_INT_MAXSOLS); + parameters[numberParameters-1].setLonghelp + ( + "You may want to stop after (say) two solutions or an hour. \ +This is checked every node in tree, so it is possible to get more solutions from heuristics." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("min!imize", "Set optimization direction to minimize", + CLP_PARAM_ACTION_MINIMIZE, 7); + parameters[numberParameters-1].setLonghelp + ( + "The default is minimize - use 'maximize' for maximization.\n\ +This should only be necessary if you have previously set maximization \ +You can also use the parameters 'direction minimize'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mipO!ptions", "Dubious options for mip", + 0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more!MipOptions", "More dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("more2!MipOptions", "More more dubious options for mip", + -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_MIXEDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed", + "off", CLP_PARAM_STR_MESSAGES); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ("The default behavior is to put out messages such as:\n\ + Clp0005 2261 Objective 109.024 Primal infeas 944413 (758)\n\ +but this program turns this off to make it look more friendly. It can be useful\ + to turn them back on if you want to be able to 'grep' for particular messages or if\ + you intend to override the behavior of a particular message. This only affects Clp not Cbc." + ); + parameters[numberParameters++] = + CbcOrClpParam("miplib", "Do some of miplib test set", + CBC_PARAM_ACTION_MIPLIB, 3, 1); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("mips!tart", "reads an initial feasible solution from file", + CBC_PARAM_ACTION_MIPSTART); + parameters[numberParameters-1].setLonghelp + ("\ +The MIPStart allows one to enter an initial integer feasible solution \ +to CBC. Values of the main decision variables which are active (have \ +non-zero values) in this solution are specified in a text file. The \ +text file format used is the same of the solutions saved by CBC, but \ +not all fields are required to be filled. First line may contain the \ +solution status and will be ignored, remaining lines contain column \ +indexes, names and values as in this example:\n\ +\n\ +Stopped on iterations - objective value 57597.00000000\n\ + 0 x(1,1,2,2) 1 \n\ + 1 x(3,1,3,2) 1 \n\ + 5 v(5,1) 2 \n\ + 33 x(8,1,5,2) 1 \n\ + ...\n\ +\n\ +Column indexes are also ignored since pre-processing can change them. \ +There is no need to include values for continuous or integer auxiliary \ +variables, since they can be computed based on main decision variables. \ +Starting CBC with an integer feasible solution can dramatically improve \ +its performance: several MIP heuristics (e.g. RINS) rely on having at \ +least one feasible solution available and can start immediately if the \ +user provides one. Feasibility Pump (FP) is a heuristic which tries to \ +overcome the problem of taking too long to find feasible solution (or \ +not finding at all), but it not always succeeds. If you provide one \ +starting solution you will probably save some time by disabling FP. \ +\n\n\ +Knowledge specific to your problem can be considered to write an \ +external module to quickly produce an initial feasible solution - some \ +alternatives are the implementation of simple greedy heuristics or the \ +solution (by CBC for example) of a simpler model created just to find \ +a feasible solution. \ +\n\n\ +Question and suggestions regarding MIPStart can be directed to\n\ +haroldo.santos@gmail.com.\ +"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "Yet more ideas for Feasibility Pump \n\ +\t/100000 == 1 use box constraints and original obj in cleanup\n\ +\t/1000 == 1 Pump will run twice if no solution found\n\ +\t/1000 == 2 Pump will only run after root cuts if no solution found\n\ +\t/1000 >10 as above but even if solution found\n\ +\t/100 == 1,3.. exact 1.0 for objective values\n\ +\t/100 == 2,3.. allow more iterations per pass\n\ +\t n fix if value of variable same for last n iterations." + ); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters++] = + CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions", + 0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "Do (in parallel if threads enabled) the root phase this number of times \ + and collect all solutions and cuts generated. The actual format is aabbcc \ +where aa is number of extra passes, if bb is non zero \ +then it is number of threads to use (otherwise uses threads setting) and \ +cc is number of times to do root phase. Yet another one from the Italian idea factory \ +(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \ +and Andrea Tramontani). \ +The solvers do not interact with each other. However if extra passes are specified \ +then cuts are collected and used in later passes - so there is interaction there." + ); + parameters[numberParameters++] = + CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic", + "off", CBC_PARAM_STR_NAIVE, 7, 1); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "Really silly stuff e.g. fix all integers with costs to zero!. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("netlib", "Solve entire netlib test set", + CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier", + CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using barrier.\ +The user can set options before e.g. clp -kkt on -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)", + CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using dual.\ +The user can set options before e.g. clp -presolve off -netlib" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)", + CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using primal.\ +The user can set options before e.g. clp -presolve off -netlibp" + ); + parameters[numberParameters++] = + CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm", + CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp and then solves the netlib test set using whatever \ +works best. I know this is cheating but it also stresses the code better by doing a \ +mixture of stuff. The best algorithm was chosen on a Linux ThinkPad using native cholesky \ +with University of Florida ordering." + ); + parameters[numberParameters++] = + CbcOrClpParam("network", "Tries to make network matrix", + CLP_PARAM_ACTION_NETWORK, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go faster if the matrix can be converted to a network. The matrix\ + operations may be a bit faster with more efficient storage, but the main advantage\ + comes from using a network factorization. It will probably not be as fast as a \ +specialized network code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file", + CLP_PARAM_ACTION_NEXTBESTSOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "To write best solution, just use solution. This prints next best (if exists) \ + and then deletes it. \ + This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); + parameters[numberParameters++] = + CbcOrClpParam("node!Strategy", "What strategy to use to select nodes", + "hybrid", CBC_PARAM_STR_NODESTRATEGY); + parameters[numberParameters-1].append("fewest"); + parameters[numberParameters-1].append("depth"); + parameters[numberParameters-1].append("upfewest"); + parameters[numberParameters-1].append("downfewest"); + parameters[numberParameters-1].append("updepth"); + parameters[numberParameters-1].append("downdepth"); + parameters[numberParameters-1].setLonghelp + ( + "Normally before a solution the code will choose node with fewest infeasibilities. \ +You can choose depth as the criterion. You can also say if up or down branch must \ +be done first (the up down choice will carry on after solution). \ +Default has now been changed to hybrid which is breadth first on small depth nodes then fewest." + ); + parameters[numberParameters++] = + CbcOrClpParam("numberA!nalyze", "Number of analysis iterations", + -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0); + parameters[numberParameters-1].setLonghelp + ( + "This says how many iterations to spend at root node analyzing problem. \ +This is a first try and will hopefully become more sophisticated." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("objective!Scale", "Scale factor to apply to objective", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If the objective function has some very large values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. It is applied after scaling. You are unlikely to need this." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC +#ifdef COIN_HAS_NTY + parameters[numberParameters++] = + CbcOrClpParam("Orbit!alBranching", "Whether to try orbital branching", + "off", CBC_PARAM_STR_ORBITAL); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("strong"); + parameters[numberParameters-1].append("force"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Orbital branching. \ +On just adds orbital, strong tries extra fixing in strong branching"); +#endif + parameters[numberParameters++] = + CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model", + CLP_PARAM_ACTION_OUTDUPROWS, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("output!Format", "Which output format to use", + 1, 6, CLP_PARAM_INT_OUTPUTFORMAT); + parameters[numberParameters-1].setLonghelp + ( + "Normally export will be done using normal representation for numbers and two values\ + per line. You may want to do just one per line (for grep or suchlike) and you may wish\ + to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\ + otherwise odd values gives one value per line, even two. Values 1,2 give normal format, 3,4\ + gives greater precision, while 5,6 give IEEE values. When used for exporting a basis 1 does not save \ +values, 2 saves values, 3 with greater accuracy and 4 in IEEE." + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("para!metrics", "Import data from file and do parametrics", + CLP_PARAM_ACTION_PARAMETRICS, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with parametric data from the given file name \ +and then do parametrics. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in modified csv format - a line ROWS will be followed by rows data \ +while a line COLUMNS will be followed by column data. The last line \ +should be ENDATA. The ROWS line must exist and is in the format \ +ROWS, inital theta, final theta, interval theta, n where n is 0 to get \ +CLPI0062 message at interval or at each change of theta \ +and 1 to get CLPI0063 message at each iteration. If interval theta is 0.0 \ +or >= final theta then no interval reporting. n may be missed out when it is \ +taken as 0. If there is Row data then \ +there is a headings line with allowed headings - name, number, \ +lower(rhs change), upper(rhs change), rhs(change). Either the lower and upper \ +fields should be given or the rhs field. \ +The optional COLUMNS line is followed by a headings line with allowed \ +headings - name, number, objective(change), lower(change), upper(change). \ + Exactly one of name and number must be given for either section and \ +missing ones have value 0.0." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passC!uts", "Number of cut passes at root node", + -9999999, 9999999, CBC_PARAM_INT_CUTPASS); + parameters[numberParameters-1].setLonghelp + ( + "The default is 100 passes if less than 500 columns, 100 passes (but \ +stop if drop small if less than 5000 columns, 20 otherwise" + ); + parameters[numberParameters++] = + CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump", + 0, 10000, CBC_PARAM_INT_FPUMPITS); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump by doing more or fewer passes." + ); + parameters[numberParameters-1].setIntValue(20); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("passP!resolve", "How many passes in presolve", + -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve does 10 passes but you may want to do less to make it\ + more lightweight or do more if improvements are still being made. As Presolve will return\ + if nothing is being taken out, you should not normally need to use this fine tuning." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree", + -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE); + parameters[numberParameters-1].setLonghelp + ( + "The default is one pass" + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("pertV!alue", "Method of perturbation", + -5000, 102, CLP_PARAM_INT_PERTVALUE, 1); + parameters[numberParameters++] = + CbcOrClpParam("perturb!ation", "Whether to perturb problem", + "on", CLP_PARAM_STR_PERTURBATION); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].setLonghelp + ( + "Perturbation helps to stop cycling, but Clp uses other measures for this.\ + However large problems and especially ones with unit elements and unit rhs or costs\ + benefit from perturbation. Normally Clp tries to be intelligent, but you can switch this off.\ + The Clp library has this off by default. This program has it on by default." + ); + parameters[numberParameters++] = + CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex", + "off", CLP_PARAM_STR_PFI, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "By default clp uses Forrest-Tomlin L-U update. If you are masochistic you can switch it off." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic", + "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic", + "off", CBC_PARAM_STR_PIVOTANDFIX); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix", + CLP_PARAM_ACTION_PLUSMINUS, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Clp will go slightly faster if the matrix can be converted so that the elements are\ + not stored and are known to be unit. The main advantage is memory use. Clp may automatically\ + see if it can convert the problem so you should not need to use this." + ); + parameters[numberParameters++] = + CbcOrClpParam("pO!ptions", "Dubious print options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1); + parameters[numberParameters-1].setIntValue(0); + parameters[numberParameters-1].setLonghelp + ( + "If this is > 0 then presolve will give more information and branch and cut will give statistics" + ); + parameters[numberParameters++] = + CbcOrClpParam("preO!pt", "Presolve options", + 0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("presolve", "Whether to presolve problem", + "on", CLP_PARAM_STR_PRESOLVE); + parameters[numberParameters-1].append("off"); + parameters[numberParameters-1].append("more"); + parameters[numberParameters-1].append("file"); + parameters[numberParameters-1].setLonghelp + ( + "Presolve analyzes the model to find such things as redundant equations, equations\ + which fix some variables, equations which can be transformed into bounds etc etc. For the\ + initial solve of any problem this is worth doing unless you know that it will have no effect. \ +on will normally do 5 passes while using 'more' will do 10. If the problem is very large you may need \ +to write the original to file using 'file'." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("preprocess", "Whether to use integer preprocessing", + "off", CBC_PARAM_STR_PREPROCESS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("save"); + parameters[numberParameters-1].append("equal"); + parameters[numberParameters-1].append("sos"); + parameters[numberParameters-1].append("trysos"); + parameters[numberParameters-1].append("equalall"); + parameters[numberParameters-1].append("strategy"); + parameters[numberParameters-1].append("aggregate"); + parameters[numberParameters-1].append("forcesos"); + parameters[numberParameters-1].setLonghelp + ( + "This tries to reduce size of model in a similar way to presolve and \ +it also tries to strengthen the model - this can be very useful and is worth trying. \ + Save option saves on file presolved.mps. equal will turn <= cliques into \ +==. sos will create sos sets if all 0-1 in sets (well one extra is allowed) \ +and no overlaps. trysos is same but allows any number extra. equalall will turn all \ +valid inequalities into equalities with integer slacks. strategy is as \ +on but uses CbcStrategy." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("preT!olerance", "Tolerance to use in presolve", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \ +infeasible and you have awkward numbers and you are sure the problem is really feasible." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm", + "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1); + parameters[numberParameters-1].append("exa!ct"); + parameters[numberParameters-1].append("dant!zig"); + parameters[numberParameters-1].append("part!ial"); + parameters[numberParameters-1].append("steep!est"); + parameters[numberParameters-1].append("change"); + parameters[numberParameters-1].append("sprint"); + parameters[numberParameters-1].setLonghelp + ( + "Clp can use any pivot selection algorithm which the user codes as long as it\ + implements the features in the abstract pivot base class. The Dantzig method is implemented\ + to show a simple method but its use is deprecated. Exact devex is the method of choice and there\ + are two variants which keep all weights updated but only scan a subset each iteration.\ + Partial switches this on while change initially does dantzig until the factorization\ + becomes denser. This is still a work in progress." + ); + parameters[numberParameters++] = + CbcOrClpParam("primalS!implex", "Do primal simplex algorithm", + CLP_PARAM_ACTION_PRIMALSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "This command solves the continuous relaxation of the current model using the primal algorithm.\ + The default is to use exact devex.\ + The time and iterations may be affected by settings such as presolve, scaling, crash\ + and also by column selection method, infeasibility weight and dual and primal tolerances." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("primalT!olerance", "For an optimal solution \ +no primal infeasibility may exceed this value", + 1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "Normally the default tolerance is fine, but you may want to increase it a\ + bit if a primal run seems to be having a hard time" + ); +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \ +costs this much to be infeasible", + 1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT); + parameters[numberParameters-1].setLonghelp + ( + "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\ + algorithm where you first get feasible then optimal. So Clp is minimizing this weight times\ + the sum of primal infeasibilities plus the true objective function (in minimization sense).\ + Too high a value may mean more iterations, while too low a bound means\ + the code may go all the way and then have to increase the weight in order to get feasible.\ + OSL had a heuristic to\ + adjust bounds, maybe we need that here." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("printi!ngOptions", "Print options", + "normal", CLP_PARAM_STR_INTPRINT, 3); + parameters[numberParameters-1].append("integer"); + parameters[numberParameters-1].append("special"); + parameters[numberParameters-1].append("rows"); + parameters[numberParameters-1].append("all"); + parameters[numberParameters-1].append("csv"); + parameters[numberParameters-1].append("bound!ranging"); + parameters[numberParameters-1].append("rhs!ranging"); + parameters[numberParameters-1].append("objective!ranging"); + parameters[numberParameters-1].append("stats"); + parameters[numberParameters-1].append("boundsint"); + parameters[numberParameters-1].append("boundsall"); + parameters[numberParameters-1].setLonghelp + ( + "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\ +integer - nonzero integer column variables\n\ +special - in format suitable for OsiRowCutDebugger\n\ +rows - nonzero column variables and row activities\n\ +all - all column variables and row activities.\n\ +\nFor non-integer problems 'integer' and 'special' act like 'normal'. \ +Also see printMask for controlling output." + ); + parameters[numberParameters++] = + CbcOrClpParam("printM!ask", "Control printing of solution on a mask", + CLP_PARAM_ACTION_PRINTMASK, 3); + parameters[numberParameters-1].setLonghelp + ( + "If set then only those names which match mask are printed in a solution. \ +'?' matches any character and '*' matches any set of characters. \ + The default is '' i.e. unset so all variables are printed. \ +This is only active if model has names." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("prio!rityIn", "Import priorities etc from file", + CBC_PARAM_ACTION_PRIORITYIN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This will read a file with priorities from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to '', i.e. it must be set. This can not read from compressed files. \ +File is in csv format with allowed headings - name, number, priority, direction, up, down, solution. Exactly one of\ + name and number must be given." + ); + parameters[numberParameters++] = + CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts", + "off", CBC_PARAM_STR_PROBINGCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceonglobal"); + parameters[numberParameters-1].append("forceOnBut"); + parameters[numberParameters-1].append("forceOnStrong"); + parameters[numberParameters-1].append("forceOnButStrong"); + parameters[numberParameters-1].append("strongRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on probing cuts (either at root or in entire tree) \ +See branchAndCut for information on options. \ +but strong options do more probing" + ); + parameters[numberParameters++] = + CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic", + "off", CBC_PARAM_STR_PROXIMITY); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("10"); + parameters[numberParameters-1].append("100"); + parameters[numberParameters-1].append("300"); + // but allow numbers after this (returning 1) + parameters[numberParameters-1].setFakeKeyWord(1); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a heuristic which looks for a solution close \ +to incumbent solution (Fischetti and Monaci). \ +See Rounding for meaning of on,both,before. \ +Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))." + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise add a constraint forcing objective below this value\ + in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump", + -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "0.0 off - otherwise use as absolute increment to cutoff \ +when solution found in feasibility pump" + ); + parameters[numberParameters++] = + CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump", + 0, 100000000, CBC_PARAM_INT_FPUMPTUNE); + parameters[numberParameters-1].setLonghelp + ( + "This fine tunes Feasibility Pump \n\ +\t>=10000000 use as objective weight switch\n\ +\t>=1000000 use as accumulate switch\n\ +\t>=1000 use index+1 as number of large loops\n\ +\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\ +\t%100 == 10,20 affects how each solve is done\n\ +\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \ +If accumulate is on then after a major pass, variables which have not moved \ +are fixed and a small branch and bound is tried." + ); + parameters[numberParameters-1].setIntValue(0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("quit", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc", + -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Cbc \ +- 0 says use time of day, -1 is as now." + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic", + "off", CBC_PARAM_STR_RANDROUND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "stuff needed. \ +Doh option does heuristic before preprocessing" ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("randomS!eed", "Random seed for Clp", + 0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED); + parameters[numberParameters-1].setLonghelp + ( + "This sets a random seed for Clp \ +- 0 says use time of day." + ); + parameters[numberParameters-1].setIntValue(1234567); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \ +best less than this fraction of larger of two", + 0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO); + parameters[numberParameters-1].setDoubleValue(0.0); + parameters[numberParameters-1].setLonghelp + ( + "If the gap between best solution and best possible solution is less than this fraction \ +of the objective value at the root node then the search will terminate. See 'allowableGap' for a \ +way of using absolute value rather than fraction." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("restoreS!olution", "reads solution from file", + CLP_PARAM_ACTION_RESTORESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will read a binary solution file from the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. This reads in a file from saveSolution" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("readSt!ored", "Import stored cuts from file", + CLP_PARAM_ACTION_STOREDFILE, 3, 0); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place", + -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0); + parameters[numberParameters-1].setLonghelp + ( + "You can set this to -1.0 to test maximization or other to stress code" + ); + parameters[numberParameters-1].setDoubleValue(1.0); + parameters[numberParameters++] = + CbcOrClpParam("reallyS!cale", "Scales model in place", + CLP_PARAM_ACTION_REALLY_SCALE, 7, 0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts", + "off", CBC_PARAM_STR_REDSPLITCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree). \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +May be slow \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2", + "off", CBC_PARAM_STR_REDSPLIT2CUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("longOn"); + parameters[numberParameters-1].append("longRoot"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on reduce and split cuts (either at root or in entire tree) \ +This version is by Giacomo Nannicini based on Francois Margot's version \ +Standard setting only uses rows in tableau <=256, long uses all \ +See branchAndCut for information on options." + ); + parameters[numberParameters++] = + CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts", + "off", CBC_PARAM_STR_RESIDCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].setLonghelp + ( + "Residual capacity cuts. \ +See branchAndCut for information on options." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("restore!Model", "Restore model from binary file", + CLP_PARAM_ACTION_RESTORE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This reads data save by saveModel from the given file. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("reverse", "Reverses sign of objective", + CLP_PARAM_ACTION_REVERSE, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "Useful for testing if maximization works correctly" + ); + parameters[numberParameters++] = + CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds", + -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0); + parameters[numberParameters-1].setLonghelp + ( + "If the rhs or bounds have some very large meaningful values, you may wish to scale them\ + internally by this amount. It can also be set by autoscale. This should not be needed." + ); + parameters[numberParameters-1].setDoubleValue(1.0); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search", + "off", CBC_PARAM_STR_RENS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("200"); + parameters[numberParameters-1].append("1000"); + parameters[numberParameters-1].append("10000"); + parameters[numberParameters-1].append("dj"); + parameters[numberParameters-1].append("djbefore"); + parameters[numberParameters-1].append("usesolution"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxation enforced neighborhood Search. \ +on just does 50 nodes \ +200 or 1000 does that many nodes. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search", + "off", CBC_PARAM_STR_RINS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("often"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on Relaxed induced neighborhood Search. \ +Doh option does heuristic before preprocessing" ); + parameters[numberParameters++] = + CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic", + "off", CBC_PARAM_STR_ROUNDING); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on a simple (but effective) rounding heuristic at each node of tree. \ +On means do in solve i.e. after preprocessing, \ +Before means do if doHeuristics used, off otherwise, \ +and both means do if doHeuristics and in solve." + ); + +#endif + parameters[numberParameters++] = + CbcOrClpParam("saveM!odel", "Save model to binary file", + CLP_PARAM_ACTION_SAVE, 7, 1); + parameters[numberParameters-1].setLonghelp + ( + "This will save the problem to the given file name for future use\ + by restoreModel. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'default.prob'." + ); + parameters[numberParameters++] = + CbcOrClpParam("saveS!olution", "saves solution to file", + CLP_PARAM_ACTION_SAVESOL); + parameters[numberParameters-1].setLonghelp + ( + "This will write a binary solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'solution.file'. To read the file use fread(int) twice to pick up number of rows \ +and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \ +activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \ +If name contains '_fix_read_' then does not write but reads and will fix all variables" + ); + parameters[numberParameters++] = + CbcOrClpParam("scal!ing", "Whether to scale problem", + "off", CLP_PARAM_STR_SCALING); + parameters[numberParameters-1].append("equi!librium"); + parameters[numberParameters-1].append("geo!metric"); + parameters[numberParameters-1].append("auto!matic"); + parameters[numberParameters-1].append("dynamic"); + parameters[numberParameters-1].append("rows!only"); + parameters[numberParameters-1].setLonghelp + ( + "Scaling can help in solving problems which might otherwise fail because of lack of\ + accuracy. It can also reduce the number of iterations. It is not applied if the range\ + of elements is small. When unscaled it is possible that there may be small primal and/or\ + infeasibilities." + ); + parameters[numberParameters-1].setCurrentOption(3); // say auto +#ifndef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "Maximum seconds", + -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds clp will act as if maximum iterations had been reached \ +(if value >=0)." + ); +#else + parameters[numberParameters++] = + CbcOrClpParam("sec!onds", "maximum seconds", + -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB); + parameters[numberParameters-1].setLonghelp + ( + "After this many seconds coin solver will act as if maximum nodes had been reached." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("sleep", "for debug", + CLP_PARAM_ACTION_DUMMY, 7, 0); + parameters[numberParameters-1].setLonghelp + ( + "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts", + -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS); + parameters[numberParameters-1].setLonghelp + ( + "Some cut generators are fairly slow - this limits the number of times they are tried." + ); + parameters[numberParameters-1].setIntValue(10); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("slp!Value", "Number of slp passes before primal", + -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1); + parameters[numberParameters-1].setLonghelp + ( + "If you are solving a quadratic problem using primal then it may be helpful to do some \ +sequential Lps to get a good approximate solution." + ); +#if CLP_MULTIPLE_FACTORIZATIONS > 0 + parameters[numberParameters++] = + CbcOrClpParam("small!Factorization", "Whether to use small factorization", + -1, 10000, CBC_PARAM_INT_SMALLFACT, 1); + parameters[numberParameters-1].setLonghelp + ( + "If processed problem <= this use small factorization" + ); + parameters[numberParameters-1].setIntValue(-1); +#endif +#endif + parameters[numberParameters++] = + CbcOrClpParam("solu!tion", "Prints solution to file", + CLP_PARAM_ACTION_SOLUTION); + parameters[numberParameters-1].setLonghelp + ( + "This will write a primitive solution file to the given file name. It will use the default\ + directory given by 'directory'. A name of '$' will use the previous value for the name. This\ + is initialized to 'stdout'. The amount of output can be varied using printi!ngOptions or printMask." + ); +#ifdef COIN_HAS_CLP +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem", + CBC_PARAM_ACTION_BAB); + parameters[numberParameters-1].setLonghelp + ( + "If there are no integer variables then this just solves LP. If there are integer variables \ +this does branch and cut." + ); + parameters[numberParameters++] = + CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL", + "off", CBC_PARAM_STR_SOS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setCurrentOption("on"); + parameters[numberParameters-1].setLonghelp + ( + "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\ + be turned off - this does so." + ); + parameters[numberParameters++] = + CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output", + -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL); + parameters[numberParameters-1].setLonghelp + ( + "If 0 then there should be no output in normal circumstances. 1 is probably the best\ + value for most uses, while 2 and 3 give more information. This parameter is only used inside MIP - for Clp use 'log'" + ); +#else + // allow solve as synonym for possible dual + parameters[numberParameters++] = + CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)", + CLP_PARAM_ACTION_EITHERSIMPLEX); + parameters[numberParameters-1].setLonghelp + ( + "Just so can use solve for clp as well as in cbc" + ); +#endif +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse", + "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0); + parameters[numberParameters-1].append("off"); + parameters[numberParameters++] = + CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp", + 0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0); + parameters[numberParameters++] = + CbcOrClpParam("sprint!Crash", "Whether to try sprint crash", + -1, 5000000, CLP_PARAM_INT_SPRINT); + parameters[numberParameters-1].setLonghelp + ( + "For long and thin problems this program may solve a series of small problems\ + created by taking a subset of the columns. I introduced the idea as 'Sprint' after\ + an LP code of that name of the 60's which tried the same tactic (not totally successfully).\ + Cplex calls it 'sifting'. -1 is automatic choice, 0 is off, n is number of passes" + ); + parameters[numberParameters++] = + CbcOrClpParam("stat!istics", "Print some statistics", + CLP_PARAM_ACTION_STATISTICS); + parameters[numberParameters-1].setLonghelp + ( + "This command prints some statistics for the current model.\ + If log level >1 then more is printed.\ + These are for presolved model if presolve on (and unscaled)." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("stop", "Stops clp execution", + CLP_PARAM_ACTION_EXIT); + parameters[numberParameters-1].setLonghelp + ( + "This stops the execution of Clp, end, exit, quit and stop are synonyms" + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("strat!egy", "Switches on groups of features", + 0, 2, CBC_PARAM_INT_STRATEGY); + parameters[numberParameters-1].setLonghelp + ( + "This turns on newer features. \ +Use 0 for easy problems, 1 is default, 2 is aggressive. \ +1 uses Gomory cuts using tolerance of 0.01 at root, \ +does a possible restart after 100 nodes if can fix many \ +and activates a diving and RINS heuristic and makes feasibility pump \ +more aggressive. \ +This does not apply to unit tests (where 'experiment' may have similar effects)." + ); + parameters[numberParameters-1].setIntValue(1); +#ifdef CBC_KEEP_DEPRECATED + parameters[numberParameters++] = + CbcOrClpParam("strengthen", "Create strengthened problem", + CBC_PARAM_ACTION_STRENGTHEN, 3); + parameters[numberParameters-1].setLonghelp + ( + "This creates a new problem by applying the root node cuts. All tight constraints \ +will be in resulting problem" + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching", + 0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING); + parameters[numberParameters-1].setLonghelp + ( + "In order to decide which variable to branch on, the code will choose up to this number \ +of unsatisfied variables to do mini up and down branches on. Then the most effective one is chosen. \ +If a variable is branched on many times then the previous average up and down costs may be used - \ +see number before trust." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve", + 0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0); + parameters[numberParameters-1].setLonghelp + ( + "Normally Presolve gets rid of 'free' variables when there are no more than 3 \ + variables in column. If you increase this the number of rows may decrease but number of \ + elements may increase." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("testO!si", "Test OsiObject stuff", + -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0); +#endif +#ifdef CBC_THREAD + parameters[numberParameters++] = + CbcOrClpParam("thread!s", "Number of threads to try and use", + -100, 100000, CBC_PARAM_INT_THREADS, 1); + parameters[numberParameters-1].setLonghelp + ( + "To use multiple threads, set threads to number wanted. It may be better \ +to use one or two more than number of cpus available. If 100+n then n threads and \ +search is repeatable (maybe be somewhat slower), \ +if 200+n use threads for root cuts, 400+n threads used in sub-trees." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \ +activity at continuous solution", + 1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0); + parameters[numberParameters-1].setLonghelp + ( + "This sleazy trick can help on some problems." + ); +#endif +#ifdef COIN_HAS_CLP + parameters[numberParameters++] = + CbcOrClpParam("tightLP", "Poor person's preSolve for now", + CLP_PARAM_ACTION_TIGHTEN, 7, 0); +#endif + parameters[numberParameters++] = + CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time", + "cpu", CLP_PARAM_STR_TIME_MODE); + parameters[numberParameters-1].append("elapsed"); + parameters[numberParameters-1].setLonghelp + ( + "cpu uses CPU time for stopping, while elapsed uses elapsed time. \ +(On Windows, elapsed time is always used)." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts", + -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE); + parameters[numberParameters-1].setLonghelp + ( + "Using strong branching computes pseudo-costs. After this many times for a variable we just \ +trust the pseudo costs and do not do any more strong branching." + ); +#endif +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters", + 0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1); + parameters[numberParameters-1].setLonghelp + ( + "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \ +If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \ +cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \ +2 - 4 As above but even if zero objective value\n \ +7 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \ +10 - 1024 Use a larger feasibility tolerance in presolve\n \ +11 - 2048 Try probing before creating cliques" + ); + parameters[numberParameters++] = + CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts", + "off", CBC_PARAM_STR_TWOMIRCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].append("forceandglobal"); + parameters[numberParameters-1].append("forceLongOn"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on two phase mixed integer rounding cuts (either at root or in entire tree) \ +See branchAndCut for information on options." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("unitTest", "Do unit test", + CLP_PARAM_ACTION_UNITTEST, 3, 1); + parameters[numberParameters-1].setLonghelp + ( + "This exercises the unit test for clp" + ); + parameters[numberParameters++] = + CbcOrClpParam("userClp", "Hand coded Clp stuff", + CLP_PARAM_ACTION_USERCLP, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCLP in main driver and modify sample code." + ); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("userCbc", "Hand coded Cbc stuff", + CBC_PARAM_ACTION_USERCBC, 0, 0); + parameters[numberParameters-1].setLonghelp + ( + "There are times e.g. when using AMPL interface when you may wish to do something unusual. \ +Look for USERCBC in main driver and modify sample code. \ +It is possible you can get same effect by using example driver4.cpp." + ); + parameters[numberParameters++] = + CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search", + "off", CBC_PARAM_STR_VND); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("both"); + parameters[numberParameters-1].append("before"); + parameters[numberParameters-1].append("intree"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on variable neighborhood Search. \ +Doh option does heuristic before preprocessing" ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex", + "off", CLP_PARAM_STR_VECTOR, 7, 0); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].setLonghelp + ( + "If this is on ClpPackedMatrix uses extra column copy in odd format." + ); + parameters[numberParameters++] = + CbcOrClpParam("verbose", "Switches on longer help on single ?", + 0, 31, CLP_PARAM_INT_VERBOSE, 0); + parameters[numberParameters-1].setLonghelp + ( + "Set to 1 to get short help with ? list, 2 to get long help, 3 for both. (add 4 to just get ampl ones)." + ); + parameters[numberParameters-1].setIntValue(0); +#ifdef COIN_HAS_CBC + parameters[numberParameters++] = + CbcOrClpParam("vub!heuristic", "Type of vub heuristic", + -2, 20, CBC_PARAM_INT_VUBTRY, 0); + parameters[numberParameters-1].setLonghelp + ( + "If set will try and fix some integer variables" + ); + parameters[numberParameters-1].setIntValue(-1); + parameters[numberParameters++] = + CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts", + "off", CBC_PARAM_STR_ZEROHALFCUTS); + parameters[numberParameters-1].append("on"); + parameters[numberParameters-1].append("root"); + parameters[numberParameters-1].append("ifmove"); + parameters[numberParameters-1].append("forceOn"); + parameters[numberParameters-1].append("onglobal"); + parameters[numberParameters-1].setLonghelp + ( + "This switches on zero-half cuts (either at root or in entire tree) \ +See branchAndCut for information on options. This implementation was written by \ +Alberto Caprara." + ); +#endif + parameters[numberParameters++] = + CbcOrClpParam("zeroT!olerance", "Kill all coefficients \ +whose absolute value is less than this value", + 1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE); + parameters[numberParameters-1].setLonghelp + ( + "This applies to reading mps files (and also lp files \ +if KILL_ZERO_READLP defined)" + ); + parameters[numberParameters-1].setDoubleValue(1.0e-20); + assert(numberParameters < CBCMAXPARAMETERS); +} +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters) +{ + int i; + for (i = 0; i < numberParameters; i++) { + if (parameters[i].type() == name) + break; + } + assert (i < numberParameters); + return i; +} +#ifdef COIN_HAS_CLP +/* Restore a solution from file. + mode 0 normal, 1 swap rows and columns and primal and dual + if 2 set then also change signs +*/ +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode) +{ + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + int numberRowsFile; + int numberColumnsFile; + double objectiveValue; + size_t nRead; + nRead = fread(&numberRowsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&numberColumnsFile, sizeof(int), 1, fp); + if (nRead != 1) + throw("Error in fread"); + nRead = fread(&objectiveValue, sizeof(double), 1, fp); + if (nRead != 1) + throw("Error in fread"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + if (mode) { + // swap + int k = numberRows; + numberRows = numberColumns; + numberColumns = k; + double * temp; + temp = dualRowSolution; + dualRowSolution = primalColumnSolution; + primalColumnSolution = temp; + temp = dualColumnSolution; + dualColumnSolution = primalRowSolution; + primalRowSolution = temp; + } + if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) { + std::cout << "Mismatch on rows and/or columns - giving up" << std::endl; + } else { + lpSolver->setObjectiveValue(objectiveValue); + if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) { + nRead = fread(primalRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast<size_t>(numberRows)) + throw("Error in fread"); + nRead = fread(dualRowSolution, sizeof(double), numberRows, fp); + if (nRead != static_cast<size_t>(numberRows)) + throw("Error in fread"); + nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast<size_t>(numberColumns)) + throw("Error in fread"); + nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nRead != static_cast<size_t>(numberColumns)) + throw("Error in fread"); + } else { + std::cout << "Mismatch on rows and/or columns - truncating" << std::endl; + double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)]; + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast<size_t>(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, primalRowSolution); + nRead = fread(temp, sizeof(double), numberRowsFile, fp); + if (nRead != static_cast<size_t>(numberRowsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberRows, dualRowSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast<size_t>(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, primalColumnSolution); + nRead = fread(temp, sizeof(double), numberColumnsFile, fp); + if (nRead != static_cast<size_t>(numberColumnsFile)) + throw("Error in fread"); + CoinMemcpyN(temp, numberColumns, dualColumnSolution); + delete [] temp; + } + if (mode == 3) { + int i; + for (i = 0; i < numberRows; i++) { + primalRowSolution[i] = -primalRowSolution[i]; + dualRowSolution[i] = -dualRowSolution[i]; + } + for (i = 0; i < numberColumns; i++) { + primalColumnSolution[i] = -primalColumnSolution[i]; + dualColumnSolution[i] = -dualColumnSolution[i]; + } + } + } + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +// Dump a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName) +{ + if (strstr(fileName.c_str(), "_fix_read_")) { + FILE * fp = fopen(fileName.c_str(), "rb"); + if (fp) { + ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver); + restoreSolution(solver, fileName, 0); + // fix all + int logLevel = solver->logLevel(); + int iColumn; + int numberColumns = solver->numberColumns(); + double * primalColumnSolution = + solver->primalColumnSolution(); + double * columnLower = solver->columnLower(); + double * columnUpper = solver->columnUpper(); + for (iColumn = 0; iColumn < numberColumns; iColumn++) { + double value = primalColumnSolution[iColumn]; + if (value > columnUpper[iColumn]) { + if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnUpper[iColumn]; + } else if (value < columnLower[iColumn]) { + if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1) + printf("%d value of %g - bounds %g %g\n", + iColumn, value, columnLower[iColumn], columnUpper[iColumn]); + value = columnLower[iColumn]; + } + columnLower[iColumn] = value; + columnUpper[iColumn] = value; + } + return; + } + } + FILE * fp = fopen(fileName.c_str(), "wb"); + if (fp) { + int numberRows = lpSolver->numberRows(); + int numberColumns = lpSolver->numberColumns(); + double objectiveValue = lpSolver->objectiveValue(); + size_t nWrite; + nWrite = fwrite(&numberRows, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&numberColumns, sizeof(int), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp); + if (nWrite != 1) + throw("Error in fwrite"); + double * dualRowSolution = lpSolver->dualRowSolution(); + double * primalRowSolution = lpSolver->primalRowSolution(); + nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast<size_t>(numberRows)) + throw("Error in fwrite"); + nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp); + if (nWrite != static_cast<size_t>(numberRows)) + throw("Error in fwrite"); + double * dualColumnSolution = lpSolver->dualColumnSolution(); + double * primalColumnSolution = lpSolver->primalColumnSolution(); + nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast<size_t>(numberColumns)) + throw("Error in fwrite"); + nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp); + if (nWrite != static_cast<size_t>(numberColumns)) + throw("Error in fwrite"); + fclose(fp); + } else { + std::cout << "Unable to open file " << fileName << std::endl; + } +} +#endif diff --git a/thirdparty/linux/include/coin1/CbcOrClpParam.hpp b/thirdparty/linux/include/coin1/CbcOrClpParam.hpp new file mode 100644 index 0000000..d76d966 --- /dev/null +++ b/thirdparty/linux/include/coin1/CbcOrClpParam.hpp @@ -0,0 +1,531 @@ + +/* $Id: CbcOrClpParam.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifdef USE_CBCCONFIG +# include "CbcConfig.h" +#else +# include "ClpConfig.h" +#endif + +#ifndef CbcOrClpParam_H +#define CbcOrClpParam_H +/** + This has parameter handling stuff which can be shared between Cbc and Clp (and Dylp etc). + + This (and .cpp) should be copied so that it is the same in Cbc/Test and Clp/Test. + I know this is not elegant but it seems simplest. + + It uses COIN_HAS_CBC for parameters wanted by CBC + It uses COIN_HAS_CLP for parameters wanted by CLP (or CBC using CLP) + It could use COIN_HAS_DYLP for parameters wanted by DYLP + It could use COIN_HAS_DYLP_OR_CLP for parameters wanted by DYLP or CLP etc etc + + */ +class OsiSolverInterface; +class CbcModel; +class ClpSimplex; +/*! \brief Parameter codes + + Parameter type ranges are allocated as follows + <ul> + <li> 1 -- 100 double parameters + <li> 101 -- 200 integer parameters + <li> 201 -- 250 string parameters + <li> 251 -- 300 cuts etc(string but broken out for clarity) + <li> 301 -- 400 `actions' + </ul> + + `Actions' do not necessarily invoke an immediate action; it's just that they + don't fit neatly into the parameters array. + + This coding scheme is in flux. +*/ + +enum CbcOrClpParameterType + +{ + CBC_PARAM_GENERALQUERY = -100, + CBC_PARAM_FULLGENERALQUERY, + + CLP_PARAM_DBL_PRIMALTOLERANCE = 1, + CLP_PARAM_DBL_DUALTOLERANCE, + CLP_PARAM_DBL_TIMELIMIT, + CLP_PARAM_DBL_DUALBOUND, + CLP_PARAM_DBL_PRIMALWEIGHT, + CLP_PARAM_DBL_OBJSCALE, + CLP_PARAM_DBL_RHSSCALE, + CLP_PARAM_DBL_ZEROTOLERANCE, + + CBC_PARAM_DBL_INFEASIBILITYWEIGHT = 51, + CBC_PARAM_DBL_CUTOFF, + CBC_PARAM_DBL_INTEGERTOLERANCE, + CBC_PARAM_DBL_INCREMENT, + CBC_PARAM_DBL_ALLOWABLEGAP, + CBC_PARAM_DBL_TIMELIMIT_BAB, + CBC_PARAM_DBL_GAPRATIO, + + CBC_PARAM_DBL_DJFIX = 81, + CBC_PARAM_DBL_TIGHTENFACTOR, + CLP_PARAM_DBL_PRESOLVETOLERANCE, + CLP_PARAM_DBL_OBJSCALE2, + CBC_PARAM_DBL_FAKEINCREMENT, + CBC_PARAM_DBL_FAKECUTOFF, + CBC_PARAM_DBL_ARTIFICIALCOST, + CBC_PARAM_DBL_DEXTRA3, + CBC_PARAM_DBL_SMALLBAB, + CBC_PARAM_DBL_DEXTRA4, + CBC_PARAM_DBL_DEXTRA5, + + CLP_PARAM_INT_SOLVERLOGLEVEL = 101, +#ifndef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL = 101, +#endif + CLP_PARAM_INT_MAXFACTOR, + CLP_PARAM_INT_PERTVALUE, + CLP_PARAM_INT_MAXITERATION, + CLP_PARAM_INT_PRESOLVEPASS, + CLP_PARAM_INT_IDIOT, + CLP_PARAM_INT_SPRINT, + CLP_PARAM_INT_OUTPUTFORMAT, + CLP_PARAM_INT_SLPVALUE, + CLP_PARAM_INT_PRESOLVEOPTIONS, + CLP_PARAM_INT_PRINTOPTIONS, + CLP_PARAM_INT_SPECIALOPTIONS, + CLP_PARAM_INT_SUBSTITUTION, + CLP_PARAM_INT_DUALIZE, + CLP_PARAM_INT_VERBOSE, + CLP_PARAM_INT_CPP, + CLP_PARAM_INT_PROCESSTUNE, + CLP_PARAM_INT_USESOLUTION, + CLP_PARAM_INT_RANDOMSEED, + CLP_PARAM_INT_MORESPECIALOPTIONS, + CLP_PARAM_INT_DECOMPOSE_BLOCKS, + + CBC_PARAM_INT_STRONGBRANCHING = 151, + CBC_PARAM_INT_CUTDEPTH, + CBC_PARAM_INT_MAXNODES, + CBC_PARAM_INT_NUMBERBEFORE, + CBC_PARAM_INT_NUMBERANALYZE, + CBC_PARAM_INT_MIPOPTIONS, + CBC_PARAM_INT_MOREMIPOPTIONS, + CBC_PARAM_INT_MAXHOTITS, + CBC_PARAM_INT_FPUMPITS, + CBC_PARAM_INT_MAXSOLS, + CBC_PARAM_INT_FPUMPTUNE, + CBC_PARAM_INT_TESTOSI, + CBC_PARAM_INT_EXTRA1, + CBC_PARAM_INT_EXTRA2, + CBC_PARAM_INT_EXTRA3, + CBC_PARAM_INT_EXTRA4, + CBC_PARAM_INT_DEPTHMINIBAB, + CBC_PARAM_INT_CUTPASSINTREE, + CBC_PARAM_INT_THREADS, + CBC_PARAM_INT_CUTPASS, + CBC_PARAM_INT_VUBTRY, + CBC_PARAM_INT_DENSE, + CBC_PARAM_INT_EXPERIMENT, + CBC_PARAM_INT_DIVEOPT, + CBC_PARAM_INT_DIVEOPTSOLVES, + CBC_PARAM_INT_STRATEGY, + CBC_PARAM_INT_SMALLFACT, + CBC_PARAM_INT_HOPTIONS, + CBC_PARAM_INT_CUTLENGTH, + CBC_PARAM_INT_FPUMPTUNE2, +#ifdef COIN_HAS_CBC + CLP_PARAM_INT_LOGLEVEL , +#endif + CBC_PARAM_INT_MAXSAVEDSOLS, + CBC_PARAM_INT_RANDOMSEED, + CBC_PARAM_INT_MULTIPLEROOTS, + CBC_PARAM_INT_STRONG_STRATEGY, + CBC_PARAM_INT_EXTRA_VARIABLES, + CBC_PARAM_INT_MAX_SLOW_CUTS, + CBC_PARAM_INT_MOREMOREMIPOPTIONS, + + CLP_PARAM_STR_DIRECTION = 201, + CLP_PARAM_STR_DUALPIVOT, + CLP_PARAM_STR_SCALING, + CLP_PARAM_STR_ERRORSALLOWED, + CLP_PARAM_STR_KEEPNAMES, + CLP_PARAM_STR_SPARSEFACTOR, + CLP_PARAM_STR_PRIMALPIVOT, + CLP_PARAM_STR_PRESOLVE, + CLP_PARAM_STR_CRASH, + CLP_PARAM_STR_BIASLU, + CLP_PARAM_STR_PERTURBATION, + CLP_PARAM_STR_MESSAGES, + CLP_PARAM_STR_AUTOSCALE, + CLP_PARAM_STR_CHOLESKY, + CLP_PARAM_STR_KKT, + CLP_PARAM_STR_BARRIERSCALE, + CLP_PARAM_STR_GAMMA, + CLP_PARAM_STR_CROSSOVER, + CLP_PARAM_STR_PFI, + CLP_PARAM_STR_INTPRINT, + CLP_PARAM_STR_VECTOR, + CLP_PARAM_STR_FACTORIZATION, + CLP_PARAM_STR_ALLCOMMANDS, + CLP_PARAM_STR_TIME_MODE, + CLP_PARAM_STR_ABCWANTED, + + CBC_PARAM_STR_NODESTRATEGY = 251, + CBC_PARAM_STR_BRANCHSTRATEGY, + CBC_PARAM_STR_CUTSSTRATEGY, + CBC_PARAM_STR_HEURISTICSTRATEGY, + CBC_PARAM_STR_GOMORYCUTS, + CBC_PARAM_STR_PROBINGCUTS, + CBC_PARAM_STR_KNAPSACKCUTS, + CBC_PARAM_STR_REDSPLITCUTS, + CBC_PARAM_STR_ROUNDING, + CBC_PARAM_STR_SOLVER, + CBC_PARAM_STR_CLIQUECUTS, + CBC_PARAM_STR_COSTSTRATEGY, + CBC_PARAM_STR_FLOWCUTS, + CBC_PARAM_STR_MIXEDCUTS, + CBC_PARAM_STR_TWOMIRCUTS, + CBC_PARAM_STR_PREPROCESS, + CBC_PARAM_STR_FPUMP, + CBC_PARAM_STR_GREEDY, + CBC_PARAM_STR_COMBINE, + CBC_PARAM_STR_PROXIMITY, + CBC_PARAM_STR_LOCALTREE, + CBC_PARAM_STR_SOS, + CBC_PARAM_STR_LANDPCUTS, + CBC_PARAM_STR_RINS, + CBC_PARAM_STR_RESIDCUTS, + CBC_PARAM_STR_RENS, + CBC_PARAM_STR_DIVINGS, + CBC_PARAM_STR_DIVINGC, + CBC_PARAM_STR_DIVINGF, + CBC_PARAM_STR_DIVINGG, + CBC_PARAM_STR_DIVINGL, + CBC_PARAM_STR_DIVINGP, + CBC_PARAM_STR_DIVINGV, + CBC_PARAM_STR_DINS, + CBC_PARAM_STR_PIVOTANDFIX, + CBC_PARAM_STR_RANDROUND, + CBC_PARAM_STR_NAIVE, + CBC_PARAM_STR_ZEROHALFCUTS, + CBC_PARAM_STR_CPX, + CBC_PARAM_STR_CROSSOVER2, + CBC_PARAM_STR_PIVOTANDCOMPLEMENT, + CBC_PARAM_STR_VND, + CBC_PARAM_STR_LAGOMORYCUTS, + CBC_PARAM_STR_LATWOMIRCUTS, + CBC_PARAM_STR_REDSPLIT2CUTS, + CBC_PARAM_STR_GMICUTS, + CBC_PARAM_STR_CUTOFF_CONSTRAINT, + CBC_PARAM_STR_DW, + CBC_PARAM_STR_ORBITAL, + + CLP_PARAM_ACTION_DIRECTORY = 301, + CLP_PARAM_ACTION_DIRSAMPLE, + CLP_PARAM_ACTION_DIRNETLIB, + CBC_PARAM_ACTION_DIRMIPLIB, + CLP_PARAM_ACTION_IMPORT, + CLP_PARAM_ACTION_EXPORT, + CLP_PARAM_ACTION_RESTORE, + CLP_PARAM_ACTION_SAVE, + CLP_PARAM_ACTION_DUALSIMPLEX, + CLP_PARAM_ACTION_PRIMALSIMPLEX, + CLP_PARAM_ACTION_EITHERSIMPLEX, + CLP_PARAM_ACTION_MAXIMIZE, + CLP_PARAM_ACTION_MINIMIZE, + CLP_PARAM_ACTION_EXIT, + CLP_PARAM_ACTION_STDIN, + CLP_PARAM_ACTION_UNITTEST, + CLP_PARAM_ACTION_NETLIB_EITHER, + CLP_PARAM_ACTION_NETLIB_DUAL, + CLP_PARAM_ACTION_NETLIB_PRIMAL, + CLP_PARAM_ACTION_SOLUTION, + CLP_PARAM_ACTION_SAVESOL, + CLP_PARAM_ACTION_TIGHTEN, + CLP_PARAM_ACTION_FAKEBOUND, + CLP_PARAM_ACTION_HELP, + CLP_PARAM_ACTION_PLUSMINUS, + CLP_PARAM_ACTION_NETWORK, + CLP_PARAM_ACTION_ALLSLACK, + CLP_PARAM_ACTION_REVERSE, + CLP_PARAM_ACTION_BARRIER, + CLP_PARAM_ACTION_NETLIB_BARRIER, + CLP_PARAM_ACTION_NETLIB_TUNE, + CLP_PARAM_ACTION_REALLY_SCALE, + CLP_PARAM_ACTION_BASISIN, + CLP_PARAM_ACTION_BASISOUT, + CLP_PARAM_ACTION_SOLVECONTINUOUS, + CLP_PARAM_ACTION_CLEARCUTS, + CLP_PARAM_ACTION_VERSION, + CLP_PARAM_ACTION_STATISTICS, + CLP_PARAM_ACTION_DEBUG, + CLP_PARAM_ACTION_DUMMY, + CLP_PARAM_ACTION_PRINTMASK, + CLP_PARAM_ACTION_OUTDUPROWS, + CLP_PARAM_ACTION_USERCLP, + CLP_PARAM_ACTION_MODELIN, + CLP_PARAM_ACTION_CSVSTATISTICS, + CLP_PARAM_ACTION_STOREDFILE, + CLP_PARAM_ACTION_ENVIRONMENT, + CLP_PARAM_ACTION_PARAMETRICS, + CLP_PARAM_ACTION_GMPL_SOLUTION, + CLP_PARAM_ACTION_RESTORESOL, + + CBC_PARAM_ACTION_BAB = 361, + CBC_PARAM_ACTION_MIPLIB, + CBC_PARAM_ACTION_STRENGTHEN, + CBC_PARAM_ACTION_PRIORITYIN, + CBC_PARAM_ACTION_MIPSTART, + CBC_PARAM_ACTION_USERCBC, + CBC_PARAM_ACTION_DOHEURISTIC, + CLP_PARAM_ACTION_NEXTBESTSOLUTION, + + CBC_PARAM_NOTUSED_OSLSTUFF = 401, + CBC_PARAM_NOTUSED_CBCSTUFF, + + CBC_PARAM_NOTUSED_INVALID = 1000 +} ; +#include <vector> +#include <string> + +/// Very simple class for setting parameters + +class CbcOrClpParam { +public: + /**@name Constructor and destructor */ + //@{ + /// Constructors + CbcOrClpParam ( ); + CbcOrClpParam (std::string name, std::string help, + double lower, double upper, CbcOrClpParameterType type, int display = 2); + CbcOrClpParam (std::string name, std::string help, + int lower, int upper, CbcOrClpParameterType type, int display = 2); + // Other strings will be added by insert + CbcOrClpParam (std::string name, std::string help, std::string firstValue, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + // Action + CbcOrClpParam (std::string name, std::string help, + CbcOrClpParameterType type, int whereUsed = 7, int display = 2); + /// Copy constructor. + CbcOrClpParam(const CbcOrClpParam &); + /// Assignment operator. This copies the data + CbcOrClpParam & operator=(const CbcOrClpParam & rhs); + /// Destructor + ~CbcOrClpParam ( ); + //@} + + /**@name stuff */ + //@{ + /// Insert string (only valid for keywords) + void append(std::string keyWord); + /// Adds one help line + void addHelp(std::string keyWord); + /// Returns name + inline std::string name( ) const { + return name_; + } + /// Returns short help + inline std::string shortHelp( ) const { + return shortHelp_; + } + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(CbcModel & model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( CbcModel & model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(CbcModel & model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(CbcModel & model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( CbcModel & model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(CbcModel & model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(ClpSimplex * model, double value) ; + /// Gets a double parameter + double doubleParameter(ClpSimplex * model) const; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( ClpSimplex * model, double value , int & returnCode); + /// Sets a int parameter (nonzero code if error) + int setIntParameter(ClpSimplex * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( ClpSimplex * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(ClpSimplex * model) const; + /// Sets a double parameter (nonzero code if error) + int setDoubleParameter(OsiSolverInterface * model, double value) ; + /// Sets double parameter and returns printable string and error code + const char * setDoubleParameterWithMessage ( OsiSolverInterface * model, double value , int & returnCode); + /// Gets a double parameter + double doubleParameter(OsiSolverInterface * model) const; + /// Sets a int parameter (nonzero code if error) + int setIntParameter(OsiSolverInterface * model, int value) ; + /// Sets int parameter and returns printable string and error code + const char * setIntParameterWithMessage ( OsiSolverInterface * model, int value , int & returnCode); + /// Gets a int parameter + int intParameter(OsiSolverInterface * model) const; + /// Checks a double parameter (nonzero code if error) + int checkDoubleParameter(double value) const; + /// Returns name which could match + std::string matchName ( ) const; + /// Returns length of name for ptinting + int lengthMatchName ( ) const; + /// Returns parameter option which matches (-1 if none) + int parameterOption ( std::string check ) const; + /// Prints parameter options + void printOptions ( ) const; + /// Returns current parameter option + inline std::string currentOption ( ) const { + return definedKeyWords_[currentKeyWord_]; + } + /// Sets current parameter option + void setCurrentOption ( int value , bool printIt = false); + /// Sets current parameter option and returns printable string + const char * setCurrentOptionWithMessage ( int value ); + /// Sets current parameter option using string + void setCurrentOption (const std::string value ); + /// Sets current parameter option using string with message + const char * setCurrentOptionWithMessage (const std::string value ); + /// Returns current parameter option position + int currentOptionAsInteger ( ) const ; + /** Returns current parameter option position + but if fake keyword returns a fake value and sets + fakeInteger to true value. If not fake then fakeInteger is -COIN_INT_MAX + */ + int currentOptionAsInteger ( int & fakeInteger ) const; + /// Sets int value + void setIntValue ( int value ); + /// Sets int value with message + const char * setIntValueWithMessage ( int value ); + inline int intValue () const { + return intValue_; + } + /// Sets double value + void setDoubleValue ( double value ); + /// Sets double value with message + const char * setDoubleValueWithMessage ( double value ); + inline double doubleValue () const { + return doubleValue_; + } + /// Sets string value + void setStringValue ( std::string value ); + inline std::string stringValue () const { + return stringValue_; + } + /// Returns 1 if matches minimum, 2 if matches less, 0 if not matched + int matches (std::string input) const; + /// type + inline CbcOrClpParameterType type() const { + return type_; + } + /// whether to display + inline int displayThis() const { + return display_; + } + /// Set Long help + inline void setLonghelp(const std::string help) { + longHelp_ = help; + } + /// Print Long help + void printLongHelp() const; + /// Print action and string + void printString() const; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + inline int whereUsed() const { + return whereUsed_; + } + /// Gets value of fake keyword + inline int fakeKeyWord() const + { return fakeKeyWord_;} + /// Sets value of fake keyword + inline void setFakeKeyWord(int value, int fakeValue) + { fakeKeyWord_ = value; fakeValue_ = fakeValue;} + /// Sets value of fake keyword to current size of keywords + void setFakeKeyWord(int fakeValue); + +private: + /// gutsOfConstructor + void gutsOfConstructor(); + //@} +////////////////// data ////////////////// +private: + + /**@name data + We might as well throw all type data in - could derive? + */ + //@{ + // Type see CbcOrClpParameterType + CbcOrClpParameterType type_; + /// If double == okay + double lowerDoubleValue_; + double upperDoubleValue_; + /// If int == okay + int lowerIntValue_; + int upperIntValue_; + // Length of name + unsigned int lengthName_; + // Minimum match + unsigned int lengthMatch_; + /// set of valid strings + std::vector<std::string> definedKeyWords_; + /// Name + std::string name_; + /// Short help + std::string shortHelp_; + /// Long help + std::string longHelp_; + /// Action + CbcOrClpParameterType action_; + /// Current keyWord (if a keyword parameter) + int currentKeyWord_; + /// Display on ? + int display_; + /// Integer parameter - current value + int intValue_; + /// Double parameter - current value + double doubleValue_; + /// String parameter - current value + std::string stringValue_; + /** 7 if used everywhere, + 1 - used by clp + 2 - used by cbc + 4 - used by ampl + */ + int whereUsed_; + /** If >=0 then integers allowed as a fake keyword + So minusnnnn would got to -nnnn in currentKeyword_ + and plusnnnn would go to fakeKeyword_+nnnn + */ + int fakeKeyWord_; + /// Return this as main value if an integer + int fakeValue_; + //@} +}; +/// Simple read stuff +std::string CoinReadNextField(); + +std::string CoinReadGetCommand(int argc, const char *argv[]); +std::string CoinReadGetString(int argc, const char *argv[]); +// valid 0 - okay, 1 bad, 2 not there +int CoinReadGetIntField(int argc, const char *argv[], int * valid); +double CoinReadGetDoubleField(int argc, const char *argv[], int * valid); +void CoinReadPrintit(const char * input); +void setCbcOrClpPrinting(bool yesNo); +#define CBCMAXPARAMETERS 250 +/* + Subroutine to establish the cbc parameter array. See the description of + class CbcOrClpParam for details. Pulled from C..Main() for clarity. +*/ +void establishParams (int &numberParameters, CbcOrClpParam *const parameters); +// Given a parameter type - returns its number in list +int whichParam (CbcOrClpParameterType name, + int numberParameters, CbcOrClpParam *const parameters); +// Dump/restore a solution to file +void saveSolution(const ClpSimplex * lpSolver, std::string fileName); +void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode); +#endif /* CbcOrClpParam_H */ diff --git a/thirdparty/linux/include/coin1/Cgl012cut.hpp b/thirdparty/linux/include/coin1/Cgl012cut.hpp new file mode 100644 index 0000000..2814b0a --- /dev/null +++ b/thirdparty/linux/include/coin1/Cgl012cut.hpp @@ -0,0 +1,464 @@ +// $Id: Cgl012cut.hpp 1149 2013-10-21 18:23:53Z tkr $ +// Copyright (C) 2010, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/** @file 012cut.h Include file for C coded 0-1/2 separator */ +#ifndef CGL012CUT +#define CGL012CUT +#include <cstdio> +#include <cstdlib> +#include <cmath> + +#define CGL_NEW_SHORT +#ifndef CGL_NEW_SHORT +typedef /* arc */ + struct arc_st +{ + int len; /* length of the arc */ + struct node_st *head; /* head node */ +} + arc; + +typedef /* node */ + struct node_st +{ + arc *first; /* first outgoing arc */ + int dist; /* tentative shortest path length */ + struct node_st *parent; /* parent pointer */ + struct node_st *next; /* next node in queue */ + struct node_st *prev; /* previous node in queue */ + int status; /* status of node */ + int temp; /* for temporary labels */ + int index; /* index of the node in the graph */ +} node; +#endif +typedef struct +{ + int length; // Length of arc + int to; // To node +} cgl_arc; + +typedef struct +{ + cgl_arc * firstArc; // First outgoing arc + int parentNode; // Parent node in shortest path + int index; // Which node I am + int distanceBack; // Distance back to source +} cgl_node; + +typedef struct +{ + int nnodes; // Number of nodes in graph + int narcs; // Number of arcs in graph + cgl_node * nodes; + cgl_arc * arcs; +} cgl_graph; +/* #define PRINT */ +/* #define PRINT_CUTS */ +#define REDUCTION + +typedef struct { +int mr; /* number of rows in the ILP matrix */ +int mc; /* number of columns in the ILP matrix */ +int mnz; /* number of nonzero's in the ILP matrix */ +int *mtbeg; /* starting position of each row in arrays mtind and mtval */ +int *mtcnt; /* number of entries of each row in arrays mtind and mtval */ +int *mtind; /* column indices of the nonzero entries of the ILP matrix */ +int *mtval; /* values of the nonzero entries of the ILP matrix */ +int *vlb; /* lower bounds on the variables */ +int *vub; /* upper bounds on the variables */ +int *mrhs; /* right hand sides of the constraints */ +char *msense; /* senses of the constraints: 'L', 'G' or 'E' */ +const double *xstar; /* current optimal solution of the LP relaxation */ +} ilp; + +typedef struct { +int mr; /* number of rows in the parity ILP matrix */ +int mc; /* number of columns in the parity ILP matrix */ +int mnz; /* number of 1's in the parity ILP matrix */ +int *mtbeg; /* starting position of each row in arrays mtind and mtval */ +int *mtcnt; /* number of entries of each row in arrays mtind and mtval */ +int *mtind; /* column indices of the 1's of the parity ILP matrix */ +short int *mrhs; /* right hand side parity of the constraints */ +double *xstar; /* current optimal solution of the LP relaxation */ +double *slack; /* slack of the constraints w.r.t. xstar */ +short int *row_to_delete; /* flag for marking rows not to be considered */ +short int *col_to_delete; /* flag for marking columns not to be considered */ +int *gcd; /* greatest common divisor of each row in the input ILP matrix */ +short int *possible_weak; /* possible weakening types of each column */ +short int *type_even_weak; /* type of even weakening of each column + (lower or upper bound weakening) */ +short int *type_odd_weak; /* type of odd weakening of each column + (lower or upper bound weakening) */ +double *loss_even_weak; /* loss for the even weakening of each column */ +double *loss_odd_weak; /* loss for the odd weakening of each column */ +double *min_loss_by_weak; /* minimum loss for the weakening of each column */ +} parity_ilp; + +typedef struct { +int nweak; /* number of variables weakened */ +int *var; /* list of variables weakened */ +short int *type; /* type of weakening (lower or upper bound weakening) */ +} info_weak; + +typedef struct { +int endpoint1, endpoint2; /* endpoints of the edge */ +double weight; /* edge weight */ +short int parity; /* edge parity (even or odd) */ +int constr; /* constraint associated with the edge */ +info_weak *weak; /* weakening information */ +} edge; + +typedef struct { +int nnodes; /* number of nodes */ +int nedges; /* number of edges */ +int *nodes; /* indexes of the ILP columns corresponding to the nodes */ +int *ind; /* indexes of the nodes corresponding to the ILP columns */ +edge **even_adj_list; /* pointers to the even edges */ +edge **odd_adj_list; /* pointers to the odd edges */ +} separation_graph; + +#ifndef CGL_NEW_SHORT +typedef struct { +int nnodes; /* number of nodes */ +int narcs; /* number of arcs */ +node *nodes; /* array of the nodes - see "types_db.h" */ +arc *arcs; /* array of the arcs - see "types_db.h" */ +} auxiliary_graph; +#else +typedef struct { +int nnodes; /* number of nodes */ +int narcs; /* number of arcs */ +cgl_node *nodes; /* array of the nodes - see "types_db.h" */ +cgl_arc *arcs; /* array of the arcs - see "types_db.h" */ +} auxiliary_graph; +#endif + +typedef struct { +long dist; /* distance from/to root */ +int pred; /* index of the predecessor */ +} short_path_node; + +typedef struct { +double weight; /* overall weight of the cycle */ +int length; /* number of edges in the cycle */ +edge **edge_list; /* list of edges in the cycle */ +} cycle; + +typedef struct { +int cnum; /* overall number of cycles */ +cycle **list; /* pointers to the cycles in the list */ +} cycle_list; + +typedef struct { +int n_of_constr; /* number of constraints combined to get the cut */ +int *constr_list; /* list of the constraints combined */ +short int *in_constr_list; /* flag saying whether a given constraint is + in the list of constraints of the cut (IN) + or not (OUT) */ +int cnzcnt; /* overall number of nonzero's in the cut */ +int *cind; /* column indices of the nonzero entries of the cut */ +int *cval; /* values of the nonzero entries of the cut */ +int crhs; /* right hand side of the cut */ +char csense; /* sense of the cut: 'L', 'G' or 'E' */ +double violation; /* violation of the cut w.r.t. the current LP solution */ +} cut; + +typedef struct { +int cnum; /* overall number of cuts */ +cut **list; /* pointers to the cuts in the list */ +} cut_list; + +typedef struct { +int n_of_constr; /* number of constraints combined to get the cut */ +int *constr_list; /* list of the constraints combined */ +int code; /* identifier of the cut */ +int n_it_violated; /* number of consecutive iterations (starting from the + last and going backward) in which the cut was + violated by the LP solution */ +int it_found; /* iteration in which the cut was separated */ +double score; /* score of the cut, used to choose wich cut should be + added to the current LP (if any) */ +} pool_cut; + +typedef struct { +int cnum; /* overall number of cuts */ +pool_cut **list; /* pointers to the cuts in the list */ +int *ncod; /* number of cuts with a given code in the pool */ +} pool_cut_list; + +typedef struct { +int *ccoef; /* coefficients of the cut */ +int crhs; /* right hand side of the cut */ +int pool_index; /* index of the cut in the pool */ +double score; /* cut score (to be maximized) */ +} select_cut; + +typedef struct { +int n_it_zero; /* number of consecutive iterations (starting from the + last and going backward) in which each variable took + the value 0 in the LP solution */ +} log_var; +/** 012Cut Generator Class + + This class is to make Cgl01cut thread safe etc +*/ + +class Cgl012Cut { + +public: + + /**@name Generate Cuts */ + //@{ +int sep_012_cut( +/* + INPUT parameters: +*/ +int mr, /* number of rows in the ILP matrix */ +int mc, /* number of columns in the ILP matrix */ +int mnz, /* number of nonzero's in the ILP matrix */ +int *mtbeg, /* starting position of each row in arrays mtind and mtval */ +int *mtcnt, /* number of entries of each row in arrays mtind and mtval */ +int *mtind, /* column indices of the nonzero entries of the ILP matrix */ +int *mtval, /* values of the nonzero entries of the ILP matrix */ +int *vlb, /* lower bounds on the variables */ +int *vub, /* upper bounds on the variables */ +int *mrhs, /* right hand sides of the constraints */ +char *msense, /* senses of the constraints: 'L', 'G' or 'E' */ +const double *xstar, /* current optimal solution of the LP relaxation */ +bool aggressive, /* flag asking whether as many cuts as possible are + required on output (TRUE) or not (FALSE) */ +/* + OUTPUT parameters (the memory for the vectors is allocated INTERNALLY + by the procedure: if some memory is already allocated, it is FREED): +*/ +int *cnum, /* number of violated 0-1/2 cuts identified by the procedure */ +int *cnzcnt, /* overall number of nonzero's in the cuts */ +int **cbeg, /* starting position of each cut in arrays cind and cval */ +int **ccnt, /* number of entries of each cut in arrays cind and cval */ +int **cind, /* column indices of the nonzero entries of the cuts */ +int **cval, /* values of the nonzero entries of the cuts */ +int **crhs, /* right hand sides of the cuts */ +char **csense /* senses of the cuts: 'L', 'G' or 'E' */ +/* + NOTE that all the numerical input/output vectors are INTEGER (with + the exception of xstar), since the procedure is intended to work + with pure ILP's, and that the ILP matrix has to be given on input + in ROW format. +*/ + ); +void ilp_load( + int mr, /* number of rows in the ILP matrix */ + int mc, /* number of columns in the ILP matrix */ + int mnz, /* number of nonzero's in the ILP matrix */ + int *mtbeg, /* starting position of each row in arrays mtind and mtval */ + int *mtcnt, /* number of entries of each row in arrays mtind and mtval */ + int *mtind, /* column indices of the nonzero entries of the ILP matrix */ + int *mtval, /* values of the nonzero entries of the ILP matrix */ + int *vlb, /* lower bounds on the variables */ + int *vub, /* upper bounds on the variables */ + int *mrhs, /* right hand sides of the constraints */ + char *msense /* senses of the constraints: 'L', 'G' or 'E' */ + ); +void free_ilp(); +/* alloc_parity_ilp: allocate the memory for the parity ILP data structure */ + +void alloc_parity_ilp( + int mr, /* number of rows in the ILP matrix */ + int mc, /* number of columns in the ILP matrix */ + int mnz /* number of nonzero's in the ILP matrix */ + ); +void free_parity_ilp(); + void initialize_log_var(); +/* free_log_var */ + void free_log_var(); +private: +/* best_weakening: find the best upper/lower bound weakening of a set + of variables */ + +int best_weakening( + int n_to_weak, /* number of variables to weaken */ +int *vars_to_weak, /* indices of the variables to weaken */ +short int original_parity, /* original parity of the constraint to weaken */ +double original_slack, /* original slack of the constraint to weaken */ +double *best_even_slack, /* best possible slack of a weakened constraint + with even right-hand-side */ +double *best_odd_slack, /* best possible slack of a weakened constraint + with odd right-hand-side */ +info_weak **info_even_weak, /* weakening information about the best possible + even weakened constraint */ +info_weak **info_odd_weak, /* weakening information about the best possible + odd weakened constraint */ +short int only_odd, /* flag which tells whether only an odd weakening is of + interest (TRUE) or both weakenings are (FALSE) */ +short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); + +/* best_cut: find the coefficients, the rhs and the violation of the + best possible cut that can be obtained by weakening a given set of + coefficients to even and a rhs to odd, dividing by 2 and rounding */ + +short int best_cut( + int *ccoef, /* vector of the coefficients */ + int *crhs, /* pointer to rhs value */ + double *violation, /* violation of the cut */ + short int update, /* TRUE/FALSE: if TRUE, the new ccoef and crhs are + given on output */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* get_cut: extract a hopefully violated cut from an odd cycle of the + separation graph */ + +cut *get_cut( + cycle *s_cyc /* shortest odd cycles identified in the separation graph */ + ); + +/* update_log_var: update the log information for the problem variables */ + void update_log_var(); + +/* basic_separation: try to identify violated 0-1/2 cuts by using the + original procedure described in Caprara and Fischetti's MP paper */ + + cut_list *basic_separation(); + +/* score_by_moving: compute the score of the best cut obtainable from + the current local search solution by inserting/deleting a constraint */ + +double score_by_moving( + int i, /* constraint to be moved */ + short int itype, /* type of move - ADD or DEL */ + double thresh /* minimum value of an interesting score */ + ); +/* modify_current: update the current local search solution by inserting/ + deleting a constraint */ + +void modify_current( + int i, /* constraint to be moved */ + short int itype /* type of move - ADD or DEL */ + ); + +/* best neighbour: find the cut to be added/deleted from the current + solution among those allowed by the tabu rules */ + + short int best_neighbour(cut_list *out_cuts /* list of the violated cuts found */); + +/* add_tight_constraint: initialize the current cut by adding a tight + constraint to it */ + + void add_tight_constraint(); + +/* tabu_012: try to identify violated 0-1/2 cuts by a simple tabu search + procedure adapted from that used by Battiti and Protasi for finding + large cliques */ + + cut_list *tabu_012(); +/* initialize: initialize the data structures for local search */ + + void initialize(); +/* restart: perform a restart of the search - IMPORTANT: in the current + implementation vector last_moved is not cleared at restart */ + + void restart(short int failure /* flag forcing the restart if some trouble occurred */); + void print_constr(int i /* constraint to be printed */); + void print_parity_ilp(); + +/* get_parity_ilp: construct an internal data structure containing all the + information which can be useful for 0-1/2 cut separation */ + + void get_parity_ilp(); +/* initialize_sep_graph: allocate and initialize the data structure + to contain the information associated with a separation graph */ + + separation_graph *initialize_sep_graph(); + void print_cut(cut *v_cut); +/* get_ori_cut_coef: get the coefficients of a cut, before dividing by 2 and + rounding, starting from the list of the constraints combined to get + the cut */ + +short int get_ori_cut_coef( + int n_of_constr, /* number of constraints combined */ + int *constr_list, /* list of the constraints combined */ + int *ccoef, /* cut left hand side coefficients */ + int *crhs, /* cut right hand side */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* define_cut: construct a cut data structure from a vector of + coefficients and a right-hand-side */ + +cut *define_cut( + int *ccoef, /* coefficients of the cut */ + int crhs /* right hand side of the cut */ + ); + +/* cut_score: define the score of a (violated) cut */ + +double cut_score( + int *ccoef, /* cut left hand side coefficients */ + int crhs, /* cut right hand side */ + double viol, /* cut violation */ + short int only_viol /* flag which tells whether only an inequality of + slack smaller than MAX_SLACK is of interest (TRUE) + otherwise (FALSE) */ + ); +/* get_current_cut: return a cut data type with the information about + the current cut of the search procedure */ + + cut *get_current_cut(); +/* print_cur_cut: display cur_cut on output */ + + void print_cur_cut(); + void print_cut_list(cut_list *cuts); + //@} +public: + /**@name Constructors and destructors */ + //@{ + /// Default constructor + Cgl012Cut (); + + /// Copy constructor + Cgl012Cut ( + const Cgl012Cut &); + + /// Assignment operator + Cgl012Cut & + operator=( + const Cgl012Cut& rhs); + + /// Destructor + virtual ~Cgl012Cut (); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + //@} + + + /**@name Private member data */ + //@{ + +ilp *inp_ilp; /* input ILP data structure */ +parity_ilp *p_ilp; /* parity ILP data structure */ +int iter; +double gap; +double maxgap; +int errorNo; +int sep_iter; /* number of the current separation iteration */ +log_var **vlog; /* information about the value attained + by the variables in the last iterations, + used to possibly set to 0 some coefficient + > 0 in a cut to be added */ +bool aggr; /* flag saying whether as many cuts as possible are required + from the separation procedure (TRUE) or not (FALSE) */ + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglAllDifferent.hpp b/thirdparty/linux/include/coin1/CglAllDifferent.hpp new file mode 100644 index 0000000..ed369d1 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglAllDifferent.hpp @@ -0,0 +1,115 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglAllDifferent_H +#define CglAllDifferent_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** AllDifferent Cut Generator Class + This has a number of sets. All the members in each set are general integer + variables which have to be different from all others in the set. + + At present this only generates column cuts + + At present it is very primitive compared to proper CSP implementations + */ +class CglAllDifferent : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** This fixes (or reduces bounds) on sets of all different variables + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglAllDifferent (); + + /// Useful constructot + CglAllDifferent(int numberSets, const int * starts, const int * which); + + /// Copy constructor + CglAllDifferent ( + const CglAllDifferent &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglAllDifferent & + operator=( + const CglAllDifferent& rhs); + + /// Destructor + virtual + ~CglAllDifferent (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const + { return false;} + //@} + /**@name Sets and Gets */ + //@{ + /// Set log level + inline void setLogLevel(int value) + { logLevel_=value;} + /// Get log level + inline int getLogLevel() const + { return logLevel_;} + /// Set Maximum number of sets to look at at once + inline void setMaxLook(int value) + { maxLook_=value;} + /// Get Maximum number of sets to look at at once + inline int getMaxLook() const + { return maxLook_;} + //@} + +private: + + // Private member methods + /**@name */ + //@{ + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// Number of sets + int numberSets_; + /// Total number of variables in all different sets + int numberDifferent_; + /// Maximum number of sets to look at at once + int maxLook_; + /// Log level - 0 none, 1 - a bit, 2 - more details + int logLevel_; + /// Start of each set + int * start_; + /// Members (0,1,....) not as in original model + int * which_; + /// Original members + int * originalWhich_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglClique.hpp b/thirdparty/linux/include/coin1/CglClique.hpp new file mode 100644 index 0000000..5b47b40 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglClique.hpp @@ -0,0 +1,308 @@ +// $Id: CglClique.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CglClique_h_ +#define _CglClique_h_ + +#include "CglCutGenerator.hpp" + +//class OsiCuts; +//class OsiSolverInterface; + +class CglClique : public CglCutGenerator { + + friend void CglCliqueUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); +public: + /// Copy constructor + CglClique(const CglClique& rhs); + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglClique& operator=(const CglClique& rhs); + +public: + + virtual void + generateCuts(const OsiSolverInterface& si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /**@name Constructors and destructors */ + //@{ + /** Default constructor. + If the setPacking argument is set to true then CglClique will assume that the + problem in the solverinterface passed to the generateCuts() method + describes a set packing problem, i.e., + - all variables are binary + - the matrix is a 0-1 matrix + - all constraints are '= 1' or '<= 1' + + Otherwise the user can use the considerRows() method to set the list of + clique rows, that is, + - all coeffs corresponding to binary variables at fractional level is 1 + - all other coeffs are non-negative + - the constraint is '= 1' or '<= 1'. + + If the user does not set the list of clique rows then CglClique will + start the generateCuts() methods by scanning the matrix for them. + Also justOriginalRows can be set to true to limit clique creation + */ + CglClique(bool setPacking = false, bool justOriginalRows = false); + /// Destructor + virtual ~CglClique() {} + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + void considerRows(const int numRows, const int* rowInd); + +public: + /** possible choices for selecting the next node in the star clique search + */ + enum scl_next_node_method { + SCL_MIN_DEGREE, + SCL_MAX_DEGREE, + SCL_MAX_XJ_MAX_DEG + }; + + void setStarCliqueNextNodeMethod(scl_next_node_method method) { + scl_next_node_rule = method; + } + + void setStarCliqueCandidateLengthThreshold(int maxlen) { + scl_candidate_length_threshold = maxlen; + } + void setRowCliqueCandidateLengthThreshold(int maxlen) { + rcl_candidate_length_threshold = maxlen; + } + + void setStarCliqueReport(bool yesno = true) { scl_report_result = yesno; } + void setRowCliqueReport(bool yesno = true) { rcl_report_result = yesno; } + + void setDoStarClique(bool yesno = true) { do_star_clique = yesno; } + void setDoRowClique(bool yesno = true) { do_row_clique = yesno; } + + void setMinViolation(double minviol) { petol = minviol; } + double getMinViolation() const { return petol; } + +private: + + struct frac_graph ; + friend struct frac_graph ; + + /** A node of the fractional graph. There is a node for every variable at + fractional level. */ + struct fnode { + /** pointer into all_nbr */ + int *nbrs; + /** 1-x_i-x_j, needed for odd holes, in the same order as the adj list, + pointer into all_edgecost */ + double *edgecosts; + /** degree of the node */ + int degree; + /** the fractional value of the variable corresponding to this node */ + double val; + }; + + /** A graph corresponding to a fractional solution of an LP. Two nodes are + adjacent iff their columns are non-orthogonal. */ + struct frac_graph { + /** # of nodes = # of fractional values in the LP solution */ + int nodenum; + /** # of edges in the graph */ + int edgenum; + /** density= edgenum/(nodenum choose 2) */ + double density; + int min_deg_node; + int min_degree; + int max_deg_node; + int max_degree; + /** The array of the nodes in the graph */ + fnode *nodes; + /** The array of all the neighbors. First the indices of the nodes + adjacent to node 0 are listed, then those adjacent to node 1, etc. */ + int *all_nbr; + /** The array of the costs of the edges going to the neighbors */ + double *all_edgecost; + + frac_graph() : + nodenum(0), edgenum(0), density(0), + min_deg_node(0), min_degree(0), max_deg_node(0), max_degree(0), + nodes(0), all_nbr(0), all_edgecost(0) {} + }; + +protected: + /** An indicator showing whether the whole matrix in the solverinterface is + a set packing problem or not */ + bool setPacking_; + /// True if just look at original rows + bool justOriginalRows_; + /** pieces of the set packing part of the solverinterface */ + int sp_numrows; + int* sp_orig_row_ind; + int sp_numcols; + int* sp_orig_col_ind; + double* sp_colsol; + int* sp_col_start; + int* sp_col_ind; + int* sp_row_start; + int* sp_row_ind; + + /** the intersection graph corresponding to the set packing problem */ + frac_graph fgraph; + /** the node-node incidence matrix of the intersection graph. */ + bool* node_node; + + /** The primal tolerance in the solverinterface. */ + double petol; + + /** data for the star clique algorithm */ + + /** Parameters */ + /**@{*/ + /** whether to do the row clique algorithm or not. */ + bool do_row_clique; + /** whether to do the star clique algorithm or not. */ + bool do_star_clique; + + /** How the next node to be added to the star clique should be selected */ + scl_next_node_method scl_next_node_rule; + /** In the star clique method the maximal length of the candidate list + (those nodes that are in a star, i.e., connected to the center of the + star) to allow complete enumeration of maximal cliques. Otherwise a + greedy algorithm is used. */ + int scl_candidate_length_threshold; + /** whether to give a detailed statistics on the star clique method */ + bool scl_report_result; + + /** In the row clique method the maximal length of the candidate list + (those nodes that can extend the row clique, i.e., connected to all + nodes in the row clique) to allow complete enumeration of maximal + cliques. Otherwise a greedy algorithm is used. */ + int rcl_candidate_length_threshold; + /** whether to give a detailed statistics on the row clique method */ + bool rcl_report_result; + /**@}*/ + + /** variables/arrays that are used across many methods */ + /**@{*/ + /** List of indices that must be in the to be created clique. This is just + a pointer, it is never new'd and therefore does not need to be + delete[]'d either. */ + const int* cl_perm_indices; + /** The length of cl_perm_indices */ + int cl_perm_length; + + /** List of indices that should be considered for extending the ones listed + in cl_perm_indices. */ + int* cl_indices; + /** The length of cl_indices */ + int cl_length; + + /** An array of nodes discarded from the candidate list. These are + rechecked when a maximal clique is found just to make sure that the + clique is really maximal. */ + int* cl_del_indices; + /** The length of cl_del_indices */ + int cl_del_length; + + /**@}*/ + +private: + /** Scan through the variables and select those that are binary and are at + a fractional level. */ + void selectFractionalBinaries(const OsiSolverInterface& si); + /** Scan through the variables and select those that are at a fractional + level. We already know that everything is binary. */ + void selectFractionals(const OsiSolverInterface& si); + /** */ + void selectRowCliques(const OsiSolverInterface& si,int numOriginalRows); + /** */ + void createSetPackingSubMatrix(const OsiSolverInterface& si); + /** */ + void createFractionalGraph(); + /** */ + int createNodeNode(); + /** */ + void deleteSetPackingSubMatrix(); + /** */ + void deleteFractionalGraph(); + /** */ + void find_scl(OsiCuts& cs); + /** */ + void find_rcl(OsiCuts& cs); + /** */ + int scl_choose_next_node(const int current_nodenum, + const int *current_indices, + const int *current_degrees, + const double *current_values); + /** */ + void scl_delete_node(const int del_ind, int& current_nodenum, + int *current_indices, int *current_degrees, + double *current_values); + /** */ + int enumerate_maximal_cliques(int& pos, bool* scl_label, OsiCuts& cs); + /** */ + int greedy_maximal_clique(OsiCuts& cs); + /** */ + void recordClique(const int len, int* indices, OsiCuts& cs); +}; +//############################################################################# +/** A function that tests the methods in the CglClique class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglCliqueUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +/// This works on a fake solver i.e. invented rows +class CglProbing; +class CglFakeClique : public CglClique { + +public: + /// Copy constructor + CglFakeClique(const CglFakeClique& rhs); + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglFakeClique& operator=(const CglFakeClique& rhs); + + virtual void + generateCuts(const OsiSolverInterface& si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /**@name Constructors and destructors */ + //@{ + /** Default constructor. + If the setPacking argument is set to true then CglFakeClique will assume that the + problem in the solverinterface passed to the generateCuts() method + describes a set packing problem, i.e., + - all variables are binary + - the matrix is a 0-1 matrix + - all constraints are '= 1' or '<= 1' + + Otherwise the user can use the considerRows() method to set the list of + clique rows, that is, + - all coeffs corresponding to binary variables at fractional level is 1 + - all other coeffs are non-negative + - the constraint is '= 1' or '<= 1'. + + If the user does not set the list of clique rows then CglFakeClique will + start the generateCuts() methods by scanning the matrix for them. + */ + CglFakeClique(OsiSolverInterface * solver=NULL,bool setPacking = false); + /// Destructor + virtual ~CglFakeClique(); + /// Assign solver (generator takes over ownership) + void assignSolver(OsiSolverInterface * fakeSolver); +protected: + /// fake solver to use + OsiSolverInterface * fakeSolver_; + /// Probing object + CglProbing * probing_; +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglConfig.h b/thirdparty/linux/include/coin1/CglConfig.h new file mode 100644 index 0000000..bca5553 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglConfig.h @@ -0,0 +1,19 @@ +/* src/config_cgl.h. Generated by configure. */ +/* src/config_cgl.h.in. */ + +#ifndef __CONFIG_CGL_H__ +#define __CONFIG_CGL_H__ + +/* Version number of project */ +#define CGL_VERSION "0.59.4" + +/* Major Version number of project */ +#define CGL_VERSION_MAJOR 0 + +/* Minor Version number of project */ +#define CGL_VERSION_MINOR 59 + +/* Release Version number of project */ +#define CGL_VERSION_RELEASE 4 + +#endif diff --git a/thirdparty/linux/include/coin1/CglCutGenerator.hpp b/thirdparty/linux/include/coin1/CglCutGenerator.hpp new file mode 100644 index 0000000..7629140 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglCutGenerator.hpp @@ -0,0 +1,121 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglCutGenerator_H +#define CglCutGenerator_H + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" +#include "CglTreeInfo.hpp" + +//------------------------------------------------------------------- +// +// Abstract base class for generating cuts. +// +//------------------------------------------------------------------- +/// +/** Cut Generator Base Class + +This is an abstract base class for generating cuts. A specific cut +generator will inherit from this class. +*/ +class CglCutGenerator { + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate cuts for the model data contained in si. + The generated cuts are inserted into and returned in the + collection of cuts cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo())=0; + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglCutGenerator (); + + /// Copy constructor + CglCutGenerator ( const CglCutGenerator &); + + /// Clone + virtual CglCutGenerator * clone() const = 0; + + /// Assignment operator + CglCutGenerator & operator=(const CglCutGenerator& rhs); + + /// Destructor + virtual ~CglCutGenerator (); + + /** Create C++ lines to set the generator in the current state. + The output must be parsed by the calling code, as each line + starts with a key indicating the following:<BR> + 0: must be kept (for #includes etc)<BR> + 3: Set to changed (not default) values<BR> + 4: Set to default values (redundant)<BR> + + Keys 1, 2, 5, 6, 7, 8 are defined, but not applicable to + cut generators. + */ + virtual std::string generateCpp( FILE * ) {return "";} + + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * ) {} + //@} + + /**@name Gets and Sets */ + //@{ + /** + Get Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + inline int getAggressiveness() const + { return aggressive_;} + + /** + Set Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + inline void setAggressiveness(int value) + { aggressive_=value;} + /// Set whether can do global cuts + inline void setGlobalCuts(bool trueOrFalse) + { canDoGlobalCuts_ = trueOrFalse;} + /// Say whether can do global cuts + inline bool canDoGlobalCuts() const + {return canDoGlobalCuts_;} + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const; + /// Return true if needs optimal basis to do cuts + virtual bool needsOptimalBasis() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const + { return COIN_INT_MAX;} + //@} + + // test this class + //static void unitTest(); + +// private: + + /** + Aggressiveness - 0 = neutral, 100 is normal root node. + Really just a hint to cut generator + */ + int aggressive_; + /// True if can do global cuts i.e. no general integers + bool canDoGlobalCuts_; +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglDuplicateRow.hpp b/thirdparty/linux/include/coin1/CglDuplicateRow.hpp new file mode 100644 index 0000000..b40f969 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglDuplicateRow.hpp @@ -0,0 +1,189 @@ +// $Id: CglDuplicateRow.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglDuplicateRow_H +#define CglDuplicateRow_H + +#include <string> + +#include "CglCutGenerator.hpp" +class CglStored; + +/** DuplicateRow Cut Generator Class */ +class CglDuplicateRow : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Fix variables and find duplicate/dominated rows for the model of the + solver interface, si. + + This is a very simple minded idea but I (JJF) am using it in a project so thought + I might as well add it. It should really be called before first solve and I may + modify CBC to allow for that. + + This is designed for problems with few rows and many integer variables where the rhs + are <= or == and all coefficients and rhs are small integers. + + If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds + (effective rhs just means original with variables with nonzero lower bounds subtracted out). + + If one row is a subset of another and the effective rhs are same we can fix some variables + and then the two rows are identical. + + The generator marks identical rows so can be taken out in solve + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); +private: + /// Does work for modes 1,2 + void generateCuts12( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Does work for mode 4 + void generateCuts4( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Does work for mode 8 + void generateCuts8( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); +public: + /** Fix variables and find duplicate/dominated rows for the model of the + solver interface, si. + + This is a very simple minded idea but I (JJF) am using it in a project so thought + I might as well add it. It should really be called before first solve and I may + modify CBC to allow for that. + + This is designed for problems with few rows and many integer variables where the rhs + are <= or == and all coefficients and rhs are small integers. + + If effective rhs is K then we can fix all variables with coefficients > K to their lower bounds + (effective rhs just means original with variables with nonzero lower bounds subtracted out). + + If one row is a subset of another and the effective rhs are same we can fix some variables + and then the two rows are identical. + + This version does deletions and fixings and may return stored cuts for + dominated columns + */ + CglStored * outDuplicates( OsiSolverInterface * solver); + + //@} + + /**@name Get information on size of problem */ + //@{ + /// Get duplicate row list, -1 means still in, -2 means out (all fixed), k>= means same as row k + inline const int * duplicate() const + { return duplicate_;} + /// Size of dynamic program + inline int sizeDynamic() const + { return sizeDynamic_;} + /// Number of rows in original problem + inline int numberOriginalRows() const + { return matrix_.getNumRows();} + //@} + + /**@name Get information on size of problem */ + //@{ + /// logLevel + inline int logLevel() const + { return logLevel_;} + inline void setLogLevel(int value) + { logLevel_ = value;} + //@} + + + /**@name We only check for duplicates amongst rows with effective rhs <= this */ + //@{ + /// Get + inline int maximumRhs() const + { return maximumRhs_;} + /// Set + inline void setMaximumRhs(int value) + { maximumRhs_=value;} + //@} + + /**@name We only check for dominated amongst groups of columns whose size <= this */ + //@{ + /// Get + inline int maximumDominated() const + { return maximumDominated_;} + /// Set + inline void setMaximumDominated(int value) + { maximumDominated_=value;} + //@} + /**@name gets and sets */ + //@{ + /// Get mode + inline int mode() const + { return mode_;} + /// Set mode + inline void setMode(int value) + { mode_=value;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglDuplicateRow (); + + /// Useful constructor + CglDuplicateRow (OsiSolverInterface * solver); + + /// Copy constructor + CglDuplicateRow ( + const CglDuplicateRow & rhs); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglDuplicateRow & + operator=( + const CglDuplicateRow& rhs); + + /// Destructor + virtual + ~CglDuplicateRow (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +protected: + + + // Protected member data + + /**@name Protected member data */ + //@{ + /// Matrix + CoinPackedMatrix matrix_; + /// Matrix by row + CoinPackedMatrix matrixByRow_; + /// Possible rhs (if 0 then not possible) + int * rhs_; + /// Marks duplicate rows + int * duplicate_; + /// To allow for <= rows + int * lower_; + /// Stored cuts if we found dominance cuts + CglStored * storedCuts_; + /// Check dominated columns if less than this number of candidates + int maximumDominated_; + /// Check duplicates if effective rhs <= this + int maximumRhs_; + /// Size of dynamic program + int sizeDynamic_; + /// 1 do rows, 2 do columns, 3 do both + int mode_; + /// Controls print out + int logLevel_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglFlowCover.hpp b/thirdparty/linux/include/coin1/CglFlowCover.hpp new file mode 100644 index 0000000..eea070f --- /dev/null +++ b/thirdparty/linux/include/coin1/CglFlowCover.hpp @@ -0,0 +1,371 @@ +// $Id: CglFlowCover.hpp 1119 2013-04-06 20:24:18Z stefan $ +//----------------------------------------------------------------------------- +// name: Cgl Lifted Simple Generalized Flow Cover Cut Generator +// author: Yan Xu email: yan.xu@sas.com +// Jeff Linderoth email: jtl3@lehigh.edu +// Martin Savelsberg email: martin.savelsbergh@isye.gatech.edu +// date: 05/01/2003 +// comments: please scan this file for '???' and read the comments +//----------------------------------------------------------------------------- +// Copyright (C) 2003, Yan Xu, Jeff Linderoth, Martin Savelsberg and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglFlowCover_H +#define CglFlowCover_H + +#include <iostream> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +//============================================================================= + +/** This enumerative constant describes the various col types.*/ +enum CglFlowColType { + /** The column(variable) is a negative binary variable.*/ + CGLFLOW_COL_BINNEG = -2, + /** The column is a negative continous variable.*/ + CGLFLOW_COL_CONTNEG, + /** The column is a positive continous variable.*/ + CGLFLOW_COL_CONTPOS = 1, + /** The column is a positive binary variable.*/ + CGLFLOW_COL_BINPOS +}; + +enum CglFlowColStatus{ +}; + +/** This enumerative constant describes the various stati of vars in + a cut or not.*/ +enum CglFlowColCut{ + /** The column is NOT in cover.*/ + CGLFLOW_COL_OUTCUT = 0, + /** The column is in cover now. */ + CGLFLOW_COL_INCUT, + /** The column is decided to be in cover. */ + CGLFLOW_COL_INCUTDONE, + /** The column is in L-. */ + CGLFLOW_COL_INLMIN, + /** The column is decided to be in L-. */ + CGLFLOW_COL_INLMINDONE, + /** The column is in L--.*/ + CGLFLOW_COL_INLMINMIN, + /** This enumerative constant describes the various stati of vars in + determining the cover.*/ + /** The column is a prime candidate. */ + CGLFLOW_COL_PRIME, + /** The column is a secondary candidate. */ + CGLFLOW_COL_SECONDARY +}; + +/** This enumerative constant describes the various row types.*/ +enum CglFlowRowType { + /** The row type of this row is NOT defined yet.*/ + CGLFLOW_ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is continous, and the RHS + is zero.*/ + CGLFLOW_ROW_VARUB, + /** After the row is flipped to 'L', the row has exactlytwo variables: + one is positive binary and the other is continous, and the RHS + is zero.*/ + CGLFLOW_ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + CGLFLOW_ROW_VAREQ, + /** Rows can not be classfied into other types and the row sense + is NOT 'E'.*/ + CGLFLOW_ROW_MIXUB, + /** Rows can not be classfied into other types and the row sense is 'E'.*/ + CGLFLOW_ROW_MIXEQ, + /** All variables are NOT binary and the row sense is NOT 'E'. */ + CGLFLOW_ROW_NOBINUB, + /** All variables are NOT binary and the row sense is 'E'. */ + CGLFLOW_ROW_NOBINEQ, + /** The row has one binary and 2 or more other types of variables and + the row sense is NOT 'E'. */ + CGLFLOW_ROW_SUMVARUB, + /** The row has one binary and 2 or more other types of variables and + the row sense is 'E'. */ + CGLFLOW_ROW_SUMVAREQ, + /** All variables are binary. */ + CGLFLOW_ROW_UNINTERSTED +}; + +//============================================================================= + +/** Variable upper bound class. */ +class CglFlowVUB +{ +protected: + int varInd_; /** The index of the associated 0-1 variable.*/ + double upper_; /** The Value of the associated upper bound.*/ + +public: + CglFlowVUB() : varInd_(-1), upper_(-1) {} + + CglFlowVUB(const CglFlowVUB& source) { + varInd_= source.varInd_; + upper_ = source.upper_; + } + + CglFlowVUB& operator=(const CglFlowVUB& rhs) { + if (this == &rhs) + return *this; + varInd_= rhs.varInd_; + upper_ = rhs.upper_; + return *this; + } + + /**@name Query and set functions for associated 0-1 variable index + and value. + */ + //@{ + inline int getVar() const { return varInd_; } + inline double getVal() const { return upper_; } + inline void setVar(const int v) { varInd_ = v; } + inline void setVal(const double v) { upper_ = v; } + //@} +}; + +//============================================================================= + +/** Variable lower bound class, which is the same as vub. */ +typedef CglFlowVUB CglFlowVLB; + +/** Overloaded operator<< for printing VUB and VLB.*/ +std::ostream& operator<<( std::ostream& os, const CglFlowVUB &v ); + +//============================================================================= + +/** + * Lifed Simple Generalized Flow Cover Cut Generator Class. + */ +class CglFlowCover : public CglCutGenerator { + friend void CglFlowCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /** + * Do the following tasks: + * <ul> + * <li> classify row types + * <li> indentify vubs and vlbs + * </ul> + * This function is called by + * <CODE>generateCuts(const OsiSolverInterface & si, OsiCuts & cs)</CODE>. + */ + void flowPreprocess(const OsiSolverInterface& si); + + /**@name Generate Cuts */ + //@{ + /** Generate Lifed Simple Generalized flow cover cuts for the model data + contained in si. The generated cuts are inserted into and returned + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Functions to query and set maximum number of cuts can be + generated. */ + //@{ + inline int getMaxNumCuts() const { return maxNumCuts_; } + inline void setMaxNumCuts(int mc) { maxNumCuts_ = mc; } + //@} + + /**@name Functions to query and set the number of cuts have been + generated. */ + //@{ + static int getNumFlowCuts() { return numFlowCuts_; } + static void setNumFlowCuts(int fc) { numFlowCuts_ = fc; } + static void incNumFlowCuts(int fc = 1) { numFlowCuts_ += fc; } + //@} + + //------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglFlowCover (); + + /// Copy constructor + CglFlowCover ( + const CglFlowCover &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglFlowCover & + operator=( + const CglFlowCover& rhs); + + /// Destructor + virtual + ~CglFlowCover (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + //------------------------------------------------------------------------- + // Private member functions + + /** Based a given row, a LP solution and other model data, this function + tries to generate a violated lifted simple generalized flow cover. + */ + bool generateOneFlowCut( const OsiSolverInterface & si, + const int rowLen, + int* ind, + double* coef, + char sense, + double rhs, + OsiRowCut& flowCut, + double& violation ); + + + /** Transform a row from ">=" to "<=", and vice versa. */ + void flipRow(int rowLen, double* coef, double& rhs) const; + + /** Transform a row from ">=" to "<=", and vice versa. Have 'sense'. */ + void flipRow(int rowLen, double* coef, char& sen, double& rhs) const; + + /** Determine the type of a given row. */ + CglFlowRowType determineOneRowType(const OsiSolverInterface& si, + int rowLen, int* ind, + double* coef, char sen, + double rhs) const; + /** Lift functions */ + void liftMinus(double &movement, /* Output */ + int t, + int r, + double z, + double dPrimePrime, + double lambda, + double ml, + double *M, + double *rho) const; + + bool liftPlus(double &alpha, + double &beta, + int r, + double m_j, + double lambda, + double y_j, + double x_j, + double dPrimePrime, + double *M) const; + + + //------------------------------------------------------------------------- + //**@name Query and set the row type of a givne row. */ + //@{ + inline const CglFlowRowType* getRowTypes() const + { return rowTypes_; } + inline CglFlowRowType getRowType(const int i) const + { return rowTypes_[i]; } + /** Set rowtypes, take over the ownership. */ + inline void setRowTypes(CglFlowRowType* rt) + { rowTypes_ = rt; rt = 0; } + inline void setRowTypes(const CglFlowRowType rt, const int i) { + if (rowTypes_ != 0) + rowTypes_[i] = rt; + else { + std::cout << "ERROR: Should allocate memory for rowType_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for rowType_", + "setRowType", "CglFlowCover"); + } + } + //@} + + //------------------------------------------------------------------------- + //**@name Query and set vubs. */ + //@{ + inline const CglFlowVUB* getVubs() const { return vubs_; } + inline const CglFlowVUB& getVubs(int i) const { return vubs_[i]; } + /** Set CglFlowVUBs,take over the ownership. */ + inline void setVubs(CglFlowVUB* vubs) { vubs_ = vubs; vubs = 0; } + inline void setVubs(const CglFlowVUB& vub, int i) { + if (vubs_ != 0) + vubs_[i] = vub; + else { + std::cout << "ERROR: Should allocate memory for vubs_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for vubs_", "setVubs", + "CglFlowCover"); + } + } + inline void printVubs(std::ostream& os) const { + for (int i = 0; i < numCols_; ++i) { + os << "ix: " << i << ", " << vubs_[i]; + } + } + //@} + + //------------------------------------------------------------------------- + //**@name Query and set vlbs. */ + //@{ + inline const CglFlowVLB* getVlbs() const { return vlbs_; } + inline const CglFlowVLB& getVlbs(int i) const { return vlbs_[i]; } + /** Set CglFlowVLBs,take over the ownership. */ + inline void setVlbs(CglFlowVLB* vlbs) { vlbs_ = vlbs; vlbs = 0; } + inline void setVlbs(const CglFlowVLB& vlb, int i) { + if (vlbs_ != 0) + vlbs_[i] = vlb; + else { + std::cout << "ERROR: Should allocate memory for vlbs_ before " + << "using it " << std::endl; + throw CoinError("Forgot to allocate memory for vlbs_", "setVlbs", + "CglFlowCover"); + } + } + //@} + +private: + //------------------------------------------------------------------------ + // Private member data + + /** The maximum number of flow cuts to be generated. Default is 1000. */ + int maxNumCuts_; + /** Tolerance used for numerical purpose. */ + double EPSILON_; + /** The variable upper bound of a flow is not indentified yet.*/ + int UNDEFINED_; + /** Very large number. */ + double INFTY_; + /** If violation of a cut is greater that this number, the cut is useful.*/ + double TOLERANCE_; + /** First time preprocessing */ + bool firstProcess_; + /** The number rows of the problem.*/ + int numRows_; + /** The number columns of the problem.*/ + int numCols_; + /** The number flow cuts found.*/ + static int numFlowCuts_; + /** Indicate whether initial flow preprecessing has been done. */ + bool doneInitPre_; + /** The array of CglFlowVUBs. */ + CglFlowVUB* vubs_; + /** The array of CglFlowVLBs. */ + CglFlowVLB* vlbs_; + /** CglFlowRowType of the rows in model. */ + CglFlowRowType* rowTypes_; +}; + +//############################################################################# +/** A function that tests the methods in the CglFlowCover class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglFlowCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglGMI.hpp b/thirdparty/linux/include/coin1/CglGMI.hpp new file mode 100644 index 0000000..240f6ad --- /dev/null +++ b/thirdparty/linux/include/coin1/CglGMI.hpp @@ -0,0 +1,364 @@ +// Last edit: 02/05/2013 +// +// Name: CglGMI.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design, Singapore +// email: nannicini@sutd.edu.sg +// Date: 11/17/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2009, Giacomo Nannicini. All Rights Reserved. + +#ifndef CglGMI_H +#define CglGMI_H + +#include "CglCutGenerator.hpp" +#include "CglGMIParam.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CoinFactorization.hpp" + +/* Enable tracking of rejection of cutting planes. If this is disabled, + the cut generator is slightly faster. If defined, it enables proper use + of setTrackRejection and related functions. */ +//#define TRACK_REJECT + +/* Debug output */ +//#define GMI_TRACE + +/* Debug output: print optimal tableau */ +//#define GMI_TRACETAB + +/* Print reason for cut rejection, whenever a cut is discarded */ +//#define GMI_TRACE_CLEAN + +/** Gomory cut generator with several cleaning procedures, used to test + * the numerical safety of the resulting cuts + */ + +class CglGMI : public CglCutGenerator { + + friend void CglGMIUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + + /** Public enum: all possible reasons for cut rejection */ + enum RejectionType{ + failureFractionality, + failureDynamism, + failureViolation, + failureSupport, + failureScale + }; + + /**@name generateCuts */ + //@{ + /** Generate Gomory Mixed-Integer cuts for the model of the solver + interface si. + + Insert the generated cuts into OsiCuts cs. + + Warning: This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau and + optimal basis inverse and makes assumptions on the way slack variables + are added by the solver. The Osi implementations for Clp and Cplex + verify these assumptions. + + When calling the generator, the solver interface si must contain + an optimized problem and information related to the optimal + basis must be available through the OsiSolverInterface methods + (si->optimalBasisIsAvailable() must return 'true'). It is also + essential that the integrality of structural variable i can be + obtained using si->isInteger(i). + + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const { return true; } + //@} + + /**@name Common Methods */ + //@{ + // Function for checking equality with user tolerance + inline bool areEqual(double x, double y, + double epsAbs = 1e-12, + double epsRel = 1e-12) { + return (fabs((x) - (y)) <= + std::max(epsAbs, epsRel * std::max(fabs(x), fabs(y)))); + } + + // Function for checking is a number is zero + inline bool isZero(double x, double epsZero = 1e-20) { + return (fabs(x) <= epsZero); + } + + + // Function for checking if a number is integer + inline bool isIntegerValue(double x, + double intEpsAbs = 1e-9, + double intEpsRel = 1e-15) { + return (fabs((x) - floor((x)+0.5)) <= + std::max(intEpsAbs, intEpsRel * fabs(x))); + } + + + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglGMIParam object. + void setParam(const CglGMIParam &source); + // Return the CglGMIParam object of the generator. + inline CglGMIParam getParam() const {return param;} + inline CglGMIParam & getParam() {return param;} + + // Compute entries of is_integer. + void computeIsInteger(); + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + /// Set/get tracking of the rejection of cutting planes. + /// Note that all rejection related functions will not do anything + /// unless the generator is compiled with the define GMI_TRACK_REJECTION + void setTrackRejection(bool value); + bool getTrackRejection(); + + /// Get number of cuts rejected for given reason; see above + int getNumberRejectedCuts(RejectionType reason); + + /// Reset counters for cut rejection tracking; see above + void resetRejectionCounters(); + + /// Get total number of generated cuts since last resetRejectionCounters() + int getNumberGeneratedCuts(); + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGMI(); + + /// Constructor with specified parameters + CglGMI(const CglGMIParam ¶m); + + /// Copy constructor + CglGMI(const CglGMI &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglGMI & operator=(const CglGMI& rhs); + + /// Destructor + virtual ~CglGMI(); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglGMI members are properly set. + void generateCuts(OsiCuts & cs); + + /// Compute the fractional part of value, allowing for small error. + inline double aboveInteger(double value) const; + + /// Compute the fractionalities involved in the cut, and the cut rhs. + /// Returns true if cut is accepted, false if discarded + inline bool computeCutFractionality(double varRhs, double& cutRhs); + + /// Compute the cut coefficient on a given variable + inline double computeCutCoefficient(double rowElem, int index); + + /// Use multiples of the initial inequalities to cancel out the coefficient + /// on a slack variables. + inline void eliminateSlack(double cutElem, int cutIndex, double* cut, + double& cutRhs, const double *elements, + const int *rowStart, const int *indices, + const int *rowLength, const double *rhs); + + /// Change the sign of the coefficients of the non basic + /// variables at their upper bound. + inline void flip(double& rowElem, int rowIndex); + + /// Change the sign of the coefficients of the non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. Two functions: one for original variables, one for slacks. + inline void unflipOrig(double& rowElem, int rowIndex, double& rowRhs); + inline void unflipSlack(double& rowElem, int rowIndex, double& rowRhs, + const double* slack_val); + + /// Pack a row of ncol elements + inline void packRow(double* row, double* rowElem, int* rowIndex, + int& rowNz); + + /// Clean the cutting plane; the cleaning procedure does several things + /// like removing small coefficients, scaling, and checks several + /// acceptance criteria. If this returns false, the cut should be discarded. + /// There are several cleaning procedures available, that can be selected + /// via the parameter param.setCLEANING_PROCEDURE(int value) + bool cleanCut(double* cutElem, int* cutIndex, int& cutNz, + double& cutRhs, const double* xbar); + + /// Cut cleaning procedures: return true if successfull, false if + /// cut should be discarded by the caller of if problems encountered + + /// Check the violation + bool checkViolation(const double* cutElem, const int* cutIndex, + int cutNz, double cutrhs, const double* xbar); + + /// Check the dynamism + bool checkDynamism(const double* cutElem, const int* cutIndex, + int cutNz); + + /// Check the support + bool checkSupport(int cutNz); + + /// Remove small coefficients and adjust the rhs accordingly + bool removeSmallCoefficients(double* cutElem, int* cutIndex, + int& cutNz, double& cutRhs); + + /// Adjust the rhs by relaxing by a small amount (relative or absolute) + void relaxRhs(double& rhs); + + /// Scale the cutting plane in different ways; + /// scaling_type possible values: + /// 0 : scale to obtain integral cut + /// 1 : scale based on norm, to obtain cut norm equal to ncol + /// 2 : scale to obtain largest coefficient equal to 1 + bool scaleCut(double* cutElem, int* cutIndex, int cutNz, + double& cutRhs, int scalingType); + + /// Scale the cutting plane in order to generate integral coefficients + bool scaleCutIntegral(double* cutElem, int* cutIndex, int cutNz, + double& cutRhs); + + /// Compute the nearest rational number; used by scale_row_integral + bool nearestRational(double val, double maxdelta, long maxdnom, + long& numerator, long& denominator); + + /// Compute the greatest common divisor + long computeGcd(long a, long b); + + /// print a vector of integers + void printvecINT(const char *vecstr, const int *x, int n) const; + /// print a vector of doubles: dense form + void printvecDBL(const char *vecstr, const double *x, int n) const; + /// print a vector of doubles: sparse form + void printvecDBL(const char *vecstr, const double *elem, const int * index, + int nz) const; + + /// Recompute the simplex tableau for want of a better accuracy. + /// Requires an empty CoinFactorization object to do the computations, + /// and two empty (already allocated) arrays which will contain + /// the basis indices on exit. Returns 0 if successfull. + int factorize(CoinFactorization & factorization, + int* colBasisIndex, int* rowBasisIndex); + + + //@} + + + // Private member data + +/**@name Private member data */ + + //@{ + + /// Object with CglGMIParam members. + CglGMIParam param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + bool *isInteger; + + /// Current basis status: columns + int *cstat; + + /// Current basis status: rows + int *rstat; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + /// Pointer on matrix of coefficient ordered by columns. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byCol; + + /// Fractionality of the cut and related quantities. + double f0; + double f0compl; + double ratiof0compl; + +#if defined(TRACK_REJECT) || defined (TRACK_REJECT_SIMPLE) + /// Should we track the reason of each cut rejection? + bool trackRejection; + /// Number of failures by type + int fracFail; + int dynFail; + int violFail; + int suppFail; + int smallCoeffFail; + int scaleFail; + /// Total number of generated cuts + int numGeneratedCuts; +#endif + + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglGMI class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglGMIUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin1/CglGMIParam.hpp b/thirdparty/linux/include/coin1/CglGMIParam.hpp new file mode 100644 index 0000000..a1aae41 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglGMIParam.hpp @@ -0,0 +1,313 @@ +// Name: CglGMIParam.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// email: nannicini@sutd.edu.sg +// based on CglRedSplitParam.hpp by Francois Margot +// Date: 11/17/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2009, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglGMIParam_H +#define CglGMIParam_H + +#include "CglParam.hpp" + + + /**@name CglGMI Parameters */ + //@{ + + /** Class collecting parameters for the GMI cut generator. + + Parameters of the generator are listed below. Modifying the default + values for parameters other than the last four might result in + invalid cuts. + + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - USE_INTSLACKS: Use integer slacks to generate cuts. + (not implemented yet, will be in the future). + See method setUSE_INTSLACKS(). + - AWAY: Look only at basic integer variables whose current value is at + least this value away from being integer. See method setAway(). + - CHECK_DUPLICATES: Should we check for duplicates when adding a cut + to the collection? Can be slow. + Default 0 - do not check, add cuts anyway. + - CLEAN_PROC: Cleaning procedure that should be used. Look below at the + enumeration CleaningProcedure for possible values. + - INTEGRAL_SCALE_CONT: If we try to scale cut coefficients so that + they become integral, do we also scale on + continuous variables? + Default 0 - do not scale continuous vars. + Used only if CLEAN_PROC does integral scaling. + - ENFORCE_SCALING: Discard badly scaled cuts, or keep them (unscaled). + Default 1 - yes. + + */ + //@} + +class CglGMIParam : public CglParam { + +public: + + /**@name Enumerations */ + enum CleaningProcedure{ + /* CglLandP procedure I */ + CP_CGLLANDP1, + /* CglLandP procedure II */ + CP_CGLLANDP2, + /* CglRedSplit procedure I */ + CP_CGLREDSPLIT, + /* Only integral cuts, i.e. cuts with integral coefficients */ + CP_INTEGRAL_CUTS, + /* CglLandP procedure I with integral scaling */ + CP_CGLLANDP1_INT, + /* CglLandP procedure I with scaling of the max element to 1 if possible */ + CP_CGLLANDP1_SCALEMAX, + /* CglLandP procedure I with scaling of the rhs to 1 if possible */ + CP_CGLLANDP1_SCALERHS + }; + + /**@name Set/get methods */ + + //@{ + /** Aliases for parameter get/set method in the base class CglParam */ + + /** Value for Infinity. Default: DBL_MAX */ + inline void setInfinity(double value) {setINFINIT(value);} + inline double getInfinity() const {return INFINIT;} + + /** Epsilon for comparing numbers. Default: 1.0e-6 */ + inline void setEps(double value) {setEPS(value);} + inline double getEps() const {return EPS;} + + /** Epsilon for zeroing out coefficients. Default: 1.0e-5 */ + inline void setEpsCoeff(double value) {setEPS_COEFF(value);} + inline double getEpsCoeff() const {return EPS_COEFF;} + + /** Maximum support of the cutting planes. Default: INT_MAX */ + inline void setMaxSupport(int value) {setMAX_SUPPORT(value);} + inline int getMaxSupport() const {return MAX_SUPPORT;} + /** Alias for consistency with our naming scheme */ + inline void setMaxSupportAbs(int value) {setMAX_SUPPORT(value);} + inline int getMaxSupportAbs() const {return MAX_SUPPORT;} + inline int getMAX_SUPPORT_ABS() const {return MAX_SUPPORT;} + + /** Set AWAY, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.005 */ + virtual void setAway(double value); + /** Get value of away */ + inline double getAway() const {return AWAY;} + /// Aliases + inline void setAWAY(double value) {setAway(value);} + inline double getAWAY() const {return AWAY;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 0 */ + virtual void setEPS_ELIM(double value); + /** Get the value of EPS_ELIM */ + inline double getEPS_ELIM() const {return EPS_ELIM;} + /// Aliases + inline void setEpsElim(double value) {setEPS_ELIM(value);} + inline double getEpsElim() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(double value); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + /// Aliases + inline void setEpsRelaxAbs(double value) {setEPS_RELAX_ABS(value);} + inline double getEpsRelaxAbs() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(double value); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + /// Aliases + inline void setEpsRelaxRel(double value) {setEPS_RELAX_REL(value);} + inline double getEpsRelaxRel() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN;} + /// Aliases + inline void setMaxDyn(double value) {setMAXDYN(value);} + inline double getMaxDyn() const {return MAXDYN;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-7 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + /// Aliases + inline void setMinViol(double value) {setMINVIOL(value);} + inline double getMinViol() const {return MINVIOL;} + + /** Set the value of MAX_SUPPORT_REL, the factor contributing to the + maximum support relative to the number of columns. Maximum + allowed support is: MAX_SUPPORT_ABS + + MAX_SUPPORT_REL*ncols. Default: 0.1 */ + virtual void setMAX_SUPPORT_REL(double value); + /** Get the value of MINVIOL */ + inline double getMAX_SUPPORT_REL() const {return MAX_SUPPORT_REL;} + /// Aliases + inline void setMaxSupportRel(double value) {setMAX_SUPPORT_REL(value);} + inline double getMaxSupportRel() const {return MAX_SUPPORT_REL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(bool value); + /** Get the value of USE_INTSLACKS */ + inline bool getUSE_INTSLACKS() const {return USE_INTSLACKS;} + /// Aliases + inline void setUseIntSlacks(bool value) {setUSE_INTSLACKS(value);} + inline int getUseIntSlacks() const {return USE_INTSLACKS;} + + /** Set the value of CHECK_DUPLICATES. Default: 0 */ + virtual void setCHECK_DUPLICATES(bool value); + /** Get the value of CHECK_DUPLICATES */ + inline bool getCHECK_DUPLICATES() const {return CHECK_DUPLICATES;} + /// Aliases + inline void setCheckDuplicates(bool value) {setCHECK_DUPLICATES(value);} + inline bool getCheckDuplicates() const {return CHECK_DUPLICATES;} + + /** Set the value of CLEAN_PROC. Default: CP_CGLLANDP1 */ + virtual void setCLEAN_PROC(CleaningProcedure value); + /** Get the value of CLEAN_PROC. */ + inline CleaningProcedure getCLEAN_PROC() const {return CLEAN_PROC;} + /// Aliases + inline void setCleanProc(CleaningProcedure value) {setCLEAN_PROC(value);} + inline CleaningProcedure getCleaningProcedure() const {return CLEAN_PROC;} + + /** Set the value of INTEGRAL_SCALE_CONT. Default: 0 */ + virtual void setINTEGRAL_SCALE_CONT(bool value); + /** Get the value of INTEGRAL_SCALE_CONT. */ + inline bool getINTEGRAL_SCALE_CONT() const {return INTEGRAL_SCALE_CONT;} + /// Aliases + inline void setIntegralScaleCont(bool value) {setINTEGRAL_SCALE_CONT(value);} + inline bool getIntegralScaleCont() const {return INTEGRAL_SCALE_CONT;} + + /** Set the value of ENFORCE_SCALING. Default: 1 */ + virtual void setENFORCE_SCALING(bool value); + /** Get the value of ENFORCE_SCALING. */ + inline bool getENFORCE_SCALING() const {return ENFORCE_SCALING;} + /// Aliases + inline void setEnforceScaling(bool value) {setENFORCE_SCALING(value);} + inline bool getEnforcescaling() const {return ENFORCE_SCALING;} + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGMIParam(double eps = 1e-12, + double away = 0.005, + double eps_coeff = 1e-11, + double eps_elim = 0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-4, + int max_supp_abs = 1000, + double max_supp_rel = 0.1, + CleaningProcedure clean_proc = CP_CGLLANDP1, + bool use_int_slacks = false, + bool check_duplicates = false, + bool integral_scale_cont = false, + bool enforce_scaling = true); + + /// Constructor from CglParam + CglGMIParam(CglParam &source, + double away = 0.005, + double eps_elim = 1e-12, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-4, + double max_supp_rel = 0.1, + CleaningProcedure clean_proc = CP_CGLLANDP1, + bool use_int_slacks = false, + bool check_duplicates = false, + bool integral_scale_cont = false, + bool enforce_scaling = true); + + /// Copy constructor + CglGMIParam(const CglGMIParam &source); + + /// Clone + virtual CglGMIParam* clone() const; + + /// Assignment operator + virtual CglGMIParam& operator=(const CglGMIParam &rhs); + + /// Destructor + virtual ~CglGMIParam(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Use row only if pivot variable should be integer but is more + than AWAY from being integer. */ + double AWAY; + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 0. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-11 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 1.e-13 */ + double EPS_RELAX_REL; + + /** Maximum ratio between largest and smallest non zero + coefficients in a cut. Default: 1e6. */ + double MAXDYN; + + /** Minimum violation for the current basic solution in a generated cut. + Default: 1e-4. */ + double MINVIOL; + + /** Maximum support relative to number of columns. Must be between 0 + and 1. Default: 0. */ + double MAX_SUPPORT_REL; + + /** Which cleaning procedure should be used? */ + CleaningProcedure CLEAN_PROC; + + /** Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. */ + bool USE_INTSLACKS; + + /** Check for duplicates when adding the cut to the collection? */ + bool CHECK_DUPLICATES; + + /** Should we try to rescale cut coefficients on continuous variables + so that they become integral, or do we only rescale coefficients + on integral variables? Used only by cleaning procedure that try + the integral scaling. */ + bool INTEGRAL_SCALE_CONT; + + /** Should we discard badly scaled cuts (according to the scaling + procedure in use)? If false, CglGMI::scaleCut always returns + true, even though it still scales cuts whenever possible, but + not cut is rejected for scaling. Default true. Used only by + cleaning procedure that try to scale. */ + bool ENFORCE_SCALING; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglGomory.hpp b/thirdparty/linux/include/coin1/CglGomory.hpp new file mode 100644 index 0000000..2d7f5c5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglGomory.hpp @@ -0,0 +1,204 @@ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglGomory_H +#define CglGomory_H + +#include <string> + +#include "CglCutGenerator.hpp" + +class CoinWarmStartBasis; +/** Gomory Cut Generator Class */ +class CglGomory : public CglCutGenerator { + friend void CglGomoryUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Gomory cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + There is a limit option, which will only generate cuts with + less than this number of entries. + + We can also only look at 0-1 variables a certain distance + from integer. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /** Generates cuts given matrix and solution etc, + returns number of cuts generated */ + int generateCuts( const OsiRowCutDebugger * debugger, + OsiCuts & cs, + const CoinPackedMatrix & columnCopy, + const CoinPackedMatrix & rowCopy, + const double * colsol, + const double * colLower, const double * colUpper, + const double * rowLower, const double * rowUpper, + const char * intVar , + const CoinWarmStartBasis* warm, + const CglTreeInfo info = CglTreeInfo()); + /** Generates cuts given matrix and solution etc, + returns number of cuts generated (no row copy passed in) */ + int generateCuts( const OsiRowCutDebugger * debugger, + OsiCuts & cs, + const CoinPackedMatrix & columnCopy, + const double * colsol, + const double * colLower, const double * colUpper, + const double * rowLower, const double * rowUpper, + const char * intVar , + const CoinWarmStartBasis* warm, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const { return true; } + //@} + + /**@name Change way Gomory works */ + //@{ + /// Pass in a copy of original solver (clone it) + void passInOriginalSolver(OsiSolverInterface * solver); + /// Returns original solver + inline OsiSolverInterface * originalSolver() const + { return originalSolver_;} + /// Set type - 0 normal, 1 add original matrix one, 2 replace + inline void setGomoryType(int type) + { gomoryType_=type;} + /// Return type + inline int gomoryType() const + { return gomoryType_;} + //@} + + /**@name Change limit on how many variables in cut (default 50) */ + //@{ + /// Set + void setLimit(int limit); + /// Get + int getLimit() const; + /// Set at root (if <normal then use normal) + void setLimitAtRoot(int limit); + /// Get at root + int getLimitAtRoot() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const; + //@} + + /**@name Change criterion on which variables to look at. All ones + more than "away" away from integrality will be investigated + (default 0.05) */ + //@{ + /// Set away + void setAway(double value); + /// Get away + double getAway() const; + /// Set away at root + void setAwayAtRoot(double value); + /// Get away at root + double getAwayAtRoot() const; + //@} + + /**@name Change criterion on which the cut id relaxed if the code + thinks the factorization has inaccuracies. The relaxation to + RHS is smallest of - + 1) 1.0e-4 + 2) conditionNumberMultiplier * condition number of factorization + 3) largestFactorMultiplier * largest (dual*element) forming tableau + row + */ + //@{ + /// Set ConditionNumberMultiplier + void setConditionNumberMultiplier(double value); + /// Get ConditionNumberMultiplier + double getConditionNumberMultiplier() const; + /// Set LargestFactorMultiplier + void setLargestFactorMultiplier(double value); + /// Get LargestFactorMultiplier + double getLargestFactorMultiplier() const; + //@} + + /**@name change factorization */ + //@{ + /// Set/unset alternative factorization + inline void useAlternativeFactorization(bool yes=true) + { alternateFactorization_= (yes) ? 1 : 0;} + /// Get whether alternative factorization being used + inline bool alternativeFactorization() const + { return (alternateFactorization_!=0);} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglGomory (); + + /// Copy constructor + CglGomory ( + const CglGomory &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglGomory & + operator=( + const CglGomory& rhs); + + /// Destructor + virtual + ~CglGomory (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + // Private member data + + /**@name Private member data */ + //@{ + /// Only investigate if more than this away from integrality + double away_; + /// Only investigate if more than this away from integrality (at root) + double awayAtRoot_; + /// Multiplier for conditionNumber cut relaxation + double conditionNumberMultiplier_; + /// Multiplier for largest factor cut relaxation + double largestFactorMultiplier_; + /// Original solver + OsiSolverInterface * originalSolver_; + /// Limit - only generate if fewer than this in cut + int limit_; + /// Limit - only generate if fewer than this in cut (at root) + int limitAtRoot_; + /// Dynamic limit in tree + int dynamicLimitInTree_; + /// Number of times stalled + int numberTimesStalled_; + /// nonzero to use alternative factorization + int alternateFactorization_; + /// Type - 0 normal, 1 add original matrix one, 2 replace + int gomoryType_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglGomory class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglGomoryUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglKnapsackCover.hpp b/thirdparty/linux/include/coin1/CglKnapsackCover.hpp new file mode 100644 index 0000000..b0e81d6 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglKnapsackCover.hpp @@ -0,0 +1,310 @@ +// $Id: CglKnapsackCover.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglKnapsackCover_H +#define CglKnapsackCover_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CglTreeInfo.hpp" + +/** Knapsack Cover Cut Generator Class */ +class CglKnapsackCover : public CglCutGenerator { + friend void CglKnapsackCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + /** A method to set which rows should be tested for knapsack covers */ + void setTestedRowIndices(int num, const int* ind); + + /**@name Generate Cuts */ + //@{ + /** Generate knapsack cover cuts for the model of the solver interface, si. + Insert the generated cuts into OsiCut, cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglKnapsackCover (); + + /// Copy constructor + CglKnapsackCover ( + const CglKnapsackCover &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglKnapsackCover & + operator=( + const CglKnapsackCover& rhs); + + /// Destructor + virtual + ~CglKnapsackCover (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + + + /**@name Sets and gets */ + //@{ + /// Set limit on number in knapsack + inline void setMaxInKnapsack(int value) + { if (value>0) maxInKnapsack_ = value;} + /// get limit on number in knapsack + inline int getMaxInKnapsack() const + {return maxInKnapsack_;} + /// Switch off expensive cuts + inline void switchOffExpensive() + { expensiveCuts_=false;} + /// Switch on expensive cuts + inline void switchOnExpensive() + { expensiveCuts_=true;} +private: + + // Private member methods + + + /**@name Private methods */ + //@{ + + /** deriveAKnapsack + returns 1 if it is able to derive + a (canonical) knapsack inequality + in binary variables of the form ax<=b + from the rowIndex-th row in the model, + returns 0 otherwise. + */ + int deriveAKnapsack( + const OsiSolverInterface & si, + OsiCuts & cs, + CoinPackedVector & krow, + bool treatAsLRow, + double & b, + int * complement, + double * xstar, + int rowIndex, + int numberElements, + const int * index, + const double * element); + + int deriveAKnapsack( + const OsiSolverInterface & si, + OsiCuts & cs, + CoinPackedVector & krow, + double & b, + int * complement, + double * xstar, + int rowIndex, + const CoinPackedVectorBase & matrixRow); + + /** Find a violated minimal cover from + a canonical form knapsack inequality by + solving the -most- violated cover problem + and postprocess to ensure minimality + */ + int findExactMostViolatedMinCover( + int nCols, + int row, + CoinPackedVector & krow, + double b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + + /** Find the most violate minimum cover by solving the lp-relaxation of the + most-violate-min-cover problem + */ + int findLPMostViolatedMinCover( + int nCols, + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + +/// find a minimum cover by a simple greedy approach + int findGreedyCover( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder + ); + + /// lift the cover inequality + int liftCoverCut( + double & b, + int nRowElem, + CoinPackedVector & cover, + CoinPackedVector & remainder, + CoinPackedVector & cut ); + + /// sequence-independent lift and uncomplement and add the resulting cut to the cut set + int liftAndUncomplementAndAdd( + double rowub, + CoinPackedVector & krow, + double & b, + int * complement, + int row, + CoinPackedVector & cover, + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// sequence-dependent lift, uncomplement and add the resulting cut to the cut set +void seqLiftAndUncomplementAndAdd( + int nCols, + double * xstar, + int * complement, + int row, + int nRowElem, + double & b, + CoinPackedVector & cover, // need not be violated + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// sequence-dependent lift binary variables either up or down, uncomplement and add to the cut set +void liftUpDownAndUncomplementAndAdd( + int nCols, + double * xstar, + int * complement, + int row, + int nRowElem, + double & b, + + // the following 3 packed vectors partition the krow: + CoinPackedVector & fracCover, // vars have frac soln values in lp relaxation + // and form cover with the vars atOne + CoinPackedVector & atOne, // vars have soln value of 1 in lp relaxation + // and together with fracCover form minimal (?) cover. + CoinPackedVector & remainder, + OsiCuts & cs ); + + /// find a cover using a variation of the logic found in OSL (w/o SOS) + int findPseudoJohnAndEllisCover ( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & cover, + CoinPackedVector & remainder); + + /// find a cover using the basic logic found in OSL (w/o SOS) + int findJohnAndEllisCover ( + int row, + CoinPackedVector & krow, + double & b, + double * xstar, + CoinPackedVector & fracCover, + CoinPackedVector & atOnes, + CoinPackedVector & remainder); + + + /** A C-style implementation of the Horowitz-Sahni exact solution + procedure for solving knapsack problem. + + (ToDo: implement the more efficient dynamic programming approach) + + (Reference: Martello and Toth, Knapsack Problems, Wiley, 1990, p30.) + */ + int exactSolveKnapsack( + int n, + double c, + double const *pp, + double const *ww, + double & z, + int * x); + /// For testing gub stuff + int gubifyCut(CoinPackedVector & cut); +public: + /** Creates cliques for use by probing. + Only cliques >= minimumSize and < maximumSize created + Can also try and extend cliques as a result of probing (root node). + Returns number of cliques found. + */ + int createCliques( OsiSolverInterface & si, + int minimumSize=2, int maximumSize=100, bool extendCliques=false); +private: + /// Delete all clique information + void deleteCliques(); + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// epsilon + double epsilon_; + /// Tolerance to use for violation - bigger than epsilon_ + double epsilon2_; + /// 1-epsilon + double onetol_; + /// Maximum in knapsack + int maxInKnapsack_; + /** which rows to look at. If specified, only these rows will be considered + for generating knapsack covers. Otherwise all rows will be tried */ + int numRowsToCheck_; + int* rowsToCheck_; + /// exactKnapsack can be expensive - this switches off some + bool expensiveCuts_; + /// Cliques + /// **** TEMP so can reference from listing + const OsiSolverInterface * solver_; + int whichRow_; + int * complement_; + double * elements_; + /// Number of cliques + int numberCliques_; + /// Clique type + typedef struct { + unsigned int equality:1; // nonzero if clique is == + } CliqueType; + CliqueType * cliqueType_; + /// Start of each clique + int * cliqueStart_; + /// Entries for clique + CliqueEntry * cliqueEntry_; + /** Start of oneFixes cliques for a column in matrix or -1 if not + in any clique */ + int * oneFixStart_; + /** Start of zeroFixes cliques for a column in matrix or -1 if not + in any clique */ + int * zeroFixStart_; + /// End of fixes for a column + int * endFixStart_; + /// Clique numbers for one or zero fixes + int * whichClique_; + /// Number of columns + int numberColumns_; + /** For each column with nonzero in row copy this gives a clique "number". + So first clique mentioned in row is always 0. If no entries for row + then no cliques. If sequence > numberColumns then not in clique. + */ + //CliqueEntry * cliqueRow_; + /// cliqueRow_ starts for each row + //int * cliqueRowStart_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglKnapsackCover class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglKnapsackCoverUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglLandP.hpp b/thirdparty/linux/include/coin1/CglLandP.hpp new file mode 100644 index 0000000..64447e7 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglLandP.hpp @@ -0,0 +1,306 @@ +// Copyright (C) 2005-2009, Pierre Bonami and others. All Rights Reserved. +// Author: Pierre Bonami +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// Date: 07/21/05 +// +// $Id: CglLandP.hpp 1122 2013-04-06 20:39:53Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//--------------------------------------------------------------------------- +#ifndef CglLandP_H +#define CglLandP_H + +#include "CglLandPValidator.hpp" +#include "CglCutGenerator.hpp" +#include "CglParam.hpp" + +#include <iostream> +class CoinWarmStartBasis; +/** Performs one round of Lift & Project using CglLandPSimplex + to build cuts +*/ + +namespace LAP +{ +enum LapMessagesTypes +{ + BEGIN_ROUND, + END_ROUND, + DURING_SEP, + CUT_REJECTED, + CUT_FAILED, + CUT_GAP, + LAP_CUT_FAILED_DO_MIG, + LAP_MESSAGES_DUMMY_END +}; +/** Output messages for Cgl */ +class LapMessages : public CoinMessages +{ +public: + /** Constructor */ + LapMessages( ); + /** destructor.*/ + virtual ~LapMessages() {} +}; +class CglLandPSimplex; +} + +class CglLandP : public CglCutGenerator +{ + friend void CglLandPUnitTest(OsiSolverInterface *si, const std::string & mpsDir); + + friend class LAP::CglLandPSimplex; + friend class CftCglp; + +public: + + enum SelectionRules + { + mostNegativeRc /** select most negative reduced cost */, + bestPivot /** select best possible pivot.*/, + initialReducedCosts/** Select only those rows which had initialy a 0 reduced cost.*/ + }; + + enum ExtraCutsMode + { + none/** Generate no extra cuts.*/, + AtOptimalBasis /** Generate cuts from the optimal basis.*/, + WhenEnteringBasis /** Generate cuts as soon as a structural enters the basis.*/, + AllViolatedMigs/** Generate all violated Mixed integer Gomory cuts in the course of the optimization.*/ + }; + + /** Space where cuts are optimized.*/ + enum SeparationSpaces + { + Fractional=0 /** True fractional space.*/, + Fractional_rc/** Use fractional space only for computing reduced costs.*/, + Full /** Work in full space.*/ + }; + + /** Normalization */ + enum Normalization + { + Unweighted = 0, + WeightRHS, + WeightLHS, + WeightBoth + }; + + enum LHSnorm + { + L1 = 0, + L2, + SupportSize, + Infinity, + Average, + Uniform + }; + /** RHS weight in normalization.*/ + enum RhsWeightType + { + Fixed = 0 /** 2*initial number of constraints. */, + Dynamic /** 2 * current number of constraints. */ + }; + /** Class storing parameters. + \remark I take all parameters from Ionut's code */ + class Parameters : public CglParam + { + public: + /** Default constructor (with default values)*/ + Parameters(); + /** Copy constructor */ + Parameters(const Parameters &other); + /** Assignment opertator */ + Parameters & operator=(const Parameters &other); + /// @name integer parameters + ///@{ + + /** Max number of pivots before we generate the cut + \default 20 */ + int pivotLimit; + /** Max number of pivots at regular nodes. Put a value if you want it lower than the global pivot limit. + \default 100.*/ + int pivotLimitInTree; + /** Maximum number of cuts generated at a given round*/ + int maxCutPerRound; + /** Maximum number of failed pivots before aborting */ + int failedPivotLimit; + /** maximum number of consecutive degenerate pivots + \default 0 */ + int degeneratePivotLimit; + /** Maximum number of extra rows to generate per round.*/ + int extraCutsLimit; + ///@} + /// @name double parameters + ///@{ + /** Tolerance for small pivots values (should be the same as the solver */ + double pivotTol; + /** A variable have to be at least away from integrity to be generated */ + double away; + /** Total time limit for cut generation.*/ + double timeLimit; + /** Time limit for generating a single cut.*/ + double singleCutTimeLimit; + /** Weight to put in RHS of normalization if static.*/ + double rhsWeight; + ///@} + + /// @name Flags + ///@{ + /** Do we use tableau row or the disjunction (I don't really get that there should be a way to always use the tableau)*/ + bool useTableauRow; + /** Do we apply Egon Balas's Heuristic for modularized cuts */ + bool modularize; + /** Do we strengthen the final cut (always do if modularize is 1) */ + bool strengthen; + /** Wether to limit or not the number of mistaken RC (when perturbation is applied).*/ + bool countMistakenRc; + /** Work in the reduced space (only non-structurals enter the basis) */ + SeparationSpaces sepSpace; + /** Apply perturbation procedure. */ + bool perturb; + /** How to weight normalization.*/ + Normalization normalization; + /** How to weight RHS of normalization.*/ + RhsWeightType rhsWeightType; + /** How to weight LHS of normalization.*/ + LHSnorm lhs_norm; + /** Generate extra constraints from optimal lift-and-project basis.*/ + ExtraCutsMode generateExtraCuts; + /** Which rule to apply for choosing entering and leaving variables.*/ + SelectionRules pivotSelection; + ///@} + }; + + + /** Constructor for the class*/ + CglLandP(const CglLandP::Parameters ¶ms = CglLandP::Parameters(), + const LAP::Validator &validator = LAP::Validator()); + /** Destructor */ + ~CglLandP(); + /** Copy constructor */ + CglLandP(const CglLandP &source); + /** Assignment operator */ + CglLandP& operator=(const CglLandP &rhs); + /** Clone function */ + CglCutGenerator * clone() const; + + /**@name Generate Cuts */ + //@{ + + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + //@} + + virtual bool needsOptimalBasis() const + { + return true; + } + + LAP::Validator & validator() + { + return validator_; + } + /** set level of log for cut generation procedure : + <ol start=0 > + <li> for none </li> + <li> for log at begin and end of procedure + at some time interval </li> + <li> for log at every cut generated </li> + </ol> + */ + void setLogLevel(int level) + { + handler_->setLogLevel(level); + } + + class NoBasisError : public CoinError + { + public: + NoBasisError(): CoinError("No basis available","LandP","") {} + }; + + class SimplexInterfaceError : public CoinError + { + public: + SimplexInterfaceError(): CoinError("Invalid conversion to simplex interface", "CglLandP","CglLandP") {} + }; + Parameters & parameter() + { + return params_; + } +private: + + + void scanExtraCuts(OsiCuts& cs, const double * colsol) const; + + Parameters params_; + + /** Some informations that will be changed by the pivots and that we want to keep*/ + struct CachedData + { + CachedData(int nBasics = 0 , int nNonBasics = 0); + CachedData(const CachedData & source); + + CachedData& operator=(const CachedData &source); + /** Get the data from a problem */ + void getData(const OsiSolverInterface &si); + + void clean(); + + ~CachedData(); + /** Indices of basic variables in starting basis (ordered if variable basics_[i] s basic in row i)*/ + int * basics_; + /** Indices of non-basic variables */ + int *nonBasics_; + /** number of basics variables */ + int nBasics_; + /** number of non-basics */ + int nNonBasics_; + /** Optimal basis */ + CoinWarmStartBasis * basis_; + /** Stores the value of the solution to cut */ + double * colsol_; + /** Stores the values of the slacks */ + double * slacks_; + /** Stores wheter slacks are integer constrained */ + bool * integers_; + /** Solver before pivots */ + OsiSolverInterface * solver_; + }; + /** Retrieve sorted integer variables which are fractional in the solution. + Return the number of variables.*/ + int getSortedFractionals(CoinPackedVector &xFrac, + const CachedData & data, + const CglLandP::Parameters& params) const; + /** Retrieve sorted integer variables which are fractional in the solution. + Return the number of variables.*/ + void getSortedFractionalIndices(std::vector<int>& indices, + const CachedData &data, + const CglLandP::Parameters & params) const; + /** Cached informations about problem.*/ + CachedData cached_; + /** message handler */ + CoinMessageHandler * handler_; + /** messages */ + CoinMessages messages_; + /** cut validator */ + LAP::Validator validator_; + /** number of rows in the original problems. */ + int numrows_; + /** number of columns in the original problems. */ + int numcols_; + /** Original lower bounds for the problem (for lifting cuts).*/ + double * originalColLower_; + /** Original upper bounds for the problem (for lifting cuts).*/ + double * originalColUpper_; + /** Flag to say if cuts can be lifted.*/ + bool canLift_; + /** Store some extra cut which could be cheaply generated but do not cut current incumbent.*/ + OsiCuts extraCuts_; +}; +void CglLandPUnitTest(OsiSolverInterface *si, const std::string & mpsDir); + +#endif + diff --git a/thirdparty/linux/include/coin1/CglLandPValidator.hpp b/thirdparty/linux/include/coin1/CglLandPValidator.hpp new file mode 100644 index 0000000..8b05597 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglLandPValidator.hpp @@ -0,0 +1,131 @@ +// Copyright (C) 2005-2009, Pierre Bonami and others. All Rights Reserved. +// Author: Pierre Bonami +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// Date: 11/22/05 +// +// $Id: CglLandPValidator.hpp 1122 2013-04-06 20:39:53Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//--------------------------------------------------------------------------- + +#ifndef CglLandPValidator_H +#define CglLandPValidator_H +#include "OsiSolverInterface.hpp" +#include "CglParam.hpp" +#include <vector> + +/** constants describing rejection codes*/ +//[5] = {"Accepted", "violation too small", "small coefficient too small", "big dynamic","too dense"} + + +namespace LAP +{ + +/** Class to validate or reject a cut */ +class Validator +{ +public: + /** Reasons for rejecting a cut */ + enum RejectionsReasons + { + NoneAccepted=0 /**Cut was accepted*/, + SmallViolation /** Violation of the cut is too small */, + SmallCoefficient /** There is a small coefficient we can not get rid off.*/, + BigDynamic /** Dynamic of coefficinet is too important. */, + DenseCut/**cut is too dense */, + EmptyCut/**After cleaning cut has become empty*/, + DummyEnd/** dummy*/ + }; + + /** Constructor with default values */ + Validator(double maxFillIn = 1., + double maxRatio = 1e8, + double minViolation = 0, + bool scale = false, + double rhsScale = 1); + + /** Clean an OsiCut */ + int cleanCut(OsiRowCut & aCut, const double * solCut,const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper); + /** Clean an OsiCut by another method */ + int cleanCut2(OsiRowCut & aCut, const double * solCut, const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper); + /** Call the cut cleaner */ + int operator()(OsiRowCut & aCut, const double * solCut,const OsiSolverInterface &si, const CglParam & par, + const double * colLower, const double * colUpper) + { + return cleanCut(aCut, solCut, si, par, colLower, colUpper); + } + /** @name set functions */ + /** @{ */ + void setMaxFillIn(double value) + { + maxFillIn_ = value; + } + void setMaxRatio(double value) + { + maxRatio_ = value; + } + void setMinViolation(double value) + { + minViolation_ = value; + } + + void setRhsScale(double v) + { + rhsScale_ = v; + } + /** @} */ + /** @name get functions */ + /** @{ */ + double getMaxFillIn() + { + return maxFillIn_; + } + double getMaxRatio() + { + return maxRatio_; + } + double getMinViolation() + { + return minViolation_; + } + /** @} */ + + const std::string& failureString(RejectionsReasons code) const + { + return rejections_[static_cast<int> (code)]; + } + const std::string& failureString(int code) const + { + return rejections_[ code]; + } + int numRejected(RejectionsReasons code)const + { + return numRejected_[static_cast<int> (code)]; + } + int numRejected(int code)const + { + return numRejected_[ code]; + } +private: + static void fillRejectionReasons(); + /** max percentage of given formulation fillIn should be accepted for cut fillin.*/ + double maxFillIn_; + /** max ratio between smallest and biggest coefficient */ + double maxRatio_; + /** minimum violation for accepting a cut */ + double minViolation_; + /** Do we do scaling? */ + bool scale_; + /** Scale of right-hand-side.*/ + double rhsScale_; + /** Strings explaining reason for rejections */ + static std::vector<std::string> rejections_; + /** Number of cut rejected for each of the reasons.*/ + std::vector<int> numRejected_; +}; + +}/* Ends namespace LAP.*/ +#endif diff --git a/thirdparty/linux/include/coin1/CglLiftAndProject.hpp b/thirdparty/linux/include/coin1/CglLiftAndProject.hpp new file mode 100644 index 0000000..364ba5a --- /dev/null +++ b/thirdparty/linux/include/coin1/CglLiftAndProject.hpp @@ -0,0 +1,104 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglLiftAndProject_H +#define CglLiftAndProject_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** Lift And Project Cut Generator Class */ +class CglLiftAndProject : public CglCutGenerator { + friend void CglLiftAndProjectUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + /**@name Generate Cuts */ + //@{ + /** Generate lift-and-project cuts for the + model of the solver interface, si. + Insert the generated cuts into OsiCut, cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /** Get the normalization : Either beta=+1 or beta=-1. + */ + + double getBeta() const { + return beta_; + } + + /** Set the normalization : Either beta=+1 or beta=-1. + Default value is 1. + */ + void setBeta(int oneOrMinusOne){ + if (oneOrMinusOne==1 || oneOrMinusOne==-1){ + beta_= static_cast<double>(oneOrMinusOne); + } + else { + throw CoinError("Unallowable value. Beta must be 1 or -1", + "cutGeneration","CglLiftAndProject"); + } + } + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglLiftAndProject (); + + /// Copy constructor + CglLiftAndProject ( + const CglLiftAndProject &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglLiftAndProject & + operator=( + const CglLiftAndProject& rhs); + + /// Destructor + virtual + ~CglLiftAndProject (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// The normalization is beta_=1 or beta_=-1 + double beta_; + /// epsilon + double epsilon_; + /// 1-epsilon + double onetol_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglLiftAndProject class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglLiftAndProjectUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglMessage.hpp b/thirdparty/linux/include/coin1/CglMessage.hpp new file mode 100644 index 0000000..5f080e8 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglMessage.hpp @@ -0,0 +1,50 @@ +// $Id: CglMessage.hpp 1105 2013-03-19 12:43:52Z forrest $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglMessage_H +#define CglMessage_H + + +#include "CoinPragma.hpp" + +// This deals with Cgl messages (as against Osi messages etc) + +#include "CoinMessageHandler.hpp" +enum CGL_Message +{ + CGL_INFEASIBLE, + CGL_CLIQUES, + CGL_FIXED, + CGL_PROCESS_STATS, + CGL_SLACKS, + CGL_PROCESS_STATS2, + CGL_PROCESS_SOS1, + CGL_PROCESS_SOS2, + CGL_UNBOUNDED, + CGL_ELEMENTS_CHANGED1, + CGL_ELEMENTS_CHANGED2, + CGL_MADE_INTEGER, + CGL_ADDED_INTEGERS, + CGL_POST_INFEASIBLE, + CGL_POST_CHANGED, + CGL_GENERAL, + CGL_DUMMY_END +}; + +/** This deals with Cgl messages (as against Osi messages etc) + */ +class CglMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + CglMessage(Language language=us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglMixedIntegerRounding.hpp b/thirdparty/linux/include/coin1/CglMixedIntegerRounding.hpp new file mode 100644 index 0000000..10580cb --- /dev/null +++ b/thirdparty/linux/include/coin1/CglMixedIntegerRounding.hpp @@ -0,0 +1,429 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// name: Mixed Integer Rounding Cut Generator +// authors: Joao Goncalves (jog7@lehigh.edu) +// Laszlo Ladanyi (ladanyi@us.ibm.com) +// date: August 11, 2004 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglMixedIntegerRounding_H +#define CglMixedIntegerRounding_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + +// Class to store variable upper bounds (VUB) +class CglMixIntRoundVUB +{ + // Variable upper bounds have the form x_j <= a y_j, where x_j is + // a continuous variable and y_j is an integer variable + +protected: + int var_; // The index of y_j + double val_; // The value of a + +public: + // Default constructor + CglMixIntRoundVUB() : var_(-1), val_(-1) {} + + // Copy constructor + CglMixIntRoundVUB(const CglMixIntRoundVUB& source) { + var_ = source.var_; + val_ = source.val_; + } + + // Assignment operator + CglMixIntRoundVUB& operator=(const CglMixIntRoundVUB& rhs) { + if (this != &rhs) { + var_ = rhs.var_; + val_ = rhs.val_; + } + return *this; + } + + // Destructor + ~CglMixIntRoundVUB() {} + + // Query and set functions + int getVar() const { return var_; } + double getVal() const { return val_; } + void setVar(const int v) { var_ = v; } + void setVal(const double v) { val_ = v; } +}; + +//============================================================================= + +// Class to store variable lower bounds (VLB). +// It is the same as the class to store variable upper bounds +typedef CglMixIntRoundVUB CglMixIntRoundVLB; + +//============================================================================= + +/** Mixed Integer Rounding Cut Generator Class */ + +// Reference: +// Hugues Marchand and Laurence A. Wolsey +// Aggregation and Mixed Integer Rounding to Solve MIPs +// Operations Research, 49(3), May-June 2001. +// Also published as CORE Dicusion Paper 9839, June 1998. + +class CglMixedIntegerRounding : public CglCutGenerator { + + friend void CglMixedIntegerRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + // The row type of this row is NOT defined yet. + ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARUB, + /** After the row is flipped to 'L', the row has exactly two variables: + one is positive binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + ROW_VAREQ, + // The row contains continuous and integer variables; + // the total number of variables is at least 2 + ROW_MIX, + // The row contains only continuous variables + ROW_CONT, + // The row contains only integer variables + ROW_INT, + // The row contains other types of rows + ROW_OTHER + }; + + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Rounding cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglMixedIntegerRounding (); + + /// Alternate Constructor + CglMixedIntegerRounding (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc = -1); + + /// Copy constructor + CglMixedIntegerRounding ( + const CglMixedIntegerRounding &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglMixedIntegerRounding & + operator=( + const CglMixedIntegerRounding& rhs); + + /// Destructor + virtual + ~CglMixedIntegerRounding (); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + + //--------------------------------------------------------------------------- + /**@name Set and get methods */ + //@{ + /// Set MAXAGGR_ + inline void setMAXAGGR_ (int maxaggr) { + if (maxaggr > 0) { + MAXAGGR_ = maxaggr; + } + else { + throw CoinError("Unallowable value. maxaggr must be > 0", + "gutsOfConstruct","CglMixedIntegerRounding"); + } + } + + /// Get MAXAGGR_ + inline int getMAXAGGR_ () const { return MAXAGGR_; } + + /// Set MULTIPLY_ + inline void setMULTIPLY_ (bool multiply) { MULTIPLY_ = multiply; } + + /// Get MULTIPLY_ + inline bool getMULTIPLY_ () const { return MULTIPLY_; } + + /// Set CRITERION_ + inline void setCRITERION_ (int criterion) { + if ((criterion >= 1) && (criterion <= 3)) { + CRITERION_ = criterion; + } + else { + throw CoinError("Unallowable value. criterion must be 1, 2 or 3", + "gutsOfConstruct","CglMixedIntegerRounding"); + } + } + + /// Get CRITERION_ + inline int getCRITERION_ () const { return CRITERION_; } + + + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + + //@} + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglMixedIntegerRounding& rhs); + + // Do preprocessing. + // It determines the type of each row. It also identifies the variable + // upper bounds and variable lower bounds. + // It may change sense and RHS for ranged rows + void mixIntRoundPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs) const; + + // Generate MIR cuts + void generateMirCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + const double* coefByRow, + const int* colInds, + const int* rowStarts, + const int* rowLengths, + //const CoinPackedMatrix& matrixByCol, + const double* coefByCol, + const int* rowInds, + const int* colStarts, + const int* colLengths, + OsiCuts& cs ) const; + + // Copy row selected to CoinPackedVector + void copyRowSelected( const int iAggregate, + const int rowSelected, + std::set<int>& setRowsAggregated, + int* listRowsAggregated, + double* xlpExtra, + const char sen, + const double rhs, + const double lhs, + const CoinPackedMatrix& matrixByRow, + CoinPackedVector& rowToAggregate, + double& rhsToAggregate) const; + + // Select a row to aggregate + bool selectRowToAggregate( const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double* colUpperBound, + const double* colLowerBound, + const std::set<int>& setRowsAggregated, + const double* xlp, const double* coefByCol, + const int* rowInds, const int* colStarts, + const int* colLengths, + int& rowSelected, + int& colSelected ) const; + + // Aggregation heuristic. + // Combines one or more rows of the original matrix + void aggregateRow( const int colSelected, + CoinPackedVector& rowToAggregate, double rhs, + CoinPackedVector& rowAggregated, + double& rhsAggregated ) const; + + // Choose the bound substitution based on the criteria defined by the user + inline bool isLowerSubst(const double inf, + const double aj, + const double xlp, + const double LB, + const double UB) const; + + // Bound substitution heuristic + bool boundSubstitution( const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double* xlp, + const double* xlpExtra, + const double* colUpperBound, + const double* colLowerBound, + CoinPackedVector& mixedKnapsack, + double& rhsMixedKnapsack, double& sStar, + CoinPackedVector& contVariablesInS ) const; + + // c-MIR separation heuristic + bool cMirSeparation ( const OsiSolverInterface& si, + const CoinPackedMatrix& matrixByRow, + const CoinPackedVector& rowAggregated, + const int* listRowsAggregated, + const char* sense, const double* RHS, + //const double* coefByRow, + //const int* colInds, const int* rowStarts, + //const int* rowLengths, + const double* xlp, const double sStar, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedVector& mixedKnapsack, + const double& rhsMixedKnapsack, + const CoinPackedVector& contVariablesInS, + OsiRowCut& flowCut ) const; + + // function to create one c-MIR inequality + void cMirInequality( const int numInt, + const double delta, + const double numeratorBeta, + const int *knapsackIndices, + const double* knapsackElements, + const double* xlp, + const double sStar, + const double* colUpperBound, + const std::set<int>& setC, + CoinPackedVector& cMIR, + double& rhscMIR, + double& sCoef, + double& violation) const; + + // function to compute G + inline double functionG( const double d, const double f ) const; + + // function to print statistics (used only in debug mode) + void printStats( + std::ofstream & fout, + const bool hasCut, + const OsiSolverInterface& si, + const CoinPackedVector& rowAggregated, + const double& rhsAggregated, const double* xlp, + const double* xlpExtra, + const int* listRowsAggregated, + const int* listColsSelected, + const int level, + const double* colUpperBound, + const double* colLowerBound ) const; + + +private: + //--------------------------------------------------------------------------- + // Private member data + + // Maximum number of rows to aggregate + int MAXAGGR_; + // Flag that indicates if an aggregated row is also multiplied by -1 + bool MULTIPLY_; + // The criterion to use in the bound substitution + int CRITERION_; + // Tolerance used for numerical purposes + double EPSILON_; + /// There is no variable upper bound or variable lower bound defined + int UNDEFINED_; + // If violation of a cut is greater that this number, the cut is accepted + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // The array of CglMixIntRoundVUBs. + CglMixIntRoundVUB* vubs_; + // The array of CglMixIntRoundVLBs. + CglMixIntRoundVLB* vlbs_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // The number of rows of type ROW_MIX + int numRowMix_; + // The indices of the rows of type ROW_MIX + int* indRowMix_; + // The number of rows of type ROW_CONT + int numRowCont_; + // The indices of the rows of type ROW_CONT + int* indRowCont_; + // The number of rows of type ROW_INT + int numRowInt_; + // The indices of the rows of type ROW_INT + int* indRowInt_; + // The number of rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int numRowContVB_; + // The indices of the rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int* indRowContVB_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + +}; + +//############################################################################# +// A function that tests the methods in the CglMixedIntegerRounding class. The +// only reason for it not to be a member method is that this way it doesn't +// have to be compiled into the library. And that's a gain, because the +// library should be compiled with optimization on, but this method should be +// compiled with debugging. +void CglMixedIntegerRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + +#endif diff --git a/thirdparty/linux/include/coin1/CglMixedIntegerRounding2.hpp b/thirdparty/linux/include/coin1/CglMixedIntegerRounding2.hpp new file mode 100644 index 0000000..abf2530 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglMixedIntegerRounding2.hpp @@ -0,0 +1,427 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// name: Mixed Integer Rounding Cut Generator +// authors: Joao Goncalves (jog7@lehigh.edu) +// Laszlo Ladanyi (ladanyi@us.ibm.com) +// date: August 11, 2004 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglMixedIntegerRounding2_H +#define CglMixedIntegerRounding2_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" +#include "CoinIndexedVector.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + +// Class to store variable upper bounds (VUB) +class CglMixIntRoundVUB2 +{ + // Variable upper bounds have the form x_j <= a y_j, where x_j is + // a continuous variable and y_j is an integer variable + +protected: + int var_; // The index of y_j + double val_; // The value of a + +public: + // Default constructor + CglMixIntRoundVUB2() : var_(-1), val_(-1) {} + + // Copy constructor + CglMixIntRoundVUB2(const CglMixIntRoundVUB2& source) { + var_ = source.var_; + val_ = source.val_; + } + + // Assignment operator + CglMixIntRoundVUB2& operator=(const CglMixIntRoundVUB2& rhs) { + if (this != &rhs) { + var_ = rhs.var_; + val_ = rhs.val_; + } + return *this; + } + + // Destructor + ~CglMixIntRoundVUB2() {} + + // Query and set functions + int getVar() const { return var_; } + double getVal() const { return val_; } + void setVar(const int v) { var_ = v; } + void setVal(const double v) { val_ = v; } +}; + +//============================================================================= + +// Class to store variable lower bounds (VLB). +// It is the same as the class to store variable upper bounds +typedef CglMixIntRoundVUB2 CglMixIntRoundVLB2; + +//============================================================================= + +/** Mixed Integer Rounding Cut Generator Class */ + +// Reference: +// Hugues Marchand and Laurence A. Wolsey +// Aggregation and Mixed Integer Rounding to Solve MIPs +// Operations Research, 49(3), May-June 2001. +// Also published as CORE Dicusion Paper 9839, June 1998. + +class CglMixedIntegerRounding2 : public CglCutGenerator { + + friend void CglMixedIntegerRounding2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + // The row type of this row is NOT defined yet. + ROW_UNDEFINED, + /** After the row is flipped to 'L', the row has exactly two variables: + one is negative binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARUB, + /** After the row is flipped to 'L', the row has exactly two variables: + one is positive binary and the other is a continous, + and the RHS is zero.*/ + ROW_VARLB, + /** The row sense is 'E', the row has exactly two variables: + one is binary and the other is a continous, and the RHS is zero.*/ + ROW_VAREQ, + // The row contains continuous and integer variables; + // the total number of variables is at least 2 + ROW_MIX, + // The row contains only continuous variables + ROW_CONT, + // The row contains only integer variables + ROW_INT, + // The row contains other types of rows + ROW_OTHER + }; + + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Rounding cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglMixedIntegerRounding2 (); + + /// Alternate Constructor + CglMixedIntegerRounding2 (const int maxaggr, + const bool multiply, + const int criterion, + const int preproc = -1); + + /// Copy constructor + CglMixedIntegerRounding2 ( + const CglMixedIntegerRounding2 &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglMixedIntegerRounding2 & + operator=( + const CglMixedIntegerRounding2& rhs); + + /// Destructor + virtual + ~CglMixedIntegerRounding2 (); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + + //--------------------------------------------------------------------------- + /**@name Set and get methods */ + //@{ + /// Set MAXAGGR_ + inline void setMAXAGGR_ (int maxaggr) { + if (maxaggr > 0) { + MAXAGGR_ = maxaggr; + } + else { + throw CoinError("Unallowable value. maxaggr must be > 0", + "gutsOfConstruct","CglMixedIntegerRounding2"); + } + } + + /// Get MAXAGGR_ + inline int getMAXAGGR_ () const { return MAXAGGR_; } + + /// Set MULTIPLY_ + inline void setMULTIPLY_ (bool multiply) { MULTIPLY_ = multiply; } + + /// Get MULTIPLY_ + inline bool getMULTIPLY_ () const { return MULTIPLY_; } + + /// Set CRITERION_ + inline void setCRITERION_ (int criterion) { + if ((criterion >= 1) && (criterion <= 3)) { + CRITERION_ = criterion; + } + else { + throw CoinError("Unallowable value. criterion must be 1, 2 or 3", + "gutsOfConstruct","CglMixedIntegerRounding2"); + } + } + + /// Get CRITERION_ + inline int getCRITERION_ () const { return CRITERION_; } + + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + //@} + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct ( const int maxaggr, + const bool multiply, + const int criterion, + const int preproc); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglMixedIntegerRounding2& rhs); + + // Do preprocessing. + // It determines the type of each row. It also identifies the variable + // upper bounds and variable lower bounds. + // It may change sense and RHS for ranged rows + void mixIntRoundPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(//const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs) const; + + // Generate MIR cuts + void generateMirCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + //const double* coefByRow, + //const int* colInds, + //const int* rowStarts, + //const CoinPackedMatrix& matrixByCol, + const double* coefByCol, + const int* rowInds, + const int* colStarts, + OsiCuts& cs ) const; + + // Copy row selected to CoinIndexedVector + void copyRowSelected( const int iAggregate, + const int rowSelected, + CoinIndexedVector& setRowsAggregated, + int* listRowsAggregated, + double* xlpExtra, + const char sen, + const double rhs, + const double lhs, + const CoinPackedMatrix& matrixByRow, + CoinIndexedVector& rowToAggregate, + double& rhsToAggregate) const; + + // Select a row to aggregate + bool selectRowToAggregate( //const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double* colUpperBound, + const double* colLowerBound, + const CoinIndexedVector& setRowsAggregated, + const double* xlp, const double* coefByCol, + const int* rowInds, const int* colStarts, + int& rowSelected, + int& colSelected ) const; + + // Aggregation heuristic. + // Combines one or more rows of the original matrix + void aggregateRow( const int colSelected, + CoinIndexedVector& rowToAggregate, double rhs, + CoinIndexedVector& rowAggregated, + double& rhsAggregated ) const; + + // Choose the bound substitution based on the criteria defined by the user + inline bool isLowerSubst(const double inf, + const double aj, + const double xlp, + const double LB, + const double UB) const; + + // Bound substitution heuristic + bool boundSubstitution( const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double* xlp, + const double* xlpExtra, + const double* colUpperBound, + const double* colLowerBound, + CoinIndexedVector& mixedKnapsack, + double& rhsMixedKnapsack, double& sStar, + CoinIndexedVector& contVariablesInS ) const; + + // c-MIR separation heuristic + bool cMirSeparation ( const OsiSolverInterface& si, + const CoinPackedMatrix& matrixByRow, + const CoinIndexedVector& rowAggregated, + const int* listRowsAggregated, + const char* sense, const double* RHS, + //const double* coefByRow, + //const int* colInds, const int* rowStarts, + const double* xlp, const double sStar, + const double* colUpperBound, + const double* colLowerBound, + const CoinIndexedVector& mixedKnapsack, + const double& rhsMixedKnapsack, + const CoinIndexedVector& contVariablesInS, + CoinIndexedVector * workVector, + OsiRowCut& flowCut ) const; + + // function to create one c-MIR inequality + void cMirInequality( const int numInt, + const double delta, + const double numeratorBeta, + const int *knapsackIndices, + const double* knapsackElements, + const double* xlp, + const double sStar, + const double* colUpperBound, + const CoinIndexedVector& setC, + CoinIndexedVector& cMIR, + double& rhscMIR, + double& sCoef, + double& violation) const; + + // function to compute G + inline double functionG( const double d, const double f ) const; + + // function to print statistics (used only in debug mode) + void printStats( + std::ofstream & fout, + const bool hasCut, + const OsiSolverInterface& si, + const CoinIndexedVector& rowAggregated, + const double& rhsAggregated, const double* xlp, + const double* xlpExtra, + const int* listRowsAggregated, + const int* listColsSelected, + const int level, + const double* colUpperBound, + const double* colLowerBound ) const; + + +private: + //--------------------------------------------------------------------------- + // Private member data + + // Maximum number of rows to aggregate + int MAXAGGR_; + // Flag that indicates if an aggregated row is also multiplied by -1 + bool MULTIPLY_; + // The criterion to use in the bound substitution + int CRITERION_; + // Tolerance used for numerical purposes + double EPSILON_; + /// There is no variable upper bound or variable lower bound defined + int UNDEFINED_; + // If violation of a cut is greater that this number, the cut is accepted + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // The array of CglMixIntRoundVUB2s. + CglMixIntRoundVUB2* vubs_; + // The array of CglMixIntRoundVLB2s. + CglMixIntRoundVLB2* vlbs_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // The number of rows of type ROW_MIX + int numRowMix_; + // The indices of the rows of type ROW_MIX + int* indRowMix_; + // The number of rows of type ROW_CONT + int numRowCont_; + // The indices of the rows of type ROW_CONT + int* indRowCont_; + // The number of rows of type ROW_INT + int numRowInt_; + // The indices of the rows of type ROW_INT + int* indRowInt_; + // The number of rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int numRowContVB_; + // The indices of the rows of type ROW_CONT that have at least one variable + // with variable upper or lower bound + int* indRowContVB_; + // If integer - for speed + char * integerType_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + +}; + +//############################################################################# +// A function that tests the methods in the CglMixedIntegerRounding2 class. The +// only reason for it not to be a member method is that this way it doesn't +// have to be compiled into the library. And that's a gain, because the +// library should be compiled with optimization on, but this method should be +// compiled with debugging. +void CglMixedIntegerRounding2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + +#endif diff --git a/thirdparty/linux/include/coin1/CglOddHole.hpp b/thirdparty/linux/include/coin1/CglOddHole.hpp new file mode 100644 index 0000000..3b80caa --- /dev/null +++ b/thirdparty/linux/include/coin1/CglOddHole.hpp @@ -0,0 +1,160 @@ +// $Id: CglOddHole.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglOddHole_H +#define CglOddHole_H + +#include <string> + +#include "CglCutGenerator.hpp" + +/** Odd Hole Cut Generator Class */ +class CglOddHole : public CglCutGenerator { + friend void CglOddHoleUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate odd hole cuts for the model of the solver interface, si. + This looks at all rows of type sum x(i) <= 1 (or == 1) (x 0-1) + and sees if there is an odd cycle cut. See Grotschel, Lovasz + and Schrijver (1988) for method. + This is then lifted by using the corresponding Chvatal cut i.e. + Take all rows in cycle and add them together. RHS will be odd so + weaken all odd coefficients so 1.0 goes to 0.0 etc - then + constraint is sum even(j)*x(j) <= odd which can be replaced by + sum (even(j)/2)*x(j) <= (odd-1.0)/2. + A similar cut can be generated for sum x(i) >= 1. + + Insert the generated cuts into OsiCut, cs. + + This is only done for rows with unsatisfied 0-1 variables. If there + are many of these it will be slow. Improvements would do a + randomized subset and also speed up shortest path algorithm used. + + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Create Row List */ + //@{ + /// Create a list of rows which might yield cuts + /// this is to speed up process + /// The possible parameter is a list to cut down search + void createRowList( const OsiSolverInterface & si, + const int * possible=NULL); + /// This version passes in a list - 1 marks possible + void createRowList(int numberRows, const int * whichRow); + //@} + + /**@name Create Clique List */ + //@{ + /// Create a list of extra row cliques which may not be in matrix + /// At present these are classical cliques + void createCliqueList(int numberCliques, const int * cliqueStart, + const int * cliqueMember); + //@} + + /**@name Number Possibilities */ + //@{ + /// Returns how many rows might give odd hole cuts + int numberPossible(); + //@} + /**@name Gets and Sets */ + //@{ + /// Minimum violation + double getMinimumViolation() const; + void setMinimumViolation(double value); + /// Minimum violation per entry + double getMinimumViolationPer() const; + void setMinimumViolationPer(double value); + /// Maximum number of entries in a cut + int getMaximumEntries() const; + void setMaximumEntries(int value); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglOddHole (); + + /// Copy constructor + CglOddHole ( + const CglOddHole &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglOddHole & + operator=( + const CglOddHole& rhs); + + /// Destructor + virtual + ~CglOddHole (); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + + /**@name Private methods */ + //@{ + /// Generate cuts from matrix copy and solution + /// If packed true then <=1 rows, otherwise >=1 rows. + void generateCuts(const OsiRowCutDebugger * debugger, + const CoinPackedMatrix & rowCopy, + const double * solution, const double * dj, + OsiCuts & cs, const int * suitableRow, + const int * fixedColumn,const CglTreeInfo info, + bool packed); + //@} + + // Private member data + + /**@name Private member data */ + //@{ + /// list of suitableRows + int * suitableRows_; + /// start of each clique + int * startClique_; + /// clique members + int * member_; + /// epsilon + double epsilon_; + /// 1-epsilon + double onetol_; + /// Minimum violation + double minimumViolation_; + /// Minimum violation per entry + double minimumViolationPer_; + /// Maximum number of entries in a cut + int maximumEntries_; + /// number of rows when suitability tested + int numberRows_; + /// number of cliques + int numberCliques_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglOddHole class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglOddHoleUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglParam.hpp b/thirdparty/linux/include/coin1/CglParam.hpp new file mode 100644 index 0000000..4463ef5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglParam.hpp @@ -0,0 +1,93 @@ +// Name: CglParam.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 11/24/06 +// +// $Id: CglParam.hpp 1122 2013-04-06 20:39:53Z stefan $ +// +// This code is licensed under the terms of the Eclipse Public License (EPL). +//----------------------------------------------------------------------------- +// Copyright (C) 2006, Francois Margot and others. All Rights Reserved. + +#ifndef CglParam_H +#define CglParam_H +#include "CglConfig.h" +#include "CoinFinite.hpp" +/** Class collecting parameters for all cut generators. Each generator + may have a derived class to add parameters. Each generator might + also set different default values for the parameters in CglParam. */ + +class CglParam { + +public: + + /**@name Public Set/get methods */ + //@{ + + /** Set INFINIT */ + virtual void setINFINIT(const double inf); + /** Get value of INFINIT */ + inline double getINFINIT() const {return INFINIT;} + + /** Set EPS */ + virtual void setEPS(const double eps); + /** Get value of EPS */ + inline double getEPS() const {return EPS;} + + /** Set EPS_COEFF */ + virtual void setEPS_COEFF(const double eps_c); + /** Get value of EPS_COEFF */ + inline double getEPS_COEFF() const {return EPS_COEFF;} + + /** Set MAX_SUPPORT */ + virtual void setMAX_SUPPORT(const int max_s); + /** Get value of MAX_SUPPORT */ + inline int getMAX_SUPPORT() const {return MAX_SUPPORT;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglParam(const double inf = COIN_DBL_MAX, const double eps = 1e-6, + const double eps_c = 1e-5, const int max_s = COIN_INT_MAX); + + /// Copy constructor + CglParam(const CglParam&); + + /// Clone + virtual CglParam* clone() const; + + /// Assignment operator + CglParam& operator=(const CglParam &rhs); + + /// Destructor + virtual ~CglParam(); + //@} + +protected: + + // Protected member data + + /**@name Protected member data */ + + //@{ + // Value for infinity. Default: COIN_DBL_MAX. + double INFINIT; + + // EPSILON for double comparisons. Default: 1e-6. + double EPS; + + // Returned cuts do not have coefficients with absolute value smaller + // than EPS_COEFF. Default: 1e-5. + double EPS_COEFF; + + /** Maximum number of non zero coefficients in a generated cut; + Default: COIN_INT_MAX */ + int MAX_SUPPORT; + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglPreProcess.hpp b/thirdparty/linux/include/coin1/CglPreProcess.hpp new file mode 100644 index 0000000..65c04ca --- /dev/null +++ b/thirdparty/linux/include/coin1/CglPreProcess.hpp @@ -0,0 +1,492 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglPreProcess_H +#define CglPreProcess_H + +#include <string> +#include <vector> + +#include "CoinMessageHandler.hpp" +#include "OsiSolverInterface.hpp" +#include "CglStored.hpp" +#include "OsiPresolve.hpp" +#include "CglCutGenerator.hpp" + +//############################################################################# + +/** Class for preProcessing and postProcessing. + + While cuts can be added at any time in the tree, some cuts are actually just + stronger versions of existing constraints. In this case they can replace those + constraints rather than being added as new constraints. This is awkward in the + tree but reasonable at the root node. + + This is a general process class which uses other cut generators to strengthen + constraints, establish that constraints are redundant, fix variables and + find relationships such as x + y == 1. + + Presolve will also be done. + + If row names existed they may be replaced by R0000000 etc + +*/ + +class CglPreProcess { + +public: + + ///@name Main methods + //@{ + /** preProcess problem - returning new problem. + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + This version uses default strategy. For more control copy and edit + code from this function i.e. call preProcessNonDefault + */ + OsiSolverInterface * preProcess(OsiSolverInterface & model, + bool makeEquality=false, int numberPasses=5); + /** preProcess problem - returning new problem. + If makeEquality true then <= cliques converted to ==. + Presolve will be done numberPasses times. + + Returns NULL if infeasible + + This version assumes user has added cut generators to CglPreProcess object + before calling it. As an example use coding in preProcess + If makeEquality is 1 add slacks to get cliques, + if 2 add slacks to get sos (but only if looks plausible) and keep sos info + */ + OsiSolverInterface * preProcessNonDefault(OsiSolverInterface & model, + int makeEquality=0, int numberPasses=5, + int tuning=0); + /// Creates solution in original model + void postProcess(OsiSolverInterface &model + ,bool deleteStuff=true); + /** Tightens primal bounds to make dual and branch and cutfaster. Unless + fixed or integral, bounds are slightly looser than they could be. + Returns non-zero if problem infeasible + Fudge for branch and bound - put bounds on columns of factor * + largest value (at continuous) - should improve stability + in branch and bound on infeasible branches (0.0 is off) + */ + int tightenPrimalBounds(OsiSolverInterface & model,double factor=0.0); + /** Fix some of problem - returning new problem. + Uses reduced costs. + Optional signed character array + 1 always keep, -1 always discard, 0 use djs + + */ + OsiSolverInterface * someFixed(OsiSolverInterface & model, + double fractionToKeep=0.25, + bool fixContinuousAsWell=false, + char * keep=NULL) const; + /** Replace cliques by more maximal cliques + Returns NULL if rows not reduced by greater than cliquesNeeded*rows + + */ + OsiSolverInterface * cliqueIt(OsiSolverInterface & model, + double cliquesNeeded=0.0) const; + /// If we have a cutoff - fix variables + int reducedCostFix(OsiSolverInterface & model); + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + /** Set cutoff bound on the objective function. + + When using strict comparison, the bound is adjusted by a tolerance to + avoid accidentally cutting off the optimal solution. + */ + void setCutoff(double value) ; + + /// Get the cutoff bound on the objective function - always as minimize + double getCutoff() const; + /// The original solver associated with this model. + inline OsiSolverInterface * originalModel() const + { return originalModel_;} + /// Solver after making clique equalities (may == original) + inline OsiSolverInterface * startModel() const + { return startModel_;} + /// Copies of solver at various stages after presolve + inline OsiSolverInterface * modelAtPass(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return model_[iPass]; else return NULL;} + /// Copies of solver at various stages after presolve after modifications + inline OsiSolverInterface * modifiedModel(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return modifiedModel_[iPass]; else return NULL;} + /// Matching presolve information + inline OsiPresolve * presolve(int iPass) const + { if (iPass>=0&&iPass<numberSolvers_) return presolve_[iPass]; else return NULL;} + /** Return a pointer to the original columns (with possible clique slacks) + MUST be called before postProcess otherwise you just get 0,1,2.. */ + const int * originalColumns(); + /** Return a pointer to the original rows + MUST be called before postProcess otherwise you just get 0,1,2.. */ + const int * originalRows(); + /// Number of SOS if found + inline int numberSOS() const + { return numberSOS_;} + /// Type of each SOS + inline const int * typeSOS() const + { return typeSOS_;} + /// Start of each SOS + inline const int * startSOS() const + { return startSOS_;} + /// Columns in SOS + inline const int * whichSOS() const + { return whichSOS_;} + /// Weights for each SOS column + inline const double * weightSOS() const + { return weightSOS_;} + /// Pass in prohibited columns + void passInProhibited(const char * prohibited,int numberColumns); + /// Updated prohibited columns + inline const char * prohibited() + { return prohibited_;} + /// Number of iterations PreProcessing + inline int numberIterationsPre() const + { return numberIterationsPre_;} + /// Number of iterations PostProcessing + inline int numberIterationsPost() const + { return numberIterationsPost_;} + /** Pass in row types + 0 normal + 1 cut rows - will be dropped if remain in + At end of preprocess cut rows will be dropped + and put into cuts + */ + void passInRowTypes(const char * rowTypes,int numberRows); + /** Updated row types - may be NULL + Carried around and corresponds to existing rows + -1 added by preprocess e.g. x+y=1 + 0 normal + 1 cut rows - can be dropped if wanted + */ + inline const char * rowTypes() + { return rowType_;} + /// Return cuts from dropped rows + inline const CglStored & cuts() const + { return cuts_;} + /// Return pointer to cuts from dropped rows + inline const CglStored * cutsPointer() const + { return &cuts_;} + /// Update prohibited and rowType + void update(const OsiPresolve * pinfo,const OsiSolverInterface * solver); + /// Set options + inline void setOptions(int value) + { options_=value;} + //@} + + ///@name Cut generator methods + //@{ + /// Get the number of cut generators + inline int numberCutGenerators() const + { return numberCutGenerators_;} + /// Get the list of cut generators + inline CglCutGenerator ** cutGenerators() const + { return generator_;} + ///Get the specified cut generator + inline CglCutGenerator * cutGenerator(int i) const + { return generator_[i];} + /** Add one generator - up to user to delete generators. + */ + void addCutGenerator(CglCutGenerator * generator); +//@} + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + + /// Get application data + void * getApplicationData() const; + //@} + + //--------------------------------------------------------------------------- + + /**@name Message handling */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Return handler + inline CoinMessageHandler * messageHandler() const + {return handler_;} + /// Return messages + inline CoinMessages messages() + {return messages_;} + /// Return pointer to messages + inline CoinMessages * messagesPointer() + {return &messages_;} + //@} + //--------------------------------------------------------------------------- + + + ///@name Constructors and destructors etc + //@{ + /// Constructor + CglPreProcess(); + + /// Copy constructor . + CglPreProcess(const CglPreProcess & rhs); + + /// Assignment operator + CglPreProcess & operator=(const CglPreProcess& rhs); + + /// Destructor + ~CglPreProcess (); + + /// Clears out as much as possible + void gutsOfDestructor(); + //@} +private: + + ///@name private methods + //@{ + /** Return model with useful modifications. + If constraints true then adds any x+y=1 or x-y=0 constraints + If NULL infeasible + */ + OsiSolverInterface * modified(OsiSolverInterface * model, + bool constraints, + int & numberChanges, + int iBigPass, + int numberPasses); + /// create original columns and rows + void createOriginalIndices(); + /// Make continuous variables integer + void makeInteger(); + //@} + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + + /// The original solver associated with this model. + OsiSolverInterface * originalModel_; + /// Solver after making clique equalities (may == original) + OsiSolverInterface * startModel_; + /// Number of solvers at various stages + int numberSolvers_; + /// Copies of solver at various stages after presolve + OsiSolverInterface ** model_; + /// Copies of solver at various stages after presolve after modifications + OsiSolverInterface ** modifiedModel_; + /// Matching presolve information + OsiPresolve ** presolve_; + + /// Message handler + CoinMessageHandler * handler_; + + /** Flag to say if handler_ is the default handler. + + The default handler is deleted when the model is deleted. Other + handlers (supplied by the client) will not be deleted. + */ + bool defaultHandler_; + + /// Cgl messages + CoinMessages messages_; + + /// Pointer to user-defined data structure + void * appData_; + /// Original column numbers + int * originalColumn_; + /// Original row numbers + int * originalRow_; + /// Number of cut generators + int numberCutGenerators_; + /// Cut generators + CglCutGenerator ** generator_; + /// Number of SOS if found + int numberSOS_; + /// Type of each SOS + int * typeSOS_; + /// Start of each SOS + int * startSOS_; + /// Columns in SOS + int * whichSOS_; + /// Weights for each SOS column + double * weightSOS_; + /// Number of columns in original prohibition set + int numberProhibited_; + /// Number of iterations done in PreProcessing + int numberIterationsPre_; + /// Number of iterations done in PostProcessing + int numberIterationsPost_; + /// Columns which should not be presolved e.g. SOS + char * prohibited_; + /// Number of rows in original row types + int numberRowType_; + /** Options + 1 - original model had integer bounds before tightening + 2 - don't do probing + 4 - don't do duplicate rows + 8 - don't do cliques + 16 - some heavy probing options + 64 - very heavy probing + */ + int options_; + /** Row types (may be NULL) + Carried around and corresponds to existing rows + -1 added by preprocess e.g. x+y=1 + 0 normal + 1 cut rows - can be dropped if wanted + */ + char * rowType_; + /// Cuts from dropped rows + CglStored cuts_; + //@} +}; +/// For Bron-Kerbosch +class CglBK { + +public: + + ///@name Main methods + //@{ + /// For recursive Bron-Kerbosch + void bronKerbosch(); + /// Creates strengthened smaller model + OsiSolverInterface * newSolver(const OsiSolverInterface & model); + //@} + + //--------------------------------------------------------------------------- + + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false if the value of the parameter is out of range. + + The get methods return the value of the parameter. + + */ + //@{ + //@} + + //--------------------------------------------------------------------------- + + + ///@name Constructors and destructors etc + //@{ + /// Default constructor + CglBK(); + + /// Useful constructor + CglBK(const OsiSolverInterface & model, const char * rowType, + int numberElements); + + /// Copy constructor . + CglBK(const CglBK & rhs); + + /// Assignment operator + CglBK & operator=(const CglBK& rhs); + + /// Destructor + ~CglBK (); + + //@} + +//--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + /// Current candidates (created at each level) + int * candidates_; + /// Array to mark stuff + char * mark_; + /// Starts for graph (numberPossible+1) + int * start_; + /// Other column/node + int * otherColumn_; + /// Original row (in parallel with otherColumn_) + int * originalRow_; + /// How many times each original row dominated + int * dominated_; + /// Clique entries + CoinPackedMatrix * cliqueMatrix_; + /// points to row types + const char * rowType_; + /// Number of original columns + int numberColumns_; + /// Number of original rows + int numberRows_; + /// Number possible + int numberPossible_; + /// Current number of candidates + int numberCandidates_; + /// First not (stored backwards from numberPossible_) + int firstNot_; + /// Current number in clique + int numberIn_; + /// For acceleration + int left_; + int lastColumn_; + //@} +}; +/** + Only store unique row cuts +*/ +// for hashing +typedef struct { + int index, next; +} CglHashLink; +class OsiRowCut; +class CglUniqueRowCuts { +public: + + CglUniqueRowCuts(int initialMaxSize=0, int hashMultiplier=4 ); + ~CglUniqueRowCuts(); + CglUniqueRowCuts(const CglUniqueRowCuts& rhs); + CglUniqueRowCuts& operator=(const CglUniqueRowCuts& rhs); + inline OsiRowCut * cut(int sequence) const + { return rowCut_[sequence];} + inline int numberCuts() const + { return numberCuts_;} + inline int sizeRowCuts() const + { return numberCuts_;} + inline OsiRowCut * rowCutPtr(int sequence) + { return rowCut_[sequence];} + void eraseRowCut(int sequence); + // insert cut + inline void insert(const OsiRowCut & cut) + { insertIfNotDuplicate(cut);} + // Return 0 if added, 1 if not + int insertIfNotDuplicate(const OsiRowCut & cut); + // Add in cuts as normal cuts (and delete) + void addCuts(OsiCuts & cs); +private: + OsiRowCut ** rowCut_; + /// Hash table + CglHashLink *hash_; + int size_; + int hashMultiplier_; + int numberCuts_; + int lastHash_; +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglProbing.hpp b/thirdparty/linux/include/coin1/CglProbing.hpp new file mode 100644 index 0000000..5ca8996 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglProbing.hpp @@ -0,0 +1,543 @@ +// $Id: CglProbing.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglProbing_H +#define CglProbing_H + +#include <string> + +#include "CglCutGenerator.hpp" + /** Only useful type of disaggregation is most normal + For now just done for 0-1 variables + Can be used for building cliques + */ + typedef struct { + //unsigned int zeroOne:1; // nonzero if affected variable is 0-1 + //unsigned int whenAtUB:1; // nonzero if fixing happens when this variable at 1 + //unsigned int affectedToUB:1; // nonzero if affected variable fixed to UB + //unsigned int affected:29; // If 0-1 then 0-1 sequence, otherwise true + unsigned int affected; + } disaggregationAction; + +/** Probing Cut Generator Class */ +class CglProbing : public CglCutGenerator { + friend void CglProbingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate probing/disaggregation cuts for the model of the + solver interface, si. + + This is a simplification of probing ideas put into OSL about + ten years ago. The only known documentation is a copy of a + talk handout - we think Robin Lougee-Heimer has a copy! + + For selected integer variables (e.g. unsatisfied ones) the effect of + setting them up or down is investigated. Setting a variable up + may in turn set other variables (continuous as well as integer). + There are various possible results: + + 1) It is shown that problem is infeasible (this may also be + because objective function or reduced costs show worse than + best solution). If the other way is feasible we can generate + a column cut (and continue probing), if not feasible we can + say problem infeasible. + + 2) If both ways are feasible, it can happen that x to 0 implies y to 1 + ** and x to 1 implies y to 1 (again a column cut). More common + is that x to 0 implies y to 1 and x to 1 implies y to 0 so we could + substitute for y which might lead later to more powerful cuts. + ** This is not done in this code as there is no mechanism for + returning information. + + 3) When x to 1 a constraint went slack by c. We can tighten the + constraint ax + .... <= b (where a may be zero) to + (a+c)x + .... <= b. If this cut is violated then it is + generated. + + 4) Similarly we can generate implied disaggregation cuts + + Note - differences to cuts in OSL. + + a) OSL had structures intended to make this faster. + b) The "chaining" in 2) was done + c) Row cuts modified original constraint rather than adding cut + b) This code can cope with general integer variables. + + Insert the generated cuts into OsiCut, cs. + + If a "snapshot" of a matrix exists then this will be used. + Presumably this will give global cuts and will be faster. + No check is done to see if cuts will be global. + + Otherwise use current matrix. + + Both row cuts and column cuts may be returned + + The mode options are: + 0) Only unsatisfied integer variables will be looked at. + If no information exists for that variable then + probing will be done so as a by-product you "may" get a fixing + or infeasibility. This will be fast and is only available + if a snapshot exists (otherwise as 1). + The bounds in the snapshot are the ones used. + 1) Look at unsatisfied integer variables, using current bounds. + Probing will be done on all looked at. + 2) Look at all integer variables, using current bounds. + Probing will be done on all + + ** If generateCutsAndModify is used then new relaxed + row bounds and tightened column bounds are generated + Returns number of infeasibilities + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + int generateCutsAndModify( const OsiSolverInterface & si, OsiCuts & cs, + CglTreeInfo * info); + //@} + + /**@name snapshot etc */ + //@{ + /** Create a copy of matrix which is to be used + this is to speed up process and to give global cuts + Can give an array with 1 set to select, 0 to ignore + column bounds are tightened + If array given then values of 1 will be set to 0 if redundant. + Objective may be added as constraint + Returns 1 if infeasible otherwise 0 + */ + int snapshot ( const OsiSolverInterface & si, + char * possible=NULL, + bool withObjective=true); + /// Deletes snapshot + void deleteSnapshot ( ); + /** Creates cliques for use by probing. + Only cliques >= minimumSize and < maximumSize created + Can also try and extend cliques as a result of probing (root node). + Returns number of cliques found. + */ + int createCliques( OsiSolverInterface & si, + int minimumSize=2, int maximumSize=100); + /// Delete all clique information + void deleteCliques(); + /** Create a fake model by adding cliques + if type&4 then delete rest of model first, + if 1 then add proper cliques, 2 add fake cliques */ + OsiSolverInterface * cliqueModel(const OsiSolverInterface * model, + int type); + //@} + + /**@name Get tighter column bounds */ + //@{ + /// Lower + const double * tightLower() const; + /// Upper + const double * tightUpper() const; + /// Array which says tighten continuous + const char * tightenBounds() const + { return tightenBounds_;} + //@} + + /**@name Get possible freed up row bounds - only valid after mode==3 */ + //@{ + /// Lower + const double * relaxedRowLower() const; + /// Upper + const double * relaxedRowUpper() const; + //@} + + /**@name Change mode */ + //@{ + /// Set + void setMode(int mode); + /// Get + int getMode() const; + //@} + + /**@name Change maxima */ + //@{ + /// Set maximum number of passes per node + void setMaxPass(int value); + /// Get maximum number of passes per node + int getMaxPass() const; + /// Set log level - 0 none, 1 - a bit, 2 - more details + void setLogLevel(int value); + /// Get log level + int getLogLevel() const; + /// Set maximum number of unsatisfied variables to look at + void setMaxProbe(int value); + /// Get maximum number of unsatisfied variables to look at + int getMaxProbe() const; + /// Set maximum number of variables to look at in one probe + void setMaxLook(int value); + /// Get maximum number of variables to look at in one probe + int getMaxLook() const; + /// Set maximum number of elements in row for it to be considered + void setMaxElements(int value); + /// Get maximum number of elements in row for it to be considered + int getMaxElements() const; + /// Set maximum number of passes per node (root node) + void setMaxPassRoot(int value); + /// Get maximum number of passes per node (root node) + int getMaxPassRoot() const; + /// Set maximum number of unsatisfied variables to look at (root node) + void setMaxProbeRoot(int value); + /// Get maximum number of unsatisfied variables to look at (root node) + int getMaxProbeRoot() const; + /// Set maximum number of variables to look at in one probe (root node) + void setMaxLookRoot(int value); + /// Get maximum number of variables to look at in one probe (root node) + int getMaxLookRoot() const; + /// Set maximum number of elements in row for it to be considered (root node) + void setMaxElementsRoot(int value); + /// Get maximum number of elements in row for it to be considered (root node) + int getMaxElementsRoot() const; + /** + Returns true if may generate Row cuts in tree (rather than root node). + Used so know if matrix will change in tree. Really + meant so column cut generators can still be active + without worrying code. + Default is true + */ + virtual bool mayGenerateRowCutsInTree() const; + //@} + + /**@name Get information back from probing */ + //@{ + /// Number looked at this time + inline int numberThisTime() const + { return numberThisTime_;} + /// Which ones looked at this time + inline const int * lookedAt() const + { return lookedAt_;} + //@} + + /**@name Stop or restart row cuts (otherwise just fixing from probing) */ + //@{ + /// Set + /// 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both) + void setRowCuts(int type); + /// Get + int rowCuts() const; + //@} + /// Clique type + typedef struct { + unsigned int equality:1; // nonzero if clique is == + } CliqueType; + + /**@name Information on cliques */ + //@{ + /// Number of cliques + inline int numberCliques() const + { return numberCliques_;} + /// Clique type + inline CliqueType * cliqueType() const + { return cliqueType_;} + /// Start of each clique + inline int * cliqueStart() const + { return cliqueStart_;} + /// Entries for clique + inline CliqueEntry * cliqueEntry() const + { return cliqueEntry_;} + //@} + + /**@name Whether use objective as constraint */ + //@{ + /** Set + 0 don't + 1 do + -1 don't even think about it + */ + void setUsingObjective(int yesNo); + /// Get + int getUsingObjective() const; + //@} + + /**@name Mark which continuous variables are to be tightened */ + //@{ + /// Mark variables to be tightened + void tightenThese(const OsiSolverInterface & solver, int number, const int * which); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglProbing (); + + /// Copy constructor + CglProbing ( + const CglProbing &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglProbing & + operator=( + const CglProbing& rhs); + + /// Destructor + virtual + ~CglProbing (); + + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + /**@name probe */ + //@{ + /// Does probing and adding cuts (without cliques and mode_!=0) + int probe( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy,const CoinBigIndex * rowStartPos, + const int * realRow, const double * rowLower, const double * rowUpper, + const char * intVar, double * minR, double * maxR, int * markR, + CglTreeInfo * info); + /// Does probing and adding cuts (with cliques) + int probeCliques( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy, const int * realRow, + double * rowLower, double * rowUpper, + char * intVar, double * minR, double * maxR, int * markR, + CglTreeInfo * info); + /// Does probing and adding cuts for clique slacks + int probeSlacks( const OsiSolverInterface & si, + const OsiRowCutDebugger * debugger, + OsiCuts & cs, + double * colLower, double * colUpper, CoinPackedMatrix *rowCopy, + CoinPackedMatrix *columnCopy, + double * rowLower, double * rowUpper, + char * intVar, double * minR, double * maxR,int * markR, + CglTreeInfo * info); + /** Does most of work of generateCuts + Returns number of infeasibilities */ + int gutsOfGenerateCuts( const OsiSolverInterface & si, + OsiCuts & cs, + double * rowLower, double * rowUpper, + double * colLower, double * colUpper, + CglTreeInfo * info); + /// Sets up clique information for each row + void setupRowCliqueInformation(const OsiSolverInterface & si); + /** This tightens column bounds (and can declare infeasibility) + It may also declare rows to be redundant */ + int tighten(double *colLower, double * colUpper, + const int *column, const double *rowElements, + const CoinBigIndex *rowStart,const CoinBigIndex * rowStartPos, + const int * rowLength, + double *rowLower, double *rowUpper, + int nRows,int nCols,char * intVar,int maxpass, + double tolerance); + /// This just sets minima and maxima on rows + void tighten2(double *colLower, double * colUpper, + const int *column, const double *rowElements, + const CoinBigIndex *rowStart, + const int * rowLength, + double *rowLower, double *rowUpper, + double * minR, double * maxR, int * markR, + int nRows); + //@} + + // Private member data + + struct disaggregation_struct_tag ; + friend struct CglProbing::disaggregation_struct_tag ; + + /**@name Private member data */ + //@{ + /// Row copy (only if snapshot) + CoinPackedMatrix * rowCopy_; + /// Column copy (only if snapshot) + CoinPackedMatrix * columnCopy_; + /// Lower bounds on rows + double * rowLower_; + /// Upper bounds on rows + double * rowUpper_; + /// Lower bounds on columns + double * colLower_; + /// Upper bounds on columns + double * colUpper_; + /// Number of rows in snapshot (or when cliqueRow stuff computed) + int numberRows_; + /// Number of columns in problem ( must == current) + int numberColumns_; + /// Tolerance to see if infeasible + double primalTolerance_; + /** Mode - 0 lazy using snapshot, 1 just unsatisfied, 2 all. + 16 bit set if want to extend cliques at root node + */ + int mode_; + /** Row cuts flag + 0 no cuts, 1 just disaggregation type, 2 coefficient ( 3 both), 4 just column cuts + -n as +n but just fixes variables unless at root + */ + int rowCuts_; + /// Maximum number of passes to do in probing + int maxPass_; + /// Log level - 0 none, 1 - a bit, 2 - more details + int logLevel_; + /// Maximum number of unsatisfied variables to probe + int maxProbe_; + /// Maximum number of variables to look at in one probe + int maxStack_; + /// Maximum number of elements in row for scan + int maxElements_; + /// Maximum number of passes to do in probing at root + int maxPassRoot_; + /// Maximum number of unsatisfied variables to probe at root + int maxProbeRoot_; + /// Maximum number of variables to look at in one probe at root + int maxStackRoot_; + /// Maximum number of elements in row for scan at root + int maxElementsRoot_; + /// Whether to include objective as constraint + int usingObjective_; + /// Number of integer variables + int numberIntegers_; + /// Number of 0-1 integer variables + int number01Integers_; + /// Number looked at this time + int numberThisTime_; + /// Total number of times called + int totalTimesCalled_; + /// Which ones looked at this time + int * lookedAt_; + /// Disaggregation cuts and for building cliques + typedef struct disaggregation_struct_tag { + int sequence; // integer variable + // index will be NULL if no probing done yet + int length; // length of newValue + disaggregationAction * index; // columns whose bounds will be changed + } disaggregation; + disaggregation * cutVector_; + /// Cliques + /// Number of cliques + int numberCliques_; + /// Clique type + CliqueType * cliqueType_; + /// Start of each clique + int * cliqueStart_; + /// Entries for clique + CliqueEntry * cliqueEntry_; + /** Start of oneFixes cliques for a column in matrix or -1 if not + in any clique */ + int * oneFixStart_; + /** Start of zeroFixes cliques for a column in matrix or -1 if not + in any clique */ + int * zeroFixStart_; + /// End of fixes for a column + int * endFixStart_; + /// Clique numbers for one or zero fixes + int * whichClique_; + /** For each column with nonzero in row copy this gives a clique "number". + So first clique mentioned in row is always 0. If no entries for row + then no cliques. If sequence > numberColumns then not in clique. + */ + CliqueEntry * cliqueRow_; + /// cliqueRow_ starts for each row + int * cliqueRowStart_; + /// If not null and [i] !=0 then also tighten even if continuous + char * tightenBounds_; + //@} +}; +inline int affectedInDisaggregation(const disaggregationAction & dis) +{ return dis.affected&0x1fffffff;} +inline void setAffectedInDisaggregation(disaggregationAction & dis, + int affected) +{ dis.affected = affected|(dis.affected&0xe0000000);} +#ifdef NDEBUG +inline bool zeroOneInDisaggregation(const disaggregationAction & ) +{ return true;} +#else +inline bool zeroOneInDisaggregation(const disaggregationAction & dis) +//{ return (dis.affected&0x80000000)!=0;} +{ assert ((dis.affected&0x80000000)!=0); return true;} +#endif +inline void setZeroOneInDisaggregation(disaggregationAction & dis,bool zeroOne) +{ dis.affected = (zeroOne ? 0x80000000 : 0)|(dis.affected&0x7fffffff);} +inline bool whenAtUBInDisaggregation(const disaggregationAction & dis) +{ return (dis.affected&0x40000000)!=0;} +inline void setWhenAtUBInDisaggregation(disaggregationAction & dis,bool whenAtUB) +{ dis.affected = (whenAtUB ? 0x40000000 : 0)|(dis.affected&0xbfffffff);} +inline bool affectedToUBInDisaggregation(const disaggregationAction & dis) +{ return (dis.affected&0x20000000)!=0;} +inline void setAffectedToUBInDisaggregation(disaggregationAction & dis,bool affectedToUB) +{ dis.affected = (affectedToUB ? 0x20000000 : 0)|(dis.affected&0xdfffffff);} + +//############################################################################# +/** A function that tests the methods in the CglProbing class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglProbingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); +/// This just uses implication info +class CglImplication : public CglCutGenerator { + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate cuts from implication table + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglImplication (); + + /// Constructor with info + CglImplication (CglTreeProbingInfo * info); + + /// Copy constructor + CglImplication ( + const CglImplication &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglImplication & + operator=( + const CglImplication& rhs); + + /// Destructor + virtual + ~CglImplication (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + /**@name Set implication */ + //@{ + /// Set implication + inline void setProbingInfo(CglTreeProbingInfo * info) + { probingInfo_=info;} + //@} + +private: + /**@name Private member data */ + //@{ + /// Pointer to tree probing info + CglTreeProbingInfo * probingInfo_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglRedSplit.hpp b/thirdparty/linux/include/coin1/CglRedSplit.hpp new file mode 100644 index 0000000..1265b1d --- /dev/null +++ b/thirdparty/linux/include/coin1/CglRedSplit.hpp @@ -0,0 +1,448 @@ +// Last edit: 4/20/07 +// +// Name: CglRedSplit.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 2/6/05 +// +// $Id: CglRedSplit.hpp 1119 2013-04-06 20:24:18Z stefan $ +//----------------------------------------------------------------------------- +// Copyright (C) 2005, Francois Margot and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglRedSplit_H +#define CglRedSplit_H + +#include "CglCutGenerator.hpp" +#include "CglRedSplitParam.hpp" + +/** Gomory Reduce-and-Split Cut Generator Class; See method generateCuts(). + Based on the paper by K. Anderson, G. Cornuejols, Yanjun Li, + "Reduce-and-Split Cuts: Improving the Performance of Mixed Integer + Gomory Cuts", Management Science 51 (2005). */ + +class CglRedSplit : public CglCutGenerator { + + friend void CglRedSplitUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + /**@name generateCuts */ + //@{ + /** Generate Reduce-and-Split Mixed Integer Gomory cuts + for the model of the solver interface si. + + Insert the generated cuts into OsiCuts cs. + + Warning: This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau and + optimal basis inverse and makes assumptions on the way slack variables + are added by the solver. The Osi implementations for Clp and Cplex + verify these assumptions. + + When calling the generator, the solver interface si + must contain an optimized + problem and information related to the optimal basis must be available + through the OsiSolverInterface methods (si->optimalBasisIsAvailable() + must return 'true'). It is also essential that the integrality of + structural variable i can be obtained using si->isInteger(i). + + Reduce-and-Split cuts are variants of Gomory cuts: Starting from + the current optimal tableau, linear combinations of the rows of + the current optimal simplex tableau are used for generating Gomory + cuts. The choice of the linear combinations is driven by the objective + of reducing the coefficients of the non basic continuous variables + in the resulting row. + Note that this generator might not be able to generate cuts for some + solutions violating integrality constraints. + + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglRedSplitParam object. + void setParam(const CglRedSplitParam &source); + // Return the CglRedSplitParam object of the generator. + inline CglRedSplitParam getParam() const {return param;} + + // Compute entries of low_is_lub and up_is_lub. + void compute_is_lub(); + + // Compute entries of is_integer. + void compute_is_integer(); + + /// Set given_optsol to the given optimal solution given_sol. + /// If given_optsol is set using this method, + /// the code will stop as soon as + /// a generated cut is violated by the given solution; exclusively + /// for debugging purposes. + void set_given_optsol(const double *given_sol, const int card_sol); + + /// Print some of the data members + void print() const; + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + //@} + + /**@name Public Methods (soon to be obsolete)*/ + //@{ + //************************************************************ + // TO BE REMOVED + /** Set limit, the maximum number of non zero coefficients in generated cut; + Default: 50 */ + void setLimit(int limit); + /** Get value of limit */ + int getLimit() const; + + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.05 */ + void setAway(double value); + /// Get value of away + double getAway() const; + /** Set the value of LUB, value considered large for the absolute value of + a lower or upper bound on a variable; + Default: 1000 */ + void setLUB(double value); + /** Get the value of LUB */ + double getLUB() const; + + /** Set the value of EPS, epsilon for double computations; + Default: 1e-7 */ + void setEPS(double value); + /** Get the value of EPS */ + double getEPS() const; + + /** Set the value of EPS_COEFF, epsilon for values of coefficients; + Default: 1e-8 */ + void setEPS_COEFF(double value); + /** Get the value of EPS_COEFF */ + double getEPS_COEFF() const; + + /** Set the value of EPS_COEFF_LUB, epsilon for values of coefficients for + variables with absolute value of lower or upper bound larger than LUB; + Default: 1e-13 */ + void setEPS_COEFF_LUB(double value); + /** Get the value of EPS_COEFF_LUB */ + double getEPS_COEFF_LUB() const; + + /** Set the value of EPS_RELAX, value used for relaxing the right hand side + of each generated cut; + Default: 1e-8 */ + void setEPS_RELAX(double value); + /** Get the value of EPS_RELAX */ + double getEPS_RELAX() const; + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + void setNormIsZero(double value); + /** Get the value of normIsZero */ + double getNormIsZero() const; + + /** Set the value of minReduc, threshold for relative norm improvement for + performing a reduction; Default: 0.05 */ + void setMinReduc(double value); + /// Get the value of minReduc + double getMinReduc() const; + + /** Set the maximum allowed value for (mTab * mTab * CoinMax(mTab, nTab)) where + mTab is the number of rows used in the combinations and nTab is the + number of continuous non basic variables. The work of the generator is + proportional to (mTab * mTab * CoinMax(mTab, nTab)). Reducing the value of + maxTab makes the generator faster, but weaker. Default: 1e7. */ + void setMaxTab(double value); + /// Get the value of maxTab + double getMaxTab() const; + // END TO BE REMOVED + //************************************************************ + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplit(); + + /// Constructor with specified parameters + CglRedSplit(const CglRedSplitParam &RS_param); + + /// Copy constructor + CglRedSplit (const CglRedSplit &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglRedSplit & + operator=( + const CglRedSplit& rhs); + + /// Destructor + virtual + ~CglRedSplit (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglRedSplit members are properly set. + void generateCuts(OsiCuts & cs); + + /// Compute the fractional part of value, allowing for small error. + inline double rs_above_integer(double value); + + /// Perform row r1 of pi := row r1 of pi - step * row r2 of pi. + void update_pi_mat(int r1, int r2, int step); + + /// Perform row r1 of tab := row r1 of tab - step * row r2 of tab. + void update_redTab(int r1, int r2, int step); + + /// Find optimal integer step for changing row r1 by adding to it a + /// multiple of another row r2. + void find_step(int r1, int r2, int *step, + double *reduc, double *norm); + + /// Test if an ordered pair of rows yields a reduction. Perform the + /// reduction if it is acceptable. + int test_pair(int r1, int r2, double *norm); + + /// Reduce rows of contNonBasicTab. + void reduce_contNonBasicTab(); + + /// Generate a row of the current LP tableau. + void generate_row(int index_row, double *row); + + /// Generate a mixed integer Chvatal-Gomory cut, when all non basic + /// variables are non negative and at their lower bound. + int generate_cgcut(double *row, double *rhs); + + /// Generate a mixed integer Chvatal-Gomory cut, when all non basic + /// variables are non negative and at their lower bound (different formula) + int generate_cgcut_2(int basic_ind, double *row, double *rhs); + + /// Use multiples of the initial inequalities to cancel out the coefficients + /// of the slack variables. + void eliminate_slacks(double *row, + const double *elements, + const int *start, + const int *indices, + const int *rowLength, + const double *rhs, double *rowrhs); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound. + void flip(double *row); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. + void unflip(double *row, double *rowrhs, double *slack_val); + + /// Return the scale factor for the row. + /// Compute max_coeff: maximum absolute value of the coefficients. + /// Compute min_coeff: minimum absolute value of the coefficients + /// larger than EPS_COEFF. + /// Return -1 if max_coeff < EPS_COEFF or if max_coeff/min_coeff > MAXDYN + /// or MAXDYN_LUB (depending if the row has a non zero coeff. for a variable + /// with large lower/upper bound) */. + double row_scale_factor(double *row); + + /// Generate the packed cut from the row representation. + int generate_packed_row(const double *xlp, double *row, + int *rowind, double *rowelem, + int *card_row, double & rhs); + + /// Check that the generated cuts do not cut a given optimal solution. + void check_optsol(const int calling_place, + const double *xlp, const double *slack_val, + const int do_flip); + + /// Check that the generated cuts do not cut a given optimal solution. + void check_optsol(const int calling_place, + const double *xlp, const double *slack_val, + const double *ck_row, const double ck_rhs, + const int cut_number, const int do_flip); + + // Check that two vectors are different. + bool rs_are_different_vectors(const int *vect1, + const int *vect2, + const int dim); + + // Check that two vectors are different. + bool rs_are_different_vectors(const double *vect1, + const double *vect2, + const int dim); + + // Check that two matrices are different. + bool rs_are_different_matrices(const CoinPackedMatrix *mat1, + const CoinPackedMatrix *mat2, + const int nmaj, + const int nmin); + //@} + + + // Private member data + +/**@name Private member data */ + + //@{ + + /// Object with CglRedSplitParam members. + CglRedSplitParam param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Number of integer basic structural variables that are fractional in the + /// current lp solution (at least param.away_ from being integer). + int card_intBasicVar_frac; + + /// Number of integer non basic structural variables in the + /// current lp solution. + int card_intNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current lp solution. + int card_contNonBasicVar; + + /// Number of non basic variables (structural or slack) at their + /// upper bound in the current lp solution. + int card_nonBasicAtUpper; + + /// Number of non basic variables (structural or slack) at their + /// lower bound in the current lp solution. + int card_nonBasicAtLower; + + /// Characteristic vector for integer basic structural variables + /// with non integer value in the current lp solution. + int *cv_intBasicVar_frac; + + /// List of integer structural basic variables + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar_frac; + + /// List of integer structural non basic variables. + int *intNonBasicVar; + + /// List of continuous non basic variables (structural or slack). + // slacks are considered continuous (no harm if this is not the case). + int *contNonBasicVar; + + /// List of non basic variables (structural or slack) at their + /// upper bound. + int *nonBasicAtUpper; + + /// List of non basic variables (structural or slack) at their lower + /// bound. + int *nonBasicAtLower; + + /// Number of rows in the reduced tableau (= card_intBasicVar_frac). + int mTab; + + /// Number of columns in the reduced tableau (= card_contNonBasicVar) + int nTab; + + /// Tableau of multipliers used to alter the rows used in generation. + /// Dimensions: mTab by mTab. Initially, pi_mat is the identity matrix. + int **pi_mat; + + /// Current tableau for continuous non basic variables (structural or slack). + /// Only rows used for generation. + /// Dimensions: mTab by nTab. + double **contNonBasicTab; + + /// Current tableau for integer non basic structural variables. + /// Only rows used for generation. + // Dimensions: mTab by card_intNonBasicVar. + double **intNonBasicTab; + + /// Right hand side of the tableau. + /// Only rows used for generation. + double *rhsTab ; + + /// Given optimal solution that should not be cut; only for debug. + const double *given_optsol; + + /// Number of entries in given_optsol. + int card_given_optsol; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + int *is_integer; + + /// Characteristic vector of the structural variables whose lower bound + /// in absolute value is larger than LUB. + int *low_is_lub; + + /// Characteristic vector of the structural variables whose upper bound + /// in absolute value is larger than LUB. + int *up_is_lub; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on column type. Reset by each call to generateCuts(). + const char *colType; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CglRedSplit class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglRedSplitUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin1/CglRedSplit2.hpp b/thirdparty/linux/include/coin1/CglRedSplit2.hpp new file mode 100644 index 0000000..c66e1ca --- /dev/null +++ b/thirdparty/linux/include/coin1/CglRedSplit2.hpp @@ -0,0 +1,494 @@ +// Last edit: 04/03/10 +// +// Name: CglRedSplit2.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// Singapore +// email: nannicini@sutd.edu.sg +// based on CglRedSplit by Francois Margot +// Date: 03/09/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2010, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglRedSplit2_H +#define CglRedSplit2_H + +#include "CglCutGenerator.hpp" +#include "CglRedSplit2Param.hpp" +#include "CoinWarmStartBasis.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinTime.hpp" + +/** Reduce-and-Split Cut Generator Class; See method generateCuts(). + Based on the papers "Practical strategies for generating rank-1 + split cuts in mixed-integer linear programming" by G. Cornuejols + and G. Nannicini, published on Mathematical Programming + Computation, and "Combining Lift-and-Project and Reduce-and-Split" + by E. Balas, G. Cornuejols, T. Kis and G. Nannicini, published on + INFORMS Journal on Computing. Part of this code is based on + CglRedSplit by F. Margot. */ + +class CglRedSplit2 : public CglCutGenerator { + + friend void CglRedSplit2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); +public: + /**@name generateCuts */ + //@{ + /** Generate Reduce-and-Split Mixed Integer Gomory cuts + for the model of the solver interface si. + + Insert the generated cuts into OsiCuts cs. + + This generator currently works only with the Lp solvers Clp or + Cplex9.0 or higher. It requires access to the optimal tableau + and optimal basis inverse and makes assumptions on the way slack + variables are added by the solver. The Osi implementations for + Clp and Cplex verify these assumptions. + + When calling the generator, the solver interface si must contain + an optimized problem and information related to the optimal + basis must be available through the OsiSolverInterface methods + (si->optimalBasisIsAvailable() must return 'true'). It is also + essential that the integrality of structural variable i can be + obtained using si->isInteger(i). + + Reduce-and-Split cuts are a class of split cuts. We compute + linear combinations of the rows of the simplex tableau, trying + to reduce some of the coefficients on the nonbasic continuous + columns. We have a large number of heuristics to choose which + coefficients should be reduced, and by using which rows. The + paper explains everything in detail. + + Note that this generator can potentially generate a huge number + of cuts, depending on how it is parametered. Default parameters + should be good for most situations; if you want to go heavy on + split cuts, use more row selection strategies or a different + number of rows in the linear combinations. Again, look at the + paper for details. If you want to generate a small number of + cuts, default parameters are not the best choice. + + A combination of Reduce-and-Split with Lift & Project is + described in the paper "Combining Lift-and-Project and + Reduce-and-Split". The Reduce-and-Split code for the + implementation used in that paper is included here. + + This generator does not generate the same cuts as CglRedSplit, + therefore both generators can be used in conjunction. + + */ + + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + + // Generate the row multipliers computed by Reduce-and-Split from the + // given OsiSolverInterface. The multipliers are written in lambda; + // lambda should be of size nrow*maxNumMultipliers. We generate at most + // maxNumMultipliers m-vectors of row multipliers, and return the number + // of m-vectors that were generated. + // If the caller wants to know which variables are basic in each row + // (same order as lambda), basicVariables should be non-NULL (size nrow). + // This method can also generate the cuts corresponding to the multipliers + // returned; it suffices to pass non-NULL OsiCuts. + // This method is not needed by the typical user; however, it is useful + // in the context of generating Lift & Project cuts. + int generateMultipliers(const OsiSolverInterface& si, int* lambda, + int maxNumMultipliers, int* basicVariables = NULL, + OsiCuts* cs = NULL); + + // Try to improve a Lift & Project cut, by employing the + // Reduce-and-Split procedure. We start from a row of a L&P tableau, + // and generate a cut trying to reduce the coefficients on the + // nonbasic variables. Note that this L&P tableau will in general + // have nonbasic variables which are nonzero in the point that we + // want to cut off, so we should be careful. Arguments: + // OsiSolverInterface which contains the simplex tableau, initial + // row from which the cut is derived, row rhs, row number of the + // source row (if it is in the simplex tableau; otherwise, a + // negative number; needed to avoid using duplicate rows), point + // that we want to cut off (note: this is NOT a basic solution for + // the OsiSolverInterace!), list of variables which are basic in + // xbar but are nonbasic in the OsiSolverInterface. The computed cut + // is written in OsiRowCut* cs. Finally, if a starting disjunction + // is provided in the vector lambda (of size ncols, i.e. a + // disjunction on the structural variables), the disjunction is + // modified according to the cut which is produced. + int tiltLandPcut(const OsiSolverInterface* si, double* row, + double rowRhs, int rownumber, const double* xbar, + const int* newnonbasics, OsiRowCut* cs, int* lambda = NULL); + + //@} + + + /**@name Public Methods */ + //@{ + + // Set the parameters to the values of the given CglRedSplit2Param object. + void setParam(const CglRedSplit2Param &source); + // Return the CglRedSplit2Param object of the generator. + inline CglRedSplit2Param& getParam() {return param;} + + /// Print some of the data members; used for debugging + void print() const; + + /// Print the current simplex tableau + void printOptTab(OsiSolverInterface *solver) const; + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplit2(); + + /// Constructor with specified parameters + CglRedSplit2(const CglRedSplit2Param &RS_param); + + /// Copy constructor + CglRedSplit2(const CglRedSplit2 &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglRedSplit2 & operator=(const CglRedSplit2& rhs); + + /// Destructor + virtual ~CglRedSplit2 (); + + //@} + +private: + + // Private member methods + +/**@name Private member methods */ + + //@{ + + // Method generating the cuts after all CglRedSplit2 members are + // properly set. This does the actual work. Returns the number of + // generated cuts (or multipliers). + // Will generate cuts if cs != NULL, and will generate multipliers + // if lambda != NULL. + int generateCuts(OsiCuts* cs, int maxNumCuts, int* lambda = NULL); + + /// Compute the fractional part of value, allowing for small error. + inline double rs_above_integer(const double value) const; + + /// Fill workNonBasicTab, depending on the column selection strategy. + /// Accepts a list of variables indices that should be ignored; by + /// default, this list is empty (it is only used by Lift & Project). + /// The list ignore_list contains -1 as the last element. + /// Note that the implementation of the ignore_list is not very efficient + /// if the list is long, so it should be used only if its short. + void fill_workNonBasicTab(CglRedSplit2Param::ColumnSelectionStrategy + strategy, const int* ignore_list = NULL); + + /// Fill workNonBasicTab, alternate version for Lift & Project: also + /// reduces columns which are now nonbasic but are basic in xbar. + /// This function should be called only when CglRedSplit2 is used in + /// conjunction with CglLandP to generate L&P+RS cuts. + void fill_workNonBasicTab(const int* newnonbasics, const double* xbar, + CglRedSplit2Param::ColumnScalingStrategy scaling); + + /// Reduce rows of workNonBasicTab, i.e. compute integral linear + /// combinations of the rows in order to reduce row coefficients on + /// workNonBasicTab + void reduce_workNonBasicTab(int numRows, + CglRedSplit2Param::RowSelectionStrategy + rowSelectionStrategy, + int maxIterations); + + /// Generate a linear combination of the rows of the current LP + /// tableau, using the row multipliers stored in the matrix pi_mat + /// on the row of index index_row + void generate_row(int index_row, double *row); + + /// Generate a mixed integer Gomory cut, when all non basic + /// variables are non negative and at their lower bound. + int generate_cgcut(double *row, double *rhs); + + /// Use multiples of the initial inequalities to cancel out the coefficients + /// of the slack variables. + void eliminate_slacks(double *row, + const double *elements, + const int *start, + const int *indices, + const int *rowLength, + const double *rhs, double *rowrhs); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound. + void flip(double *row); + + /// Change the sign of the coefficients of the continuous non basic + /// variables at their upper bound and do the translations restoring + /// the original bounds. Modify the right hand side + /// accordingly. + void unflip(double *row, double *rowrhs); + + /// Returns 1 if the row has acceptable max/min coeff ratio. + /// Compute max_coeff: maximum absolute value of the coefficients. + /// Compute min_coeff: minimum absolute value of the coefficients + /// larger than EPS_COEFF. + /// Return 0 if max_coeff/min_coeff > MAXDYN. + int check_dynamism(double *row); + + /// Generate the packed cut from the row representation. + int generate_packed_row(const double *xlp, double *row, + int *rowind, double *rowelem, + int *card_row, double & rhs); + + // Compute entries of is_integer. + void compute_is_integer(); + + // Check that two vectors are different. + bool rs_are_different_vectors(const int *vect1, + const int *vect2, + const int dim); + + // allocate matrix of integers + void rs_allocmatINT(int ***v, int m, int n); + // deallocate matrix of integers + void rs_deallocmatINT(int ***v, int m); + // allocate matrix of doubles + void rs_allocmatDBL(double ***v, int m, int n); + // deallocate matrix of doubles + void rs_deallocmatDBL(double ***v, int m); + // print a vector of integers + void rs_printvecINT(const char *vecstr, const int *x, int n) const; + // print a vector of doubles + void rs_printvecDBL(const char *vecstr, const double *x, int n) const; + // print a matrix of integers + void rs_printmatINT(const char *vecstr, const int * const *x, int m, int n) const; + // print a matrix of doubles + void rs_printmatDBL(const char *vecstr, const double * const *x, int m, int n) const; + // dot product + double rs_dotProd(const double *u, const double *v, int dim) const; + double rs_dotProd(const int *u, const double *v, int dim) const; + // From Numerical Recipes in C: LU decomposition + int ludcmp(double **a, int n, int *indx, double *d, double* vv) const; + // from Numerical Recipes in C: backward substitution + void lubksb(double **a, int n, int *indx, double *b) const; + + // Check if the linear combination given by listOfRows with given multipliers + // improves the norm of row #rowindex; note: multipliers are rounded! + // Returns the difference with respect to the old norm (if negative there is + // an improvement, if positive norm increases) + double compute_norm_change(double oldnorm, const int* listOfRows, + int numElemList, const double* multipliers) const; + + // Compute the list of rows that should be used to reduce row #rowIndex + int get_list_rows_reduction(int rowIndex, int numRowsReduction, + int* list, const double* norm, + CglRedSplit2Param::RowSelectionStrategy + rowSelectionStrategy) const; + + // Sorts the rows by increasing number of nonzeroes with respect to a given + // row (rowIndex), on the nonbasic variables (whichTab == 0 means only + // integer, whichTab == 1 means only workTab, whichTab == 2 means both). + // The array for sorting must be allocated (and deleted) by caller. + // Corresponds to BRS1 in the paper. + int sort_rows_by_nonzeroes(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Greedy variant of the previous function; slower but typically + // more effective. Corresponds to BRS2 in the paper. + int sort_rows_by_nonzeroes_greedy(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Sorts the rows by decreasing absolute value of the cosine of the + // angle with respect to a given row (rowIndex), on the nonbasic + // variables (whichTab == 0 means only integer, whichTab == 1 means + // only workTab, whichTab == 2 means both). The array for sorting + // must be allocated (and deleted) by caller. Very effective + // strategy in practice. Corresponds to BRS3 in the paper. + int sort_rows_by_cosine(struct sortElement* array, int rowIndex, + int maxRows, int whichTab) const; + + // Did we hit the time limit? + inline bool checkTime() const{ + if ((CoinCpuTime() - startTime) < param.getTimeLimit()){ + return true; + } + return false; + } + + //@} + + + // Private member data + + /**@name Private member data */ + + //@{ + + /// Object with CglRedSplit2Param members. + CglRedSplit2Param param; + + /// Number of rows ( = number of slack variables) in the current LP. + int nrow; + + /// Number of structural variables in the current LP. + int ncol; + + /// Number of rows which have been reduced + int numRedRows; + + /// Lower bounds for structural variables + const double *colLower; + + /// Upper bounds for structural variables + const double *colUpper; + + /// Lower bounds for constraints + const double *rowLower; + + /// Upper bounds for constraints + const double *rowUpper; + + /// Righ hand side for constraints (upper bound for ranged constraints). + const double *rowRhs; + + /// Reduced costs for columns + const double *reducedCost; + + /// Row price + const double *rowPrice; + + /// Objective coefficients + const double* objective; + + /// Number of integer basic structural variables + int card_intBasicVar; + + /// Number of integer basic structural variables that are fractional in the + /// current lp solution (at least param.away_ from being integer). + int card_intBasicVar_frac; + + /// Number of integer non basic structural variables in the + /// current lp solution. + int card_intNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current lp solution. + int card_contNonBasicVar; + + /// Number of continuous non basic variables (structural or slack) in the + /// current working set for coefficient reduction + int card_workNonBasicVar; + + /// Number of non basic variables (structural or slack) at their + /// upper bound in the current lp solution. + int card_nonBasicAtUpper; + + /// Number of non basic variables (structural or slack) at their + /// lower bound in the current lp solution. + int card_nonBasicAtLower; + + /// Characteristic vector for integer basic structural variables + int *cv_intBasicVar; + + /// Characteristic vector for integer basic structural variables + /// with non integer value in the current lp solution. + int *cv_intBasicVar_frac; + + /// Characteristic vector for rows of the tableau selected for reduction + /// with non integer value in the current lp solution + int *cv_fracRowsTab; + + /// List of integer structural basic variables + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar; + + /// List of integer structural basic variables with fractional value + /// (in order of pivot in selected rows for cut generation). + int *intBasicVar_frac; + + /// List of integer structural non basic variables. + int *intNonBasicVar; + + /// List of continuous non basic variables (structural or slack). + // slacks are considered continuous (no harm if this is not the case). + int *contNonBasicVar; + + /// List of non basic variables (structural or slack) at their + /// upper bound. + int *nonBasicAtUpper; + + /// List of non basic variables (structural or slack) at their lower + /// bound. + int *nonBasicAtLower; + + /// Number of rows in the reduced tableau (= card_intBasicVar). + int mTab; + + /// Number of columns in the reduced tableau (= card_contNonBasicVar) + int nTab; + + /// Tableau of multipliers used to alter the rows used in generation. + /// Dimensions: mTab by mTab. Initially, pi_mat is the identity matrix. + int **pi_mat; + + /// Simplex tableau for continuous non basic variables (structural or slack). + /// Only rows used for generation. + /// Dimensions: mTab by card_contNonBasicVar. + double **contNonBasicTab; + + /// Current tableau for continuous non basic variables (structural or slack). + /// Only columns used for coefficient reduction. + /// Dimensions: mTab by card_workNonBasicVar. + double **workNonBasicTab; + + /// Simplex tableau for integer non basic structural variables. + /// Only rows used for generation. + // Dimensions: mTab by card_intNonBasicVar. + double **intNonBasicTab; + + /// Right hand side of the tableau. + /// Only rows used for generation. + double *rhsTab; + + /// Norm of rows in workNonBasicTab; needed for faster computations + double *norm; + + /// Characteristic vectors of structural integer variables or continuous + /// variables currently fixed to integer values. + int *is_integer; + + /// Pointer on solver. Reset by each call to generateCuts(). + OsiSolverInterface *solver; + + /// Pointer on point to separate. Reset by each call to generateCuts(). + const double *xlp; + + /// Pointer on row activity. Reset by each call to generateCuts(). + const double *rowActivity; + + /// Pointer on matrix of coefficient ordered by rows. + /// Reset by each call to generateCuts(). + const CoinPackedMatrix *byRow; + + /// Time at which cut computations began. + /// Reset by each call to generateCuts(). + double startTime; + + //@} +}; + +//############################################################################# +/** A function that tests some of the methods in the CglRedSplit2 + class. The only reason for it not to be a member method is that + this way it doesn't have to be compiled into the library. And + that's a gain, because the library should be compiled with + optimization on, but this method should be compiled with + debugging. */ +void CglRedSplit2UnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +#endif diff --git a/thirdparty/linux/include/coin1/CglRedSplit2Param.hpp b/thirdparty/linux/include/coin1/CglRedSplit2Param.hpp new file mode 100644 index 0000000..369c676 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglRedSplit2Param.hpp @@ -0,0 +1,495 @@ +// Name: CglRedSplit2Param.hpp +// Author: Giacomo Nannicini +// Singapore University of Technology and Design +// Singapore +// email: nannicini@sutd.edu.sg +// Date: 03/09/09 +//----------------------------------------------------------------------------- +// Copyright (C) 2010, Giacomo Nannicini and others. All Rights Reserved. + +#ifndef CglRedSplit2Param_H +#define CglRedSplit2Param_H + +#include "CglParam.hpp" +#include <vector> + + /**@name CglRedSplit2 Parameters */ + //@{ + + /** Class collecting parameters the Reduced-and-split cut generator. + + An important thing to note is that the cut generator allows for + the selection of a number of strategies that can be combined + together. By default, a selection that typically yields a good + compromise between speed and cut strenght is made. The selection + can be changed by resetting the default choices (see the + functions whose name starts with "reset") or by setting the + parameter use_default_strategies to false in the + constructors. After this, the chosen strategies can be added to + the list by using the functions whose name starts with + "add". All strategies will be combined together: if we choose 3 + row selection strategies, 2 column selection strategies, and 2 + possible numbers of rows, we end up with a total of 3*2*2 + combinations. + + For a detailed explanation of the parameters and their meaning, + see the paper by Cornuejols and Nannicini: "Practical strategies + for generating rank-1 split cuts in mixed-integer linear + programming", on Mathematical Programming Computation. + + Parameters of the generator are listed below. + + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - EPS_RELAX_ABS: Absolute relaxation of cut rhs. + - EPS_RELAX_REL: Relative relaxation of cut rhs. + - MAX_SUPP_ABS: Maximum cut support (absolute). + - MAX_SUPP_REL: Maximum cut support (relative): the formula to + compute maximum cut support is + MAX_SUPP_ABS + ncol*MAX_SUPP_REL. + - USE_INTSLACKS: Use integer slacks to generate cuts. (not implemented). + See method setUSE_INTSLACKS(). + - normIsZero: Norm of a vector is considered zero if smaller than + this value. See method setNormIsZero(). + - minNormReduction: a cut is generated if the new norm of the row on the + continuous nonbasics is reduced by at least + this factor (relative reduction). + - away: Look only at basic integer variables whose current value + is at least this value from being integer. See method setAway(). + - maxSumMultipliers: maximum sum (in absolute value) of row multipliers + - normalization: normalization factor for the norm of lambda in the + coefficient reduction algorithm (convex min problem) + - numRowsReduction: Maximum number of rows in the linear system for + norm reduction. + - columnSelectionStrategy: parameter to select which columns should be + used for coefficient reduction. + - rowSelectionStrategy: parameter to select which rows should be + used for coefficient reduction. + - timeLimit: Time limit (in seconds) for cut generation. + - maxNumCuts: Maximum number of cuts that can be returned at each pass; + we could generate more cuts than this number (see below) + - maxNumComputedCuts: Maximum number of cuts that can be computed + by the generator at each pass + - maxNonzeroesTab : Rows of the simplex tableau with more than + this number of nonzeroes will not be + considered for reduction. Only works if + RS_FAST_* are defined in CglRedSplit2. + - skipGomory: Skip traditional Gomory cuts, i.e. GMI cuts arising from + a single row of the tableau (instead of a combination). + Default is 1 (true), because we assume that they are + generated by a traditional Gomory generator anyway. + */ + //@} + +class CglRedSplit2Param : public CglParam { + +public: + /** Enumerations for parameters */ + + /** Row selection strategies; same names as in the paper */ + enum RowSelectionStrategy{ + /* Pick rows that introduce the fewest nonzeroes on integer nonbasics */ + RS1, + /* Pick rows that introduce the fewest nonzeroes on the set of working + continuous nonbasics */ + RS2, + /* Pick rows that introduce the fewest nonzeroes on both integer and + working continuous nonbasics */ + RS3, + /* Same as RS0 but with greedy algorithm */ + RS4, + /* Same as RS1 but with greedy algorithm */ + RS5, + /* Same as RS2 but with greedy algorithm */ + RS6, + /* Pick rows with smallest angle in the space of integer and working + continuous nonbasics */ + RS7, + /* Pick rows with smallest angle in the space of working + continuous nonbasics */ + RS8, + /* Use all strategies */ + RS_ALL, + /* Use best ones - that is, RS8 and RS7 */ + RS_BEST + }; + + /** Column selection strategies; again, look them up in the paper. */ + enum ColumnSelectionStrategy{ + /* C-3P */ + CS1, CS2, CS3, + /* C-5P */ + CS4, CS5, CS6, CS7, CS8, + /* I-2P-2/3 */ + CS9, CS10, + /* I-2P-4/5 */ + CS11, CS12, + /* I-2P-1/2 */ + CS13, CS14, + /* I-3P */ + CS15, CS16, CS17, + /* I-4P */ + CS18, CS19, CS20, CS21, + /* Use all strategies up to this point */ + CS_ALL, + /* Use best strategies (same effect as CS_ALL, because it turns out that + using all strategies is the best thing to do) */ + CS_BEST, + /* Optimize over all continuous nonbasic columns; this does not give + good results, but we use it for testing Lift & Project + RedSplit */ + CS_ALLCONT, + /* Lift & Project specific strategy: only select variables which + are nonbasic in the tableau but are basic in the point to cut + off. This strategy cannot be used outside L&P. It is not very + effective even with L&P, but is left here for testing.*/ + CS_LAP_NONBASICS + }; + + /** Scaling strategies for new nonbasic columns for Lift & Project; + * "factor" is the value of columnScalingBoundLAP_ */ + enum ColumnScalingStrategy{ + /* No scaling */ + SC_NONE, + /* Multiply by |xbar[i]| where xbar[i] is the value of the + corresponding component of the point that we want to cut off */ + SC_LINEAR, + /* Multiply by min(factor,|xbar[i]|) */ + SC_LINEAR_BOUNDED, + /* Multiply by min(factor,log(|xbar[i]|)) */ + SC_LOG_BOUNDED, + /* Multiply all new nonbasics by factor */ + SC_UNIFORM, + /* Multiply only nonzero coefficients by factor */ + SC_UNIFORM_NZ + }; + + /**@name Set/get methods */ + //@{ + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.005 */ + virtual void setAway(double value); + /// Get value of away + inline double getAway() const {return away_;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 0.0 */ + void setEPS_ELIM(double value); + /** Get the value of EPS_ELIM */ + double getEPS_ELIM() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(double eps_ra); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(double eps_rr); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-3 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + + /** Maximum absolute support of the cutting planes. Default: INT_MAX. + Aliases for consistency with our naming scheme. */ + inline void setMAX_SUPP_ABS(int value) {setMAX_SUPPORT(value);} + inline int getMAX_SUPP_ABS() const {return MAX_SUPPORT;} + + /** Maximum relative support of the cutting planes. Default: 0.0. + The maximum support is MAX_SUPP_ABS + MAX_SUPPREL*ncols. */ + inline void setMAX_SUPP_REL(double value); + inline double getMAX_SUPP_REL() const {return MAX_SUPP_REL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(int value); + /** Get the value of USE_INTSLACKS */ + inline int getUSE_INTSLACKS() const {return USE_INTSLACKS;} + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + virtual void setNormIsZero(double value); + /** Get the value of normIsZero */ + inline double getNormIsZero() const {return normIsZero_;} + + /** Set the value of minNormReduction; Default: 0.1 */ + virtual void setMinNormReduction(double value); + /** Get the value of normIsZero */ + inline double getMinNormReduction() const {return minNormReduction_;} + + /** Set the value of maxSumMultipliers; Default: 10 */ + virtual void setMaxSumMultipliers(int value); + /** Get the value of maxSumMultipliers */ + inline int getMaxSumMultipliers() const {return maxSumMultipliers_;} + + /** Set the value of normalization; Default: 0.0001 */ + virtual void setNormalization(double value); + /** Get the value of normalization */ + inline double getNormalization() const {return normalization_;} + + /** Set the value of numRowsReduction, max number of rows that are used + * for each row reduction step. In particular, the linear system will + * involve a numRowsReduction*numRowsReduction matrix */ + virtual void addNumRowsReduction(int value); + /// get the value + inline std::vector<int> getNumRowsReduction() const {return numRowsReduction_;} + /// reset + inline void resetNumRowsReduction() {numRowsReduction_.clear();} + + /** Add the value of columnSelectionStrategy */ + virtual void addColumnSelectionStrategy(ColumnSelectionStrategy value); + /// get the value + inline std::vector<ColumnSelectionStrategy> getColumnSelectionStrategy() const {return columnSelectionStrategy_;} + /// reset + inline void resetColumnSelectionStrategy(){columnSelectionStrategy_.clear();} + + /** Set the value for rowSelectionStrategy, which changes the way we choose + * the rows for the reduction step */ + virtual void addRowSelectionStrategy(RowSelectionStrategy value); + /// get the value + inline std::vector<RowSelectionStrategy> getRowSelectionStrategy() const {return rowSelectionStrategy_;}; + /// reset + inline void resetRowSelectionStrategy() {rowSelectionStrategy_.clear();} + + /** Set the value of numRowsReductionLAP, max number of rows that are used + * for each row reduction step during Lift & Project. + * In particular, the linear system will involve a + * numRowsReduction*numRowsReduction matrix */ + virtual void addNumRowsReductionLAP(int value); + /// get the value + inline std::vector<int> getNumRowsReductionLAP() const {return numRowsReductionLAP_;} + /// reset + inline void resetNumRowsReductionLAP() {numRowsReductionLAP_.clear();} + + /** Add the value of columnSelectionStrategyLAP */ + virtual void addColumnSelectionStrategyLAP(ColumnSelectionStrategy value); + /// get the value + inline std::vector<ColumnSelectionStrategy> getColumnSelectionStrategyLAP() const {return columnSelectionStrategyLAP_;} + /// reset + inline void resetColumnSelectionStrategyLAP(){columnSelectionStrategyLAP_.clear();} + + /** Set the value for rowSelectionStrategyLAP, which changes the way we + * choose the rows for the reduction step */ + virtual void addRowSelectionStrategyLAP(RowSelectionStrategy value); + /// get the value + inline std::vector<RowSelectionStrategy> getRowSelectionStrategyLAP() const {return rowSelectionStrategyLAP_;}; + /// reset + inline void resetRowSelectionStrategyLAP() {rowSelectionStrategyLAP_.clear();} + + /** Set the value for columnScalingStrategyLAP, which sets the way nonbasic + * columns that are basic in the fractional point to cut off are scaled */ + virtual void setColumnScalingStrategyLAP(ColumnScalingStrategy value); + /// get the value + inline ColumnScalingStrategy getColumnScalingStrategyLAP() const {return columnScalingStrategyLAP_; }; + + /** Set the value for the bound in the column scaling factor */ + virtual void setColumnScalingBoundLAP(double value); + /// get the value + inline double getColumnScalingBoundLAP() const {return columnScalingBoundLAP_;}; + + /** Set the value of the time limit for cut generation (in seconds) */ + virtual void setTimeLimit(double value); + /// get the value + inline double getTimeLimit() const {return timeLimit_;} + + /** Set the value for the maximum number of cuts that can be returned */ + virtual void setMaxNumCuts(int value); + /// get the value + inline int getMaxNumCuts() const {return maxNumCuts_;} + + /** Set the value for the maximum number of cuts that can be computed */ + virtual void setMaxNumComputedCuts(int value); + /// get the value + inline int getMaxNumComputedCuts() const {return maxNumComputedCuts_;} + + /** Set the value for the maximum number of nonzeroes in a row of + * the simplex tableau for the row to be considered */ + virtual void setMaxNonzeroesTab(int value); + /// get the value + inline int getMaxNonzeroesTab() const {return maxNonzeroesTab_;} + + /** Set the value of skipGomory: should we skip simple Gomory cuts, + * i.e. GMI cuts derived from a single row of the simple tableau? + * This is 1 (true) by default: we only generate cuts from linear + * combinations of at least two rows. */ + virtual void setSkipGomory(int value); + /// get the value + inline int getSkipGomory() const {return skipGomory_;} + + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor. If use_default_strategies is true, we add + /// to the list of strategies the default ones. If is false, the + /// list of strategies is left empty (must be populated before usage!). + CglRedSplit2Param(bool use_default_strategies = true, + double eps = 1e-12, + double eps_coeff = 1e-11, + double eps_elim = 0.0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-3, + int max_supp_abs = 1000, + double max_supp_rel = 0.1, + int use_int_slacks = 0, + double norm_zero = 1e-5, + double minNormReduction = 0.1, + int maxSumMultipliers = 10, + double normalization = 0.0001, + double away = 0.005, + double timeLimit = 60, + int maxNumCuts = 10000, + int maxNumComputedCuts = 10000, + int maxNonzeroesTab = 1000, + double columnScalingBoundLAP = 5.0, + int skipGomory = 1); + + /// Constructor from CglParam. If use_default_strategies is true, we + /// add to the list of strategies the default ones. If is false, the + /// list of strategies is left empty (must be populated before + /// usage!). + CglRedSplit2Param(const CglParam &source, + bool use_default_strategies = true, + double eps_elim = 0.0, + double eps_relax_abs = 1e-11, + double eps_relax_rel = 1e-13, + double max_dyn = 1e6, + double min_viol = 1e-3, + double max_supp_rel = 0.1, + int use_int_slacks = 0, + double norm_zero = 1e-5, + double minNormReduction = 0.1, + int maxSumMultipliers = 10, + double normalization = 0.0001, + double away = 0.005, + double timeLimit = 60, + int maxNumCuts = 10000, + int maxNumComputedCuts = 10000, + int maxNonzeroesTab = 1000, + double columnScalingBoundLAP = 5.0, + int skipGomory = 1); + + /// Copy constructor + CglRedSplit2Param(const CglRedSplit2Param &source); + + /// Clone + virtual CglRedSplit2Param* clone() const; + + /// Assignment operator + virtual CglRedSplit2Param& operator=(const CglRedSplit2Param &rhs); + + /// Destructor + virtual ~CglRedSplit2Param(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 0.0. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-11 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 1e-13 */ + double EPS_RELAX_REL; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e6. + double MAXDYN; + + /// Minimum violation for the current basic solution in a generated cut. + /// Default: 1e-3. + double MINVIOL; + + /// Maximum support - relative part of the formula + double MAX_SUPP_REL; + + /// Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. + int USE_INTSLACKS; + + /// Norm of a vector is considered zero if smaller than normIsZero; + /// Default: 1e-5. + double normIsZero_; + + /// Minimum reduction to accept a new row. + double minNormReduction_; + + /// Maximum sum of the vector of row multipliers to generate a cut + int maxSumMultipliers_; + + /// Normalization factor for the norm of lambda in the quadratic + /// minimization problem that is solved during the coefficient reduction step + double normalization_; + + /// Use row only if pivot variable should be integer but is more + /// than away_ from being integer. Default: 0.005 + double away_; + + /// Maximum number of rows to use for the reduction of a given row. + std::vector<int> numRowsReduction_; + + /// Column selection method + std::vector<ColumnSelectionStrategy> columnSelectionStrategy_; + + /// Row selection method + std::vector<RowSelectionStrategy> rowSelectionStrategy_; + + /// Maximum number of rows to use for the reduction during Lift & Project + std::vector<int> numRowsReductionLAP_; + + /// Column selection method for Lift & Project + std::vector<ColumnSelectionStrategy> columnSelectionStrategyLAP_; + + /// Row selection method for Lift & Project + std::vector<RowSelectionStrategy> rowSelectionStrategyLAP_; + + /// Column scaling strategy for the nonbasics columns that were basic in + /// the point that we want to cut off (Lift & Project only) + ColumnScalingStrategy columnScalingStrategyLAP_; + + /// Minimum value for column scaling (Lift & Project only) + double columnScalingBoundLAP_; + + /// Time limit + double timeLimit_; + + /// Maximum number of returned cuts + int maxNumCuts_; + + /// Maximum number of computed cuts + int maxNumComputedCuts_; + + /// Maximum number of nonzeroes in tableau row for reduction + int maxNonzeroesTab_; + + /// Skip simple Gomory cuts + int skipGomory_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglRedSplitParam.hpp b/thirdparty/linux/include/coin1/CglRedSplitParam.hpp new file mode 100644 index 0000000..2601fb2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglRedSplitParam.hpp @@ -0,0 +1,272 @@ +// Name: CglRedSplitParam.hpp +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 11/24/06 +// +// $Id: CglRedSplitParam.hpp 1122 2013-04-06 20:39:53Z stefan $ +//----------------------------------------------------------------------------- +// Copyright (C) 2006, Francois Margot and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglRedSplitParam_H +#define CglRedSplitParam_H + +#include "CglParam.hpp" + + + /**@name CglRedSplit Parameters */ + //@{ + + /** Class collecting parameters the Reduced-and-split cut generator. + + Parameters of the generator are listed below. Modifying the default + values for parameters other than the last four might result in + invalid cuts. + + - LUB: Value considered large for the absolute value of a lower or upper + bound on a variable. See method setLUB(). + - MAXDYN: Maximum ratio between largest and smallest non zero + coefficients in a cut. See method setMAXDYN(). + - MAXDYN_LUB: Maximum ratio between largest and smallest non zero + coefficients in a cut involving structural variables with + lower or upper bound in absolute value larger than LUB. + Should logically be larger or equal to MAXDYN. + See method setMAXDYN_LUB(). + - EPS_ELIM: Precision for deciding if a coefficient is zero when + eliminating slack variables. See method setEPS_ELIM(). + - EPS_COEFF_LUB: Precision for deciding if a coefficient of a + generated cut is zero when the corresponding + variable has a lower or upper bound larger than + LUB in absolute value. See method setEPS_COEFF_LUB(). + - MINVIOL: Minimum violation for the current basic solution in + a generated cut. See method setMINVIOL(). + - USE_INTSLACKS: Use integer slacks to generate cuts. (not implemented). + See method setUSE_INTSLACKS(). + - USE_CG2: Use alternative formula to generate a mixed integer Gomory + cut (see methods CglRedSPlit::generate_cgcut() + and CglRedSPlit::generate_cgcut_2()). See method setUSE_CG2(). + - normIsZero: Norm of a vector is considered zero if smaller than + this value. See method setNormIsZero(). + - minReduc: Reduction is performed only if the norm of the vector is + reduced by this fraction. See method setMinReduc(). + - away: Look only at basic integer variables whose current value + is at least this value from being integer. See method setAway(). + - maxTab: Controls the number of rows selected for the generation. See + method setMaxTab(). + */ + //@} + +class CglRedSplitParam : public CglParam { + +public: + + /**@name Set/get methods */ + //@{ + /** Set away, the minimum distance from being integer used for selecting + rows for cut generation; all rows whose pivot variable should be + integer but is more than away from integrality will be selected; + Default: 0.05 */ + virtual void setAway(const double value); + /// Get value of away + inline double getAway() const {return away_;} + + /** Set the value of LUB, value considered large for the absolute value of + a lower or upper bound on a variable; + Default: 1000 */ + virtual void setLUB(const double value); + /** Get the value of LUB */ + inline double getLUB() const {return LUB;} + + /** Set the value of EPS_ELIM, epsilon for values of coefficients when + eliminating slack variables; + Default: 1e-12 */ + void setEPS_ELIM(const double value); + /** Get the value of EPS_ELIM */ + double getEPS_ELIM() const {return EPS_ELIM;} + + /** Set EPS_RELAX_ABS */ + virtual void setEPS_RELAX_ABS(const double eps_ra); + /** Get value of EPS_RELAX_ABS */ + inline double getEPS_RELAX_ABS() const {return EPS_RELAX_ABS;} + + /** Set EPS_RELAX_REL */ + virtual void setEPS_RELAX_REL(const double eps_rr); + /** Get value of EPS_RELAX_REL */ + inline double getEPS_RELAX_REL() const {return EPS_RELAX_REL;} + + // Set the maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e8. + virtual void setMAXDYN(double value); + /** Get the value of MAXDYN */ + inline double getMAXDYN() const {return MAXDYN_LUB;} + + // Set the maximum ratio between largest and smallest non zero + // coefficient in a cut involving structural variables with + // lower or upper bound in absolute value larger than LUB. + // Should logically be larger or equal to MAXDYN. Default: 1e13. + virtual void setMAXDYN_LUB(double value); + /** Get the value of MAXDYN_LUB */ + inline double getMAXDYN_LUB() const {return MAXDYN_LUB;} + + /** Set the value of EPS_COEFF_LUB, epsilon for values of coefficients for + variables with absolute value of lower or upper bound larger than LUB; + Default: 1e-13 */ + virtual void setEPS_COEFF_LUB(const double value); + /** Get the value of EPS_COEFF_LUB */ + inline double getEPS_COEFF_LUB() const {return EPS_COEFF_LUB;} + + /** Set the value of MINVIOL, the minimum violation for the current + basic solution in a generated cut. Default: 1e-7 */ + virtual void setMINVIOL(double value); + /** Get the value of MINVIOL */ + inline double getMINVIOL() const {return MINVIOL;} + + /** Set the value of USE_INTSLACKS. Default: 0 */ + virtual void setUSE_INTSLACKS(int value); + /** Get the value of USE_INTSLACKS */ + inline int getUSE_INTSLACKS() const {return USE_INTSLACKS;} + + /** Set the value of USE_CG2. Default: 0 */ + virtual void setUSE_CG2(int value); + /** Get the value of USE_CG2 */ + inline int getUSE_CG2() const {return USE_CG2;} + + /** Set the value of normIsZero, the threshold for considering a norm to be + 0; Default: 1e-5 */ + virtual void setNormIsZero(const double value); + /** Get the value of normIsZero */ + inline double getNormIsZero() const {return normIsZero;} + + /** Set the value of minReduc, threshold for relative norm improvement for + performing a reduction; Default: 0.05 */ + virtual void setMinReduc(const double value); + /// Get the value of minReduc + inline double getMinReduc() const {return minReduc;} + + /** Set the maximum allowed value for (mTab * mTab * CoinMax(mTab, nTab)) where + mTab is the number of rows used in the combinations and nTab is the + number of continuous non basic variables. The work of the generator is + proportional to (mTab * mTab * CoinMax(mTab, nTab)). Reducing the value of + maxTab makes the generator faster, but weaker. Default: 1e7. */ + virtual void setMaxTab(const double value); + /// Get the value of maxTab + inline double getMaxTab() const {return maxTab_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglRedSplitParam(const double lub = 1000.0, + const double eps_elim = 1e-12, + const double eps_relax_abs = 1e-8, + const double eps_relax_rel = 0.0, + const double max_dyn = 1e8, + const double max_dyn_lub = 1e13, + const double eps_coeff_lub = 1e-13, + const double min_viol = 1e-7, + const int use_int_slacks = 0, + const int use_cg2 = 0, + const double norm_zero = 1e-5, + const double min_reduc = 0.05, + const double away = 0.05, + const double max_tab = 1e7); + + /// Constructor from CglParam + CglRedSplitParam(const CglParam &source, + const double lub = 1000.0, + const double eps_elim = 1e-12, + const double eps_relax_abs = 1e-8, + const double eps_relax_rel = 0.0, + const double max_dyn = 1e8, + const double max_dyn_lub = 1e13, + const double eps_coeff_lub = 1e-13, + const double min_viol = 1e-7, + const int use_int_slacks = 0, + const int use_cg2 = 0, + const double norm_zero = 1e-5, + const double min_reduc = 0.05, + const double away = 0.05, + const double max_tab = 1e7); + + /// Copy constructor + CglRedSplitParam(const CglRedSplitParam &source); + + /// Clone + virtual CglRedSplitParam* clone() const; + + /// Assignment operator + virtual CglRedSplitParam& operator=(const CglRedSplitParam &rhs); + + /// Destructor + virtual ~CglRedSplitParam(); + //@} + +protected: + + /**@name Parameters */ + //@{ + + /** Value considered large for the absolute value of lower or upper + bound on a variable. Default: 1000. */ + double LUB; + + /** Epsilon for value of coefficients when eliminating slack variables. + Default: 1e-12. */ + double EPS_ELIM; + + /** Value added to the right hand side of each generated cut to relax it. + Default: 1e-8 */ + double EPS_RELAX_ABS; + + /** For a generated cut with right hand side rhs_val, + EPS_RELAX_EPS * fabs(rhs_val) is used to relax the constraint. + Default: 0 */ + double EPS_RELAX_REL; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut. Default: 1e8. + double MAXDYN; + + // Maximum ratio between largest and smallest non zero + // coefficients in a cut involving structural variables with + // lower or upper bound in absolute value larger than LUB. + // Should logically be larger or equal to MAXDYN. Default: 1e13. + double MAXDYN_LUB; + + /// Epsilon for value of coefficients for variables with absolute value of + /// lower or upper bound larger than LUB. Default: 1e-13. + double EPS_COEFF_LUB; + + /// Minimum violation for the current basic solution in a generated cut. + /// Default: 1e-7. + double MINVIOL; + + /// Use integer slacks to generate cuts if USE_INTSLACKS = 1. Default: 0. + int USE_INTSLACKS; + + /// Use second way to generate a mixed integer Gomory cut + /// (see methods generate_cgcut()) and generate_cgcut_2()). Default: 0. + int USE_CG2; + + /// Norm of a vector is considered zero if smaller than normIsZero; + /// Default: 1e-5. + double normIsZero; + + /// Minimum reduction in percent that must be achieved by a potential + /// reduction step in order to be performed; Between 0 and 1, default: 0.05. + double minReduc; + + /// Use row only if pivot variable should be integer but is more + /// than away_ from being integer. + double away_; + + /// Maximum value for (mTab * mTab * CoinMax(mTab, nTab)). See method + /// setMaxTab(). + double maxTab_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CglResidualCapacity.hpp b/thirdparty/linux/include/coin1/CglResidualCapacity.hpp new file mode 100644 index 0000000..1e26e46 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglResidualCapacity.hpp @@ -0,0 +1,240 @@ +// LAST EDIT: +//----------------------------------------------------------------------------- +// Implementation of Residual Capacity Inequalities +// Francisco Barahona (barahon@us.ibm.com) +// +// date: May 18, 2006 +//----------------------------------------------------------------------------- +// Copyright (C) 2004, International Business Machines Corporation and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. + +#ifndef CglResidualCapacity_H +#define CglResidualCapacity_H + +#include <iostream> +#include <fstream> +//#include <vector> + +#include "CoinError.hpp" + +#include "CglCutGenerator.hpp" + +//============================================================================= + +#ifndef CGL_DEBUG +#define CGL_DEBUG 0 +#endif + +//============================================================================= + + + + +//============================================================================= + +/** Residual Capacity Inequalities Cut Generator Class + + References: + T Magnanti, P Mirchandani, R Vachani, + "The convex hull of two core capacitated network design problems," + Math Programming 60 (1993), 233-250. + + A Atamturk, D Rajan, + "On splittable and unsplittable flow capacitated network design + arc-set polyhedra," Math Programming 92 (2002), 315-333. **/ + +class CglResidualCapacity : public CglCutGenerator { + + friend void CglResidualCapacityUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +private: + //--------------------------------------------------------------------------- + // Enumeration constants that describe the various types of rows + enum RowType { + /** row of the type a_1 c_1 + + a_k c_k - d z_1 - - d z_p <= b, + where c_i are continuous variables and z_j are integer variables + */ + ROW_L, + /** row of the type -a_1 c_1 - - a_k c_k + d z_1 + + d z_p >= b, + where c_i are continuous variables and z_j are integer variables + */ + ROW_G, + /** equation that can be treated as ROW_L and ROW_G + */ + ROW_BOTH, + /** Other types of rows + */ + ROW_OTHER + }; + + +public: + /**@name Get and Set Parameters */ + //@{ + /// Set Epsilon + void setEpsilon(double value); + /// Get Epsilon + double getEpsilon() const; + /// Set Tolerance + void setTolerance(double value); + /// Get Tolerance + double getTolerance() const; + /// Set doPreproc + void setDoPreproc(int value); + /// Get doPreproc + bool getDoPreproc() const; + //@} + + /**@name Generate Cuts */ + //@{ + /** Generate Residual Capacity cuts for the model data + contained in si. The generated cuts are inserted + in the collection of cuts cs. + */ + virtual void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + //--------------------------------------------------------------------------- + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglResidualCapacity (); + + /// Alternate Constructor + CglResidualCapacity ( const double tolerance ); + + /// Copy constructor + CglResidualCapacity ( + const CglResidualCapacity &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglResidualCapacity & + operator=( + const CglResidualCapacity& rhs); + + /// Destructor + virtual + ~CglResidualCapacity (); + /// This is to refresh preprocessing + virtual void refreshPrep(); + //@} + + + +private: + //-------------------------------------------------------------------------- + // Private member methods + + // Construct + void gutsOfConstruct ( const double tolerance); + + // Delete + void gutsOfDelete(); + + // Copy + void gutsOfCopy (const CglResidualCapacity& rhs); + + // Do preprocessing. + // It determines the type of each row. + // It may change sense and RHS for ranged rows + void resCapPreprocess(const OsiSolverInterface& si); + + // Determine the type of a given row. + RowType determineRowType(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, const char sense, + const double rhs, + const double* colLowerBound, + const double* colUpperBound) const; + // helps the function above + bool treatAsLessThan(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, + const double rhs, + const double* colLowerBound, + const double* colUpperBound) const; + + // Generate Residual Capacity cuts + void generateResCapCuts( const OsiSolverInterface& si, + const double* xlp, + const double* colUpperBound, + const double* colLowerBound, + const CoinPackedMatrix& matrixByRow, + const double* LHS, + const double* coefByRow, + const int* colInds, + const int* rowStarts, + const int* rowLengths, + OsiCuts& cs ) const; + + + // Residual Capacity separation + bool resCapSeparation(const OsiSolverInterface& si, + const int rowLen, const int* ind, + const double* coef, + const double rhs, + const double *xlp, + const double* colUpperBound, + const double* colLowerBound, + OsiRowCut& resCapCut) const; + + + +private: + //--------------------------------------------------------------------------- + // Private member data + /** Tolerance used for numerical purposes, default value: 1.e-6 **/ + double EPSILON_; + /** If violation of a cut is greater that this number, + the cut is accepted, default value: 1.e-4 **/ + double TOLERANCE_; + /** Controls the preprocessing of the matrix to identify rows suitable for + cut generation.<UL> + <LI> -1: preprocess according to solver settings; + <LI> 0: Do preprocessing only if it has not yet been done; + <LI> 1: Do preprocessing. + </UL> + Default value: -1 **/ + int doPreproc_; + // The number of rows of the problem. + int numRows_; + // The number columns of the problem. + int numCols_; + // Indicates whether preprocessing has been done. + bool doneInitPre_; + // Array with the row types of the rows in the model. + RowType* rowTypes_; + // The indices of the rows of the initial matrix + int* indRows_; + // Sense of rows (modified if ranges) + char * sense_; + // RHS of rows (modified if ranges) + double * RHS_; + // The number of rows of type ROW_L + int numRowL_; + // The indices of the rows of type ROW_L + int* indRowL_; + // The number of rows of type ROW_G + int numRowG_; + // The indices of the rows of type ROW_G + int* indRowG_; +}; + +//############################################################################# +/** A function that tests the methods in the CglResidualCapacity class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglResidualCapacityUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +#endif diff --git a/thirdparty/linux/include/coin1/CglSimpleRounding.hpp b/thirdparty/linux/include/coin1/CglSimpleRounding.hpp new file mode 100644 index 0000000..b93c8bf --- /dev/null +++ b/thirdparty/linux/include/coin1/CglSimpleRounding.hpp @@ -0,0 +1,174 @@ +// $Id: CglSimpleRounding.hpp 1149 2013-10-21 18:23:53Z tkr $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglSimpleRounding_H +#define CglSimpleRounding_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinPackedMatrix.hpp" + +/** Simple Rounding Cut Generator Class + + This class generates simple rounding cuts via the following method: + For each contraint, + attempt to derive a <= inequality in all integer variables + by netting out any continuous variables. + Divide the resulting integer inequality through by + the greatest common denomimator (gcd) of the lhs coefficients. + Round down the rhs. + + Warning: Use with careful attention to data precision. + + (Reference: Nemhauser and Wolsey, Integer and Combinatorial Optimization, 1988, pg 211.) +*/ + +class CglSimpleRounding : public CglCutGenerator { + friend void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate simple rounding cuts for the model accessed through the solver interface. + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglSimpleRounding (); + + /// Copy constructor + CglSimpleRounding ( + const CglSimpleRounding &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglSimpleRounding & + operator=( + const CglSimpleRounding& rhs); + + /// Destructor + virtual + ~CglSimpleRounding (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + + /// Derive a <= inequality in integer variables from the rowIndex-th constraint + bool deriveAnIntegerRow( + const OsiSolverInterface & si, + int rowIndex, + const CoinShallowPackedVector & matrixRow, + CoinPackedVector & irow, + double & b, + bool * negative) const; + + + /** Given a vector of doubles, x, with size elements and a positive tolerance, + dataTol, this method returns the smallest power of 10 needed so that + x[i]*10**power "is integer" for all i=0,...,size-1. + + ** change of definition of dataTol so that it refers to original + data, not to scaled data as that seems to lead to problems. + + So if xScaled is x[i]*10**power and xInt is rounded(xScaled) + then fabs(xScaled-xInt) <= dataTol*10**power. This means that + dataTol should be smaller - say 1.0e-12 rather tahn 1.0e-8 + + Returns -number of times overflowed if the power is so big that it will + cause overflow (i.e. integer stored will be bigger than 2**31). + Test in cut generator. + */ + int power10ToMakeDoubleAnInt( + int size, // the length of the vector x + const double * x, + double dataTol ) const; // the precision of the data, i.e. the positive + // epsilon, which is equivalent to zero + + /**@name Greatest common denominators methods */ + //@{ + /// Returns the greatest common denominator of two positive integers, a and b. + inline int gcd(int a, int b) const; + + /** Returns the greatest common denominator of a vector of + positive integers, vi, of length n. + */ + inline int gcdv(int n, const int * const vi) const; + //@} + + //@} + + /**@name Private member data */ + //@{ + /// A value within an epsilon_ neighborhood of 0 is considered to be 0. + double epsilon_; + //@} +}; + + +//------------------------------------------------------------------- +// Returns the greatest common denominator of two +// positive integers, a and b, found using Euclid's algorithm +//------------------------------------------------------------------- +int +CglSimpleRounding::gcd(int a, int b) const +{ + if(a > b) { + // Swap a and b + int temp = a; + a = b; + b = temp; + } + int remainder = b % a; + if (remainder == 0) return a; + else return gcd(remainder,a); +} + +//------------------------------------------------------------------- +// Returns the greatest common denominator of a vector of +// positive integers, vi, of length n. +//------------------------------------------------------------------- +int +CglSimpleRounding::gcdv(int n, const int* const vi) const +{ + if (n==0) + abort(); + + if (n==1) + return vi[0]; + + int retval=gcd(vi[0], vi[1]); + for (int i=2; i<n; i++){ + retval=gcd(retval,vi[i]); + } + return retval; +} + +//############################################################################# +/** A function that tests the methods in the CglSimpleRounding class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglSimpleRoundingUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/CglStored.hpp b/thirdparty/linux/include/coin1/CglStored.hpp new file mode 100644 index 0000000..07039d9 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglStored.hpp @@ -0,0 +1,125 @@ +// $Id: CglStored.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglStored_H +#define CglStored_H + +#include <string> + +#include "CglCutGenerator.hpp" + +class CoinWarmStartBasis; +class CglTreeProbingInfo; +/** Stored Cut Generator Class */ +class CglStored : public CglCutGenerator { + +public: + + + /**@name Generate Cuts */ + //@{ + /** Generate Mixed Integer Stored cuts for the model of the + solver interface, si. + + Insert the generated cuts into OsiCut, cs. + + This generator just looks at previously stored cuts + and inserts any that are violated by enough + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Change criterion on whether to include cut. + Violations of more than this will be added to current cut list + (default 1.0e-5) */ + //@{ + /// Set + inline void setRequiredViolation(double value) + { requiredViolation_=value;} + /// Get + inline double getRequiredViolation() const + { return requiredViolation_;} + /// Takes over ownership of probing info + inline void setProbingInfo(CglTreeProbingInfo * info) + { probingInfo_ = info;} + //@} + + /**@name Cut stuff */ + //@{ + /// Add cuts + void addCut(const OsiCuts & cs); + /// Add a row cut + void addCut(const OsiRowCut & cut); + /// Add a row cut from a packed vector + void addCut(double lb, double ub, const CoinPackedVector & vector); + /// Add a row cut from elements + void addCut(double lb, double ub, int size, const int * colIndices, const double * elements); + inline int sizeRowCuts() const + { return cuts_.sizeRowCuts();} + const OsiRowCut * rowCutPointer(int index) const + { return cuts_.rowCutPtr(index);} + /// Save stuff + void saveStuff(double bestObjective, const double * bestSolution, + const double * lower, const double * upper); + /// Best solution (or NULL) + inline const double * bestSolution() const + { return bestSolution_;} + /// Best objective + double bestObjective() const; + /// Tight lower bounds + const double * tightLower() const + { return bounds_;} + /// Tight upper bounds + const double * tightUpper() const + { return bounds_+numberColumns_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglStored (int numberColumns=0); + + /// Copy constructor + CglStored (const CglStored & rhs); + + /// Constructor from file + CglStored (const char * fileName); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglStored & + operator=(const CglStored& rhs); + + /// Destructor + virtual + ~CglStored (); + //@} + +protected: + + // Protected member methods + + // Protected member data + + /**@name Protected member data */ + //@{ + /// Only add if more than this requiredViolation + double requiredViolation_; + /// Pointer to probing information + CglTreeProbingInfo * probingInfo_; + /// Cuts + OsiCuts cuts_; + /// Number of columns in model + int numberColumns_; + /// Best solution (objective at end) + double * bestSolution_; + /// Tight bounds + double * bounds_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CglTreeInfo.hpp b/thirdparty/linux/include/coin1/CglTreeInfo.hpp new file mode 100644 index 0000000..4f85aca --- /dev/null +++ b/thirdparty/linux/include/coin1/CglTreeInfo.hpp @@ -0,0 +1,180 @@ +// $Id: CglTreeInfo.hpp 1201 2014-03-07 17:24:04Z forrest $ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglTreeInfo_H +#define CglTreeInfo_H + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" +#include "CoinHelperFunctions.hpp" +class CglStored; +/** Information about where the cut generator is invoked from. */ + +class CglTreeInfo { +public: + /// The level of the search tree node + int level; + /** How many times the cut generator was already invoked in this search tree + node */ + int pass; + /** The number of rows in the original formulation. Some generators may not + want to consider already generated rows when generating new ones. */ + int formulation_rows; + /** Options + 1 - treat costed integers as important + 2 - switch off some stuff as variables semi-integer + 4 - set global cut flag if at root node + 8 - set global cut flag if at root node and first pass + 16 - set global cut flag and make cuts globally valid + 32 - last round of cuts did nothing - maybe be more aggressive + 64 - in preprocessing stage + 128 - looks like solution + 256 - want alternate cuts + 512 - in sub tree (i.e. parent model) + 1024 - in must call again mode or after everything mode + */ + int options; + /// Set true if in tree (to avoid ambiguity at first branch) + bool inTree; + /** Replacement array. Before Branch and Cut it may be beneficial to strengthen rows + rather than adding cuts. If this array is not NULL then the cut generator can + place a pointer to the stronger cut in this array which is number of rows in size. + + A null (i.e. zero elements and free rhs) cut indicates that the row is useless + and can be removed. + + The calling function can then replace those rows. + */ + OsiRowCut ** strengthenRow; + /// Optional pointer to thread specific random number generator + CoinThreadRandom * randomNumberGenerator; + /// Default constructor + CglTreeInfo (); + + /// Copy constructor + CglTreeInfo ( + const CglTreeInfo &); + /// Clone + virtual CglTreeInfo * clone() const; + + /// Assignment operator + CglTreeInfo & + operator=( + const CglTreeInfo& rhs); + + /// Destructor + virtual + ~CglTreeInfo (); + /// Take action if cut generator can fix a variable (toValue -1 for down, +1 for up) + virtual bool fixes(int , int , int ,bool) {return false;} + /** Initalizes fixing arrays etc - returns >0 if we want to save info + 0 if we don't and -1 if is to be used */ + virtual int initializeFixing(const OsiSolverInterface * ) {return 0;} + +}; + +/** Derived class to pick up probing info. */ +typedef struct { + //unsigned int oneFixed:1; // nonzero if variable to 1 fixes all + //unsigned int sequence:31; // variable (in matrix) (but also see cliqueRow_) + unsigned int fixes; +} CliqueEntry; + +class CglTreeProbingInfo : public CglTreeInfo { +public: + /// Default constructor + CglTreeProbingInfo (); + /// Constructor from model + CglTreeProbingInfo (const OsiSolverInterface * model); + + /// Copy constructor + CglTreeProbingInfo ( + const CglTreeProbingInfo &); + /// Clone + virtual CglTreeInfo * clone() const; + + /// Assignment operator + CglTreeProbingInfo & + operator=( + const CglTreeProbingInfo& rhs); + + /// Destructor + virtual + ~CglTreeProbingInfo (); + OsiSolverInterface * analyze(const OsiSolverInterface & si, int createSolver=0, + int numberExtraCliques=0,const int * starts=NULL, + const CliqueEntry * entries=NULL,const char * type=NULL); + /** Take action if cut generator can fix a variable + (toValue -1 for down, +1 for up) + Returns true if still room, false if not */ + virtual bool fixes(int variable, int toValue, int fixedVariable,bool fixedToLower); + /** Initalizes fixing arrays etc - returns >0 if we want to save info + 0 if we don't and -1 if is to be used */ + virtual int initializeFixing(const OsiSolverInterface * model) ; + /// Fix entries in a solver using implications + int fixColumns(OsiSolverInterface & si) const; + /// Fix entries in a solver using implications for one variable + int fixColumns(int iColumn, int value, OsiSolverInterface & si) const; + /// Packs down entries + int packDown(); + /// Generate cuts from implications + void generateCuts(const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info) const; + /// Entries for fixing variables + inline CliqueEntry * fixEntries() + { convert(); return fixEntry_;} + /// Starts of integer variable going to zero + inline int * toZero() + { convert(); return toZero_;} + /// Starts of integer variable going to one + inline int * toOne() + { convert(); return toOne_;} + /// List of 0-1 integer variables + inline int * integerVariable() const + { return integerVariable_;} + /// Backward look up + inline int * backward() const + { return backward_;} + /// Number of variables + inline int numberVariables() const + { return numberVariables_;} + /// Number of 0-1 variables + inline int numberIntegers() const + { return numberIntegers_;} +private: + /// Converts to ordered + void convert(); +protected: + /// Entries for fixing variables + CliqueEntry * fixEntry_; + /// Starts of integer variable going to zero + int * toZero_; + /// Starts of integer variable going to one + int * toOne_; + /// List of 0-1 integer variables + int * integerVariable_; + /// Backward look up + int * backward_; + /// Entries for fixing variable when collecting + int * fixingEntry_; + /// Number of variables + int numberVariables_; + /// Number of 0-1 variables + int numberIntegers_; + /// Maximum number in fixEntry_ + int maximumEntries_; + /// Number entries in fixingEntry_ (and fixEntry_) or -2 if correct style + int numberEntries_; +}; +inline int sequenceInCliqueEntry(const CliqueEntry & cEntry) +{ return cEntry.fixes&0x7fffffff;} +inline void setSequenceInCliqueEntry(CliqueEntry & cEntry,int sequence) +{ cEntry.fixes = sequence|(cEntry.fixes&0x80000000);} +inline bool oneFixesInCliqueEntry(const CliqueEntry & cEntry) +{ return (cEntry.fixes&0x80000000)!=0;} +inline void setOneFixesInCliqueEntry(CliqueEntry & cEntry,bool oneFixes) +{ cEntry.fixes = (oneFixes ? 0x80000000 : 0)|(cEntry.fixes&0x7fffffff);} + +#endif diff --git a/thirdparty/linux/include/coin1/CglTwomir.hpp b/thirdparty/linux/include/coin1/CglTwomir.hpp new file mode 100644 index 0000000..ba00380 --- /dev/null +++ b/thirdparty/linux/include/coin1/CglTwomir.hpp @@ -0,0 +1,565 @@ +// $Id: CglTwomir.hpp 1119 2013-04-06 20:24:18Z stefan $ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CglTwomir_H +#define CglTwomir_H +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinFactorization.hpp" + +typedef struct +{ + + int nz; /* current length of arrays index[] and coeff[] */ + int max_nz; /* max length of arrays index[] and coeff[] */ + double *coeff; /* coefficient of each variable in the constraint */ + int *index; /* index of the variable (value in 0 ... nrow+ncol) */ + double rhs; /* rhs of the constraint */ + char sense; /* ?? is it necessary */ + +} DGG_constraint_t; + +typedef struct{ + int n; + DGG_constraint_t **c; + int *ctype; + double *alpha; +} DGG_list_t; + +/******************** BASIS INFORMATION ADTs **********************************/ +typedef struct{ + int q_min; + int q_max; + int t_min; + int t_max; + int a_max; + int max_elements; +} cutParams; + +typedef struct +{ + double gomory_threshold; /* factional variable must be this away from int */ + int ncol, /* number of columns in LP */ + nrow, /* number of constaints in LP */ + ninteger; /* number of integer variables in LP */ + + int nbasic_col, /* number of basic columns in the LP */ + nbasic_row; /* number of basic rows in the LP */ + + /* the following arrays are all of size (ncol+nrow) */ + int *info; /* description of each variable (see below) */ + double *lb; /* specifies the lower bound (if any) of each variable */ + double *ub; /* specifies the upper bound (if any) of each variable */ + double *x; /* current solution */ + double *rc; /* current reduced cost */ + double *opt_x; + + cutParams cparams; +} DGG_data_t; + +/* the following macros allow us to decode the info of the DGG_data + type. The encoding is as follows, + bit 1 : if the variable is basic or not (non-basic). + bit 2 : if the variable is integer or or not (rational). + bit 3 : if the variable is structural or not (artifical). + bit 4 : if the variable is non-basic and at its upper bound + (else if non-basic at lower bound). */ + +#define DGG_isBasic(data,idx) ((data->info[idx])&1) +#define DGG_isInteger(data,idx) ((data->info[idx] >> 1)&1) +#define DGG_isStructural(data,idx) ((data->info[idx] >> 2)&1) +#define DGG_isEqualityConstraint(data,idx) ((data->info[idx] >> 3)&1) +#define DGG_isNonBasicAtUB(data,idx) ((data->info[idx] >> 4)&1) +#define DGG_isNonBasicAtLB(data,idx) ((data->info[idx] >> 5)&1) +#define DGG_isConstraintBoundedAbove(data,idx) ((data->info[idx] >> 6)&1) +#define DGG_isConstraintBoundedBelow(data,idx) ((data->info[idx] >> 7)&1) + +#define DGG_setIsBasic(data,idx) ((data->info[idx]) |= 1) +#define DGG_setIsInteger(data,idx) ((data->info[idx]) |= (1<<1)) +#define DGG_setIsStructural(data,idx) ((data->info[idx]) |= (1<<2)) +#define DGG_setEqualityConstraint(data,idx) ((data->info[idx]) |= (1<<3)) +#define DGG_setIsNonBasicAtUB(data,idx) ((data->info[idx]) |= (1<<4)) +#define DGG_setIsNonBasicAtLB(data,idx) ((data->info[idx]) |= (1<<5)) +#define DGG_setIsConstraintBoundedAbove(data,idx) ((data->info[idx]) |= (1<<6)) +#define DGG_setIsConstraintBoundedBelow(data,idx) ((data->info[idx]) |= (1<<7)) + +class CoinWarmStartBasis; +/** Twostep MIR Cut Generator Class */ +class CglTwomir : public CglCutGenerator { + + friend void CglTwomirUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + + +public: + + /// Problem name + std::string probname_; + + /**@name Generate Cuts */ + //@{ + /** Generate Two step MIR cuts either from the tableau rows or from the + formulation rows + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + /// Return true if needs optimal basis to do cuts (will return true) + virtual bool needsOptimalBasis() const; + + /**@name Change criterion on which scalings to use (default = 1,1,1,1) */ + //@{ + /// Set + void setMirScale (int tmin, int tmax) {t_min_ = tmin; t_max_ = tmax;} + void setTwomirScale (int qmin, int qmax) {q_min_ = qmin; q_max_ = qmax;} + void setAMax (int a) {a_max_ = a;} + void setMaxElements (int n) {max_elements_ = n;} + void setMaxElementsRoot (int n) {max_elements_root_ = n;} + void setCutTypes (bool mir, bool twomir, bool tab, bool form) + { do_mir_ = mir; do_2mir_ = twomir; do_tab_ = tab; do_form_ = form;} + void setFormulationRows (int n) {form_nrows_ = n;} + + /// Get + int getTmin() const {return t_min_;} + int getTmax() const {return t_max_;} + int getQmin() const {return q_min_;} + int getQmax() const {return q_max_;} + int getAmax() const {return a_max_;} + int getMaxElements() const {return max_elements_;} + int getMaxElementsRoot() const {return max_elements_root_;} + int getIfMir() const { return do_mir_;} + int getIfTwomir() const { return do_2mir_;} + int getIfTableau() const { return do_tab_;} + int getIfFormulation() const { return do_form_;} + //@} + + /**@name Change criterion on which variables to look at. All ones + more than "away" away from integrality will be investigated + (default 0.05) */ + //@{ + /// Set away + void setAway(double value); + /// Get away + double getAway() const; + /// Set away at root + void setAwayAtRoot(double value); + /// Get away at root + double getAwayAtRoot() const; + /// Return maximum length of cut in tree + virtual int maximumLengthOfCutInTree() const + { return max_elements_;} + //@} + + /**@name Change way TwoMir works */ + //@{ + /// Pass in a copy of original solver (clone it) + void passInOriginalSolver(OsiSolverInterface * solver); + /// Returns original solver + inline OsiSolverInterface * originalSolver() const + { return originalSolver_;} + /// Set type - 0 normal, 1 add original matrix one, 2 replace + inline void setTwomirType(int type) + { twomirType_=type;} + /// Return type + inline int twomirType() const + { return twomirType_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglTwomir (); + + /// Copy constructor + CglTwomir (const CglTwomir &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglTwomir & operator=(const CglTwomir& rhs); + + /// Destructor + virtual ~CglTwomir (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any inforamtion + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + // Private member data + /**@name Private member data */ + //@{ + /// Threadsafe random number generator + CoinThreadRandom randomNumberGenerator_; + /// Original solver + OsiSolverInterface * originalSolver_; + /// Only investigate if more than this away from integrality + double away_; + /// Only investigate if more than this away from integrality (at root) + double awayAtRoot_; + /// Type - 0 normal, 1 add original matrix one, 2 replace + int twomirType_; + bool do_mir_; + bool do_2mir_; + bool do_tab_; + bool do_form_; + + int t_min_; /// t_min - first value of t to use for tMIR inequalities + int t_max_; /// t_max - last value of t to use for tMIR inequalities + int q_min_; /// q_min - first value of t to use for 2-Step tMIR inequalities + int q_max_; /// q_max - last value of t to use for 2-Step tMIR inequalities + int a_max_; /// a_max - maximum value of bhat/alpha + int max_elements_; /// Maximum number of elements in cut + int max_elements_root_; /// Maximum number of elements in cut at root + int form_nrows_; //number of rows on which formulation cuts will be generated + //@} +}; + +//############################################################################# + +/* +#include <stdlib.h> +#include <stdio.h> +#include <stdarg.h> +#include <math.h> +#include <float.h> +#include <cassert> +#include <iostream.h> +*/ + +/******************** DEBUG DEFINITIONS ***************************************/ + +#define DGG_DEBUG_DGG 1 +#define DGG_TRACE_ERRORS 0 +#define DGG_DISPLAY 0 +#define DGG_AUTO_CHECK_CUT_OFF_OPTIMAL 1 + +/******************** CONFIGURATION DEFAULTS **********************************/ + +#define DGG_DEFAULT_METHOD 2 +#define DGG_DEFAULT_TMIN 1 +#define DGG_DEFAULT_TMAX 1 +#define DGG_DEFAULT_TAUMIN 2 +#define DGG_DEFAULT_TAUMAX 6 +#define DGG_DEFAULT_MAX_CUTS 500 +#define DGG_DEFAULT_IMPROVEMENT_THRESH 0.001 +#define DGG_DEFAULT_NBELOW_THRESH INT_MAX +#define DGG_DEFAULT_NROOT_ROUNDS 2 +#define DGG_DEFAULT_NEGATIVE_SCALED_TWOSTEPS 0 +#define DGG_DEFAULT_ALPHA_RULE 0 +#define DGG_DEFAULT_CUT_INC 250 +#define DGG_DEFAULT_CUT_FORM 0 +#define DGG_DEFAULT_NICEFY 0 +#define DGG_DEFAULT_ONLY_DELAYED 0 +#define DGG_DEFAULT_DELAYED_FREQ 9999999 +#define DGG_DEFAULT_LPROWS_FREQ 9999999 +#define DGG_DEFAULT_WHICH_FORMULATION_CUTS 2 + +/******************** SOLVER CONFIGURATION DEFINITIONS ************************/ + +#define DGG_OSI 0 +#define DGG_CPX 1 +#define DGG_QSO 2 + +/* determines the solver to be used */ +#define DGG_SOLVER DGG_OSI + +/* adds checking routines to make sure solver works as expected */ +#define DGG_DEBUG_SOLVER 0 + +/* turn off screen output from solver */ +#define DGG_SOLVER_SCREEN_FLAG 0 + +/******************** CUT DEFINITIONS *****************************************/ + +/* internal names for cut types */ +#define DGG_TMIR_CUT 1 +#define DGG_2STEP_CUT 2 + +/* internal names for alpha-selection rules */ +#define DGG_ALPHA_MIN_SUM 0 +#define DGG_ALPHA_RANDOM_01 1 +#define DGG_ALPHA_RANDOM_COEFF 2 +#define DGG_ALPHA_ALL 3 +#define DGG_ALPHA_MAX_STEEP 5 + +/******************** PRECISION & NUMERICAL ISSUES DEFINITIONS ****************/ + +/* how steep a cut must be before adding it to the lp */ +#define DGG_MIN_STEEPNESS 1.0e-4 +#define DGG_MAX_L2NORM 1.0e7 + +/* 0 = min steepness, 1 = max norm */ +#define DGG_NORM_CRITERIA 1 + +/* internal representation of +infinity */ +#define UB_MAX DBL_MAX + +/* used to define how fractional a basic-integer variable must be + before choosing to use it to generate a TMIR cut on. + OSI's default is 1.0e-7 */ +#define DGG_GOMORY_THRESH 0.005 + +#define DGG_RHS_THRESH 0.005 + +/* used for comparing variables to their upper bounds. + OSI's default is 1.0e-7. + We set it to 1.0e6 because e-7 seems too sensitive. + In fact, with e-7 the problem dsbmip.mps complains. */ +#define DGG_BOUND_THRESH 1.0e-6 + +/* used for comparing the lhs (activity) value of a tableau row + with the rhs. This is only used for debugging purposes. */ +#define DGG_EQUALITY_THRESH 1.0e-5 + +/* used for comparing a variable's lower bound to 0.0 + and determining if we need to shift the variable */ +#define DGG_SHIFT_THRESH 1.0e-6 + +/* used for determing how far from an integer is still an integer. + This value is used for comparing coefficients to integers. + OSI's default is 1.0e-10. */ +#define DGG_INTEGRALITY_THRESH 1.0e-10 + +/* the min value that a coeff can have in the tableau row + before being set to zero. */ +#define CBC_CHECK_CUT +#ifndef CBC_CHECK_CUT +#define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-8 +#else +#define DGG_MIN_TABLEAU_COEFFICIENT 1.0e-12 +#endif + +/* smallest value rho is allowed to have for a simple 2-step MIR + (ie: not an extended two-step MIR) */ +#define DGG_MIN_RHO 1.0e-7 +#define DGG_MIN_ALPHA 1.0e-7 + +/* when a slack is null: used to check if a cut is satisfied or not. */ +#define DGG_NULL_SLACK 1.0e-5 + +/* nicefy constants */ +#define DGG_NICEFY_MIN_ABSVALUE 1.0e-13 +#define DGG_NICEFY_MIN_FIX 1.0e-7 +#define DGG_NICEFY_MAX_PADDING 1.0e-6 +#define DGG_NICEFY_MAX_RATIO 1.0e9 + + +/******************** ERROR-CATCHING MACROS ***********************************/ +#if DGG_TRACE_ERRORS > 0 + +#define __DGG_PRINT_LOC__(F) fprintf(((F==0)?stdout:F), " in %s (%s:%d)\n", __func__, __FILE__, __LINE__) + +#define DGG_THROW(A,REST...) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + return (A);} + +#define DGG_IF_EXIT(A,B,REST...) {\ + if(A) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + exit(B);}} + +#define DGG_CHECKRVAL(A,B) {\ + if(A) {\ + __DGG_PRINT_LOC__(stdout); \ + return B; } } + +#define DGG_CHECKRVAL1(A,B) {\ + if(A) {\ + __DGG_PRINT_LOC__(stdout); \ + rval = B; goto CLEANUP; } } + +#define DGG_WARNING(A, REST...) {\ + if(A) {\ + fprintf(stdout, ##REST); \ + __DGG_PRINT_LOC__(stdout); \ + }} + +#define DGG_TEST(A,B,REST...) {\ + if(A) DGG_THROW(B,##REST) } + +#define DGG_TEST2(A,B,C,REST) {DGG_TEST(A,B,C,REST) } +#define DGG_TEST3(A,B,C,D,REST) {DGG_TEST(A,B,C,D,REST) } + +#else + +#define DGG_IF_EXIT(A,B,REST) {if(A) {fprintf(stdout, REST);exit(B);}} + +#define DGG_THROW(A,B) return(A) + +#define DGG_CHECKRVAL(A,B) { if(A) return(B); } +#define DGG_CHECKRVAL1(A,B){ if(A) { rval = B; goto CLEANUP; } } + +#define DGG_TEST(A,B,REST) { if(A) return(B);} +#define DGG_TEST2(A,B,REST,C) { DGG_TEST(A,B,REST) } +#define DGG_TEST3(A,B,REST,C,D) { DGG_TEST(A,B,REST) } + +#endif + +/******************** SIMPLE MACROS AND FUNCTIONS *****************************/ + +#define DGG_MIN(a,b) ( (a<b)?a:b ) +#define DGG_MAX(a,b) ( (a>b)?a:b ) +#define KREM(vht,alpha,tau) (DGG_MIN( ceil(vht / alpha), tau ) - 1) +#define LMIN(vht, d, bht) (DGG_MIN( floor(d*bht/bht), d)) +#define ABOV(v) (v - floor(v)) +#define QINT(vht,bht,tau) ( (int)floor( (vht*(tau-1))/bht ) ) +#define V2I(bht,tau,i) ( ((i+1)*bht / tau) ) + +int DGG_is_even(double vht, double bht, int tau, int q); +double frac_part(double value); +int DGG_is_a_multiple_of_b(double a, double b); + + +/* free function for DGG_data_t. Frees internal arrays and data structure */ +int DGG_freeData( DGG_data_t *data ); + +/******************** CONSTRAINT ADTs *****************************************/ +DGG_constraint_t* DGG_newConstraint(int max_arrays); +void DGG_freeConstraint(DGG_constraint_t *c); +DGG_constraint_t *DGG_copyConstraint(DGG_constraint_t *c); +void DGG_scaleConstraint(DGG_constraint_t *c, int t); + +/******************** CONFIGURATION *******************************************/ +void DGG_list_init (DGG_list_t *l); +int DGG_list_addcut (DGG_list_t *l, DGG_constraint_t *cut, int ctype, double alpha); +void DGG_list_delcut (DGG_list_t *l, int i); +void DGG_list_free(DGG_list_t *l); + +/******************* SOLVER SPECIFIC METHODS **********************************/ +DGG_data_t *DGG_getData(const void *solver_ptr); + +/******************* CONSTRAINT MANIPULATION **********************************/ + +/* DGG_transformConstraint: manipulates a constraint in the following way: + +packs everything in output + +1 - variables at their upper bounds are substituted for their +complements. This is done by adjusting the coefficients and +the right hand side (simple substitution). + +2 - variables with non-zero lower bounds are shifted. */ + +int DGG_transformConstraint( DGG_data_t *data, + double **x_out, + double **rc_out, + char **isint_out, + DGG_constraint_t *constraint ); + +/* DGG_unTransformConstraint : + +1 - Undoes step (1) of DGG_transformConstraint +2 - Undoes step (2) of DGG_transformConstraint */ + +int DGG_unTransformConstraint( DGG_data_t *data, + DGG_constraint_t *constraint ); + +/* substitutes each slack variable by the structural variables which + define it. This function, hence, changes the constraint 'cut'. */ + +int DGG_substituteSlacks( const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t *cut ); + +int DGG_nicefyConstraint( const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t *cut); + +/******************* CUT GENERATION *******************************************/ +int DGG_getFormulaConstraint( int row_idx, + const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t* row ); + +int DGG_getTableauConstraint( int index, + const void *solver_ptr, + DGG_data_t *data, + DGG_constraint_t* tabrow, + const int * colIsBasic, + const int * rowIsBasic, + CoinFactorization & factorization, + int mode ); + +DGG_constraint_t* DGG_getSlackExpression(const void *solver_ptr, DGG_data_t* data, int row_index); + + int DGG_generateTabRowCuts( DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr ); + + int DGG_generateFormulationCuts( DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr, + int nrows, + CoinThreadRandom & generator); + + + int DGG_generateFormulationCutsFromBase( DGG_constraint_t *base, + double slack, + DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr, + CoinThreadRandom & generator); + + int DGG_generateCutsFromBase( DGG_constraint_t *base, + DGG_list_t *list, + DGG_data_t *data, + const void *solver_ptr ); + +int DGG_buildMir( char *isint, + DGG_constraint_t *base, + DGG_constraint_t **cut_out ); + +int DGG_build2step( double alpha, + char *isint, + DGG_constraint_t *base, + DGG_constraint_t **cut_out ); + + int DGG_addMirToList ( DGG_constraint_t *base, + char *isint, + double *x, + DGG_list_t *list, + DGG_data_t *data, + DGG_constraint_t *orig_base ); + + int DGG_add2stepToList ( DGG_constraint_t *base, + char *isint, + double *x, + double *rc, + DGG_list_t *list, + DGG_data_t *data, + DGG_constraint_t *orig_base ); + +/******************* CUT INFORMATION ******************************************/ + +double DGG_cutLHS(DGG_constraint_t *c, double *x); +int DGG_isCutDesirable(DGG_constraint_t *c, DGG_data_t *d); + +/******************* TEST / DEBUGGING ROUTINES ********************************/ + +int DGG_isConstraintViolated(DGG_data_t *d, DGG_constraint_t *c); + +int DGG_isBaseTrivial(DGG_data_t *d, DGG_constraint_t* c); +int DGG_is2stepValid(double alpha, double bht); + +int DGG_cutsOffPoint(double *x, DGG_constraint_t *cut); + +//############################################################################# +/** A function that tests the methods in the CglTwomir class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglTwomirUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir); + + +#endif + + diff --git a/thirdparty/linux/include/coin1/CglZeroHalf.hpp b/thirdparty/linux/include/coin1/CglZeroHalf.hpp new file mode 100644 index 0000000..929269a --- /dev/null +++ b/thirdparty/linux/include/coin1/CglZeroHalf.hpp @@ -0,0 +1,133 @@ +// $Id: CglZeroHalf.hpp 1122 2013-04-06 20:39:53Z stefan $ +// Copyright (C) 2010, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +#ifndef CglZeroHalf_H +#define CglZeroHalf_H + +#include <string> + +#include "CglCutGenerator.hpp" +#include "CoinPackedMatrix.hpp" +#include "Cgl012cut.hpp" + +/** Zero Half Cut Generator Class + + This class generates zero half cuts via the following method: + + See - + +G. Andreello, A. Caprara, M. Fischetti, + “Embedding Cuts in a Branch and Cut Framework: a Computational Study + with {0,1/2}-Cuts”, INFORMS Journal on Computing 19(2), 229-238, 2007. + +*/ + +class CglZeroHalf : public CglCutGenerator { + friend void CglZeroHalfUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +public: + + /**@name Generate Cuts */ + //@{ + /** Generate zero half cuts for the model accessed through the solver interface. + Insert generated cuts into the cut set cs. + */ + virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs, + const CglTreeInfo info = CglTreeInfo()); + //@} + + /**@name Sets and Gets */ + //@{ + /// Get flags + inline int getFlags() const + { return flags_;} + /// Set flags + inline void setFlags(int value) + { flags_ = value;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + CglZeroHalf (); + + /// Copy constructor + CglZeroHalf ( + const CglZeroHalf &); + + /// Clone + virtual CglCutGenerator * clone() const; + + /// Assignment operator + CglZeroHalf & + operator=( + const CglZeroHalf& rhs); + + /// Destructor + virtual + ~CglZeroHalf (); + /// Create C++ lines to get to current state + virtual std::string generateCpp( FILE * fp); + /// This can be used to refresh any information + virtual void refreshSolver(OsiSolverInterface * solver); + //@} + +private: + + // Private member methods + + /**@name Private methods */ + //@{ + //@} + + + /**@name Private member data */ + //@{ + /// number of rows in the ILP matrix + int mr_; + /// number of columns in the ILP matrix + int mc_; + /// number of nonzero's in the ILP matrix + int mnz_; + /// starting position of each row in arrays mtind and mtval + int *mtbeg_; + /// number of entries of each row in arrays mtind and mtval + int *mtcnt_; + /// column indices of the nonzero entries of the ILP matrix + int *mtind_; + /// values of the nonzero entries of the ILP matrix + int *mtval_; + /// lower bounds on the variables + int *vlb_; + /// upper bounds on the variables + int *vub_; + /// right hand sides of the constraints + int *mrhs_; + /// senses of the constraints: 'L', 'G' or 'E' + char *msense_; + /// Cgl012Cut object to make thread safe + Cgl012Cut cutInfo_; + /** Flags + 1 bit - global cuts + */ + int flags_; + //@} +}; +/// A simple Dijkstra shortest path - make better later +#ifndef CGL_NEW_SHORT +void cglShortestPath(cgl_graph * graph, int source, int maximumLength); +#else +void cglShortestPath(auxiliary_graph * graph, int source, int maximumLength); +#endif +//############################################################################# +/** A function that tests the methods in the CglZeroHalf class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void CglZeroHalfUnitTest(const OsiSolverInterface * siP, + const std::string mpdDir ); + +#endif diff --git a/thirdparty/linux/include/coin1/ClpCholeskyBase.hpp b/thirdparty/linux/include/coin1/ClpCholeskyBase.hpp new file mode 100644 index 0000000..815af01 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpCholeskyBase.hpp @@ -0,0 +1,294 @@ +/* $Id: ClpCholeskyBase.hpp 1722 2011-04-17 09:58:37Z stefan $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpCholeskyBase_H +#define ClpCholeskyBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +//#define CLP_LONG_CHOLESKY 0 +#ifndef CLP_LONG_CHOLESKY +#define CLP_LONG_CHOLESKY 0 +#endif +/* valid combinations are + CLP_LONG_CHOLESKY 0 and COIN_LONG_WORK 0 + CLP_LONG_CHOLESKY 1 and COIN_LONG_WORK 1 + CLP_LONG_CHOLESKY 2 and COIN_LONG_WORK 1 +*/ +#if COIN_LONG_WORK==0 +#if CLP_LONG_CHOLESKY>0 +#define CHOLESKY_BAD_COMBINATION +#endif +#else +#if CLP_LONG_CHOLESKY==0 +#define CHOLESKY_BAD_COMBINATION +#endif +#endif +#ifdef CHOLESKY_BAD_COMBINATION +# warning("Bad combination of CLP_LONG_CHOLESKY and COIN_BIG_DOUBLE/COIN_LONG_WORK"); +"Bad combination of CLP_LONG_CHOLESKY and COIN_LONG_WORK" +#endif +#if CLP_LONG_CHOLESKY>1 +typedef long double longDouble; +#define CHOL_SMALL_VALUE 1.0e-15 +#elif CLP_LONG_CHOLESKY==1 +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#else +typedef double longDouble; +#define CHOL_SMALL_VALUE 1.0e-11 +#endif +class ClpInterior; +class ClpCholeskyDense; +class ClpMatrixBase; + +/** Base class for Clp Cholesky factorization + Will do better factorization. very crude ordering + + Derived classes may be using more sophisticated methods +*/ + +class ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Orders rows and saves pointer to matrix.and model. + returns non-zero if not enough memory. + You can use preOrder to set up ADAT + If using default symbolic etc then must set sizeFactor_ to + size of input matrix to order (and to symbolic). + Also just permute_ and permuteInverse_ should be created */ + virtual int order(ClpInterior * model); + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /** Uses factorization to solve. - given as if KKT. + region1 is rows+columns, region2 is rows */ + virtual void solveKKT (CoinWorkDouble * region1, CoinWorkDouble * region2, const CoinWorkDouble * diagonal, + CoinWorkDouble diagonalScaleFactor); +private: + /// AMD ordering + int orderAMD(); +public: + //@} + + /**@name Gets */ + //@{ + /// status. Returns status + inline int status() const { + return status_; + } + /// numberRowsDropped. Number of rows gone + inline int numberRowsDropped() const { + return numberRowsDropped_; + } + /// reset numberRowsDropped and rowsDropped. + void resetRowsDropped(); + /// rowsDropped - which rows are gone + inline char * rowsDropped() const { + return rowsDropped_; + } + /// choleskyCondition. + inline double choleskyCondition() const { + return choleskyCondition_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline double goDense() const { + return goDense_; + } + /// goDense i.e. use dense factoriaztion if > this (default 0.7). + inline void setGoDense(double value) { + goDense_ = value; + } + /// rank. Returns rank + inline int rank() const { + return numberRows_ - numberRowsDropped_; + } + /// Return number of rows + inline int numberRows() const { + return numberRows_; + } + /// Return size + inline CoinBigIndex size() const { + return sizeFactor_; + } + /// Return sparseFactor + inline longDouble * sparseFactor() const { + return sparseFactor_; + } + /// Return diagonal + inline longDouble * diagonal() const { + return diagonal_; + } + /// Return workDouble + inline longDouble * workDouble() const { + return workDouble_; + } + /// If KKT on + inline bool kkt() const { + return doKKT_; + } + /// Set KKT + inline void setKKT(bool yesNo) { + doKKT_ = yesNo; + } + /// Set integer parameter + inline void setIntegerParameter(int i, int value) { + integerParameters_[i] = value; + } + /// get integer parameter + inline int getIntegerParameter(int i) { + return integerParameters_[i]; + } + /// Set double parameter + inline void setDoubleParameter(int i, double value) { + doubleParameters_[i] = value; + } + /// get double parameter + inline double getDoubleParameter(int i) { + return doubleParameters_[i]; + } + //@} + + +public: + + /**@name Constructors, destructor + */ + //@{ + /** Constructor which has dense columns activated. + Default is off. */ + ClpCholeskyBase(int denseThreshold = -1); + /** Destructor (has to be public) */ + virtual ~ClpCholeskyBase(); + /// Copy + ClpCholeskyBase(const ClpCholeskyBase&); + /// Assignment + ClpCholeskyBase& operator=(const ClpCholeskyBase&); + //@} + //@{ + ///@name Other + /// Clone + virtual ClpCholeskyBase * clone() const; + + /// Returns type + inline int type() const { + if (doKKT_) return 100; + else return type_; + } +protected: + /// Sets type + inline void setType(int type) { + type_ = type; + } + /// model. + inline void setModel(ClpInterior * model) { + model_ = model; + } + //@} + + /**@name Symbolic, factor and solve */ + //@{ + /** Symbolic1 - works out size without clever stuff. + Uses upper triangular as much easier. + Returns size + */ + int symbolic1(const CoinBigIndex * Astart, const int * Arow); + /** Symbolic2 - Fills in indices + Uses lower triangular so can do cliques etc + */ + void symbolic2(const CoinBigIndex * Astart, const int * Arow); + /** Factorize - filling in rowsDropped and returning number dropped + in integerParam. + */ + void factorizePart2(int * rowsDropped) ; + /** solve - 1 just first half, 2 just second half - 3 both. + If 1 and 2 then diagonal has sqrt of inverse otherwise inverse + */ + void solve(CoinWorkDouble * region, int type); + /// Forms ADAT - returns nonzero if not enough memory + int preOrder(bool lowerTriangular, bool includeDiagonal, bool doKKT); + /// Updates dense part (broken out for profiling) + void updateDense(longDouble * d, /*longDouble * work,*/ int * first); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// type (may be useful) if > 20 do KKT + int type_; + /// Doing full KKT (only used if default symbolic and factorization) + bool doKKT_; + /// Go dense at this fraction + double goDense_; + /// choleskyCondition. + double choleskyCondition_; + /// model. + ClpInterior * model_; + /// numberTrials. Number of trials before rejection + int numberTrials_; + /// numberRows. Number of Rows in factorization + int numberRows_; + /// status. Status of factorization + int status_; + /// rowsDropped + char * rowsDropped_; + /// permute inverse. + int * permuteInverse_; + /// main permute. + int * permute_; + /// numberRowsDropped. Number of rows gone + int numberRowsDropped_; + /// sparseFactor. + longDouble * sparseFactor_; + /// choleskyStart - element starts + CoinBigIndex * choleskyStart_; + /// choleskyRow (can be shorter than sparsefactor) + int * choleskyRow_; + /// Index starts + CoinBigIndex * indexStart_; + /// Diagonal + longDouble * diagonal_; + /// double work array + longDouble * workDouble_; + /// link array + int * link_; + // Integer work array + CoinBigIndex * workInteger_; + // Clique information + int * clique_; + /// sizeFactor. + CoinBigIndex sizeFactor_; + /// Size of index array + CoinBigIndex sizeIndex_; + /// First dense row + int firstDense_; + /// integerParameters + int integerParameters_[64]; + /// doubleParameters; + double doubleParameters_[64]; + /// Row copy of matrix + ClpMatrixBase * rowCopy_; + /// Dense indicators + char * whichDense_; + /// Dense columns (updated) + longDouble * denseColumn_; + /// Dense cholesky + ClpCholeskyDense * dense_; + /// Dense threshold (for taking out of Cholesky) + int denseThreshold_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpCholeskyDense.hpp b/thirdparty/linux/include/coin1/ClpCholeskyDense.hpp new file mode 100644 index 0000000..d8428b6 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpCholeskyDense.hpp @@ -0,0 +1,162 @@ +/* $Id: ClpCholeskyDense.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +/* + Copyright (C) 2003, International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpCholeskyDense_H +#define ClpCholeskyDense_H + +#include "ClpCholeskyBase.hpp" +class ClpMatrixBase; + +class ClpCholeskyDense : public ClpCholeskyBase { + +public: + /**@name Virtual methods that the derived classes provides */ + /**@{*/ + /** Orders rows and saves pointer to matrix.and model. + Returns non-zero if not enough memory */ + virtual int order(ClpInterior * model) ; + /** Does Symbolic factorization given permutation. + This is called immediately after order. If user provides this then + user must provide factorize and solve. Otherwise the default factorization is used + returns non-zero if not enough memory */ + virtual int symbolic(); + /** Factorize - filling in rowsDropped and returning number dropped. + If return code negative then out of memory */ + virtual int factorize(const CoinWorkDouble * diagonal, int * rowsDropped) ; + /** Uses factorization to solve. */ + virtual void solve (CoinWorkDouble * region) ; + /**@}*/ + + /**@name Non virtual methods for ClpCholeskyDense */ + /**@{*/ + /** Reserves space. + If factor not NULL then just uses passed space + Returns non-zero if not enough memory */ + int reserveSpace(const ClpCholeskyBase * factor, int numberRows) ; + /** Returns space needed */ + CoinBigIndex space( int numberRows) const; + /** part 2 of Factorize - filling in rowsDropped */ + void factorizePart2(int * rowsDropped) ; + /** part 2 of Factorize - filling in rowsDropped - blocked */ + void factorizePart3(int * rowsDropped) ; + /** Forward part of solve */ + void solveF1(longDouble * a, int n, CoinWorkDouble * region); + void solveF2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + /** Backward part of solve */ + void solveB1(longDouble * a, int n, CoinWorkDouble * region); + void solveB2(longDouble * a, int n, CoinWorkDouble * region, CoinWorkDouble * region2); + int bNumber(const longDouble * array, int &, int&); + /** A */ + inline longDouble * aMatrix() const { + return sparseFactor_; + } + /** Diagonal */ + inline longDouble * diagonal() const { + return diagonal_; + } + /**@}*/ + + + /**@name Constructors, destructor */ + /**@{*/ + /** Default constructor. */ + ClpCholeskyDense(); + /** Destructor */ + virtual ~ClpCholeskyDense(); + /** Copy */ + ClpCholeskyDense(const ClpCholeskyDense&); + /** Assignment */ + ClpCholeskyDense& operator=(const ClpCholeskyDense&); + /** Clone */ + virtual ClpCholeskyBase * clone() const ; + /**@}*/ + + +private: + /**@name Data members */ + /**@{*/ + /** Just borrowing space */ + bool borrowSpace_; + /**@}*/ +}; + +/* structure for C */ +typedef struct { + longDouble * diagonal_; + longDouble * a; + longDouble * work; + int * rowsDropped; + double doubleParameters_[1]; /* corresponds to 10 */ + int integerParameters_[2]; /* corresponds to 34, nThreads */ + int n; + int numberBlocks; +} ClpCholeskyDenseC; + +extern "C" { + void ClpCholeskySpawn(void *); +} +/**Non leaf recursive factor */ +void +ClpCholeskyCfactor(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, int numberBlocks, + longDouble * diagonal, longDouble * work, int * rowsDropped); + +/**Non leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRec(ClpCholeskyDenseC * thisStruct, + longDouble * aTri, int nThis, + longDouble * aUnder, longDouble * diagonal, + longDouble * work, + int nLeft, int iBlock, int jBlock, + int numberBlocks); +/**Non leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTri(ClpCholeskyDenseC * thisStruct, + longDouble * aUnder, int nTri, int nDo, + int iBlock, int jBlock, longDouble * aTri, + longDouble * diagonal, longDouble * work, + int numberBlocks); +/** Non leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRec(ClpCholeskyDenseC * thisStruct, + longDouble * above, int nUnder, int nUnderK, + int nDo, longDouble * aUnder, longDouble *aOther, + longDouble * work, + int iBlock, int jBlock, + int numberBlocks); +/**Leaf recursive factor */ +void +ClpCholeskyCfactorLeaf(ClpCholeskyDenseC * thisStruct, + longDouble * a, int n, + longDouble * diagonal, longDouble * work, + int * rowsDropped); +/**Leaf recursive triangle rectangle update */ +void +ClpCholeskyCtriRecLeaf(/*ClpCholeskyDenseC * thisStruct,*/ + longDouble * aTri, longDouble * aUnder, + longDouble * diagonal, longDouble * work, + int nUnder); +/**Leaf recursive rectangle triangle update */ +void +ClpCholeskyCrecTriLeaf(/*ClpCholeskyDenseC * thisStruct, */ + longDouble * aUnder, longDouble * aTri, + /*longDouble * diagonal,*/ longDouble * work, int nUnder); +/** Leaf recursive rectangle rectangle update, + nUnder is number of rows in iBlock, + nUnderK is number of rows in kBlock +*/ +void +ClpCholeskyCrecRecLeaf(/*ClpCholeskyDenseC * thisStruct, */ + const longDouble * COIN_RESTRICT above, + const longDouble * COIN_RESTRICT aUnder, + longDouble * COIN_RESTRICT aOther, + const longDouble * COIN_RESTRICT work, + int nUnder); +#endif diff --git a/thirdparty/linux/include/coin1/ClpConfig.h b/thirdparty/linux/include/coin1/ClpConfig.h new file mode 100644 index 0000000..d10a206 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpConfig.h @@ -0,0 +1,17 @@ +/* src/config_clp.h. Generated by configure. */ +/* src/config_clp.h.in. */ + +/* Define to 1, 2, 3, or 4 if Aboca should be build. */ +/* #undef CLP_HAS_ABC */ + +/* Version number of project */ +#define CLP_VERSION "1.16.6" + +/* Major Version number of project */ +#define CLP_VERSION_MAJOR 1 + +/* Minor Version number of project */ +#define CLP_VERSION_MINOR 16 + +/* Release Version number of project */ +#define CLP_VERSION_RELEASE 6 diff --git a/thirdparty/linux/include/coin1/ClpConstraint.hpp b/thirdparty/linux/include/coin1/ClpConstraint.hpp new file mode 100644 index 0000000..be43bb8 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpConstraint.hpp @@ -0,0 +1,125 @@ +/* $Id: ClpConstraint.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraint_H +#define ClpConstraint_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Constraint Abstract Base Class + +Abstract Base Class for describing a constraint or objective function + +*/ +class ClpConstraint { + +public: + + ///@name Stuff + //@{ + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient undefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const = 0; + /// Constraint function value + virtual double functionValue (const ClpSimplex * model, + const double * solution, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale constraint + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const = 0; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const = 0; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraint(); + + /// Copy constructor + ClpConstraint(const ClpConstraint &); + + /// Assignment operator + ClpConstraint & operator=(const ClpConstraint& rhs); + + /// Destructor + virtual ~ClpConstraint (); + + /// Clone + virtual ClpConstraint * clone() const = 0; + + //@} + + ///@name Other + //@{ + /// Returns type, 0 linear, 1 nonlinear + inline int type() { + return type_; + } + /// Row number (-1 is objective) + inline int rowNumber() const { + return rowNumber_; + } + + /// Number of possible coefficients in gradient + virtual int numberCoefficients() const = 0; + + /// Stored constraint function value + inline double functionValue () const { + return functionValue_; + } + + /// Constraint offset + inline double offset () const { + return offset_; + } + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Gradient at last evaluation + mutable double * lastGradient_; + /// Value of non-linear part of constraint + mutable double functionValue_; + /// Value of offset for constraint + mutable double offset_; + /// Type of constraint - linear is 1 + int type_; + /// Row number (-1 is objective) + int rowNumber_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpConstraintLinear.hpp b/thirdparty/linux/include/coin1/ClpConstraintLinear.hpp new file mode 100644 index 0000000..fd0a4da --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpConstraintLinear.hpp @@ -0,0 +1,110 @@ +/* $Id: ClpConstraintLinear.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintLinear_H +#define ClpConstraintLinear_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Linear Constraint Class + +*/ + +class ClpConstraintLinear : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Linear then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintLinear(); + + /// Constructor from constraint + ClpConstraintLinear(int row, int numberCoefficients, int numberColumns, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintLinear(const ClpConstraintLinear & rhs); + + /// Assignment operator + ClpConstraintLinear & operator=(const ClpConstraintLinear& rhs); + + /// Destructor + virtual ~ClpConstraintLinear (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in linear constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients + int numberCoefficients_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpConstraintQuadratic.hpp b/thirdparty/linux/include/coin1/ClpConstraintQuadratic.hpp new file mode 100644 index 0000000..2eff6cc --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpConstraintQuadratic.hpp @@ -0,0 +1,119 @@ +/* $Id: ClpConstraintQuadratic.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpConstraintQuadratic_H +#define ClpConstraintQuadratic_H + +#include "ClpConstraint.hpp" + +//############################################################################# + +/** Quadratic Constraint Class + +*/ + +class ClpConstraintQuadratic : public ClpConstraint { + +public: + + ///@name Stuff + //@{ + + + /** Fills gradient. If Quadratic then solution may be NULL, + also returns true value of function and offset so we can use x not deltaX in constraint + If refresh is false then uses last solution + Uses model for scaling + Returns non-zero if gradient udefined at current solution + */ + virtual int gradient(const ClpSimplex * model, + const double * solution, + double * gradient, + double & functionValue , + double & offset, + bool useScaling = false, + bool refresh = true) const ; + /// Resize constraint + virtual void resize(int newNumberColumns) ; + /// Delete columns in constraint + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale constraint + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonquadratic columns to 1. + Returns number of nonquadratic columns + */ + virtual int markNonlinear(char * which) const ; + /** Given a zeroed array sets possible nonzero coefficients to 1. + Returns number of nonzeros + */ + virtual int markNonzero(char * which) const; + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpConstraintQuadratic(); + + /// Constructor from quadratic + ClpConstraintQuadratic(int row, int numberQuadraticColumns, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + + /** Copy constructor . + */ + ClpConstraintQuadratic(const ClpConstraintQuadratic & rhs); + + /// Assignment operator + ClpConstraintQuadratic & operator=(const ClpConstraintQuadratic& rhs); + + /// Destructor + virtual ~ClpConstraintQuadratic (); + + /// Clone + virtual ClpConstraint * clone() const; + //@} + ///@name Gets and sets + //@{ + /// Number of coefficients + virtual int numberCoefficients() const; + /// Number of columns in constraint + inline int numberColumns() const { + return numberColumns_; + } + /// Column starts + inline CoinBigIndex * start() const { + return start_; + } + /// Columns + inline const int * column() const { + return column_; + } + /// Coefficients + inline const double * coefficient() const { + return coefficient_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Column starts + CoinBigIndex * start_; + /// Column (if -1 then linear coefficient) + int * column_; + /// Coefficients + double * coefficient_; + /// Useful to have number of columns about + int numberColumns_; + /// Number of coefficients in gradient + int numberCoefficients_; + /// Number of quadratic columns + int numberQuadraticColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpDualRowDantzig.hpp b/thirdparty/linux/include/coin1/ClpDualRowDantzig.hpp new file mode 100644 index 0000000..73b42b3 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDualRowDantzig.hpp @@ -0,0 +1,71 @@ +/* $Id: ClpDualRowDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowDantzig_H +#define ClpDualRowDantzig_H + +#include "ClpDualRowPivot.hpp" + +//############################################################################# + +/** Dual Row Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpDualRowDantzig : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowDantzig(); + + /// Copy constructor + ClpDualRowDantzig(const ClpDualRowDantzig &); + + /// Assignment operator + ClpDualRowDantzig & operator=(const ClpDualRowDantzig& rhs); + + /// Destructor + virtual ~ClpDualRowDantzig (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpDualRowPivot.hpp b/thirdparty/linux/include/coin1/ClpDualRowPivot.hpp new file mode 100644 index 0000000..f1f57a6 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDualRowPivot.hpp @@ -0,0 +1,129 @@ +/* $Id: ClpDualRowPivot.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowPivot_H +#define ClpDualRowPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Dual Row Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose row pivot in dual simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. + +*/ + +class ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow() = 0; + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn) = 0; + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + Would be faster if we kept basic regions, but on other hand it + means everything is always in sync + */ + /* FIXME: this was pure virtul (=0). Why? */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective) = 0; + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize to 1 , infeasibilities + 6) scale back + 7) for strong branching - initialize full weights , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// checks accuracy and may re-initialize (may be empty) + virtual void checkAccuracy(); + /// Gets rid of last update (may be empty) + virtual void unrollWeights(); + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const { + return false; + } + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpDualRowPivot(); + + /// Copy constructor + ClpDualRowPivot(const ClpDualRowPivot &); + + /// Assignment operator + ClpDualRowPivot & operator=(const ClpDualRowPivot& rhs); + + /// Destructor + virtual ~ClpDualRowPivot (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + + /// Sets model (normally to NULL) + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of row pivot algorithm + int type_; + //@} +}; +#ifndef CLP_DUAL_COLUMN_MULTIPLIER +//#define CLP_DUAL_COLUMN_MULTIPLIER 0.99999 +#endif +#endif diff --git a/thirdparty/linux/include/coin1/ClpDualRowSteepest.hpp b/thirdparty/linux/include/coin1/ClpDualRowSteepest.hpp new file mode 100644 index 0000000..7e2cc62 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDualRowSteepest.hpp @@ -0,0 +1,153 @@ +/* $Id: ClpDualRowSteepest.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDualRowSteepest_H +#define ClpDualRowSteepest_H + +#include "ClpDualRowPivot.hpp" +class CoinIndexedVector; + + +//############################################################################# + +/** Dual Row Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + +class ClpDualRowSteepest : public ClpDualRowPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /// Returns pivot row, -1 if none + virtual int pivotRow(); + + /** Updates weights and returns pivot alpha. + Also does FT update */ + virtual double updateWeights(CoinIndexedVector * input, + CoinIndexedVector * spare, + CoinIndexedVector * spare2, + CoinIndexedVector * updatedColumn); + + /** Updates primal solution (and maybe list of candidates) + Uses input vector which it deletes + Computes change in objective function + */ + virtual void updatePrimalSolution(CoinIndexedVector * input, + double theta, + double & changeInObjective); + + /** Saves any weights round factorization as pivot rows may change + Save model + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) for strong branching - initialize (uninitialized) , infeasibilities + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Pass in saved weights + void passInSavedWeights(const CoinIndexedVector * saved); + /// Get saved weights + inline CoinIndexedVector * savedWeights() + { return savedWeights_;} + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any row + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is uninitialized, 1 full, 2 is partial uninitialized, + 3 starts as 2 but may switch to 1. + By partial is meant that the weights are updated as normal + but only part of the infeasible basic variables are scanned. + This can be faster on very easy problems. + */ + ClpDualRowSteepest(int mode = 3); + + /// Copy constructor + ClpDualRowSteepest(const ClpDualRowSteepest &); + + /// Assignment operator + ClpDualRowSteepest & operator=(const ClpDualRowSteepest& rhs); + + /// Fill most values + void fill(const ClpDualRowSteepest& rhs); + + /// Destructor + virtual ~ClpDualRowSteepest (); + + /// Clone + virtual ClpDualRowPivot * clone(bool copyData = true) const; + + //@} + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /// Set mode + inline void setMode(int mode) { + mode_ = mode; + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } +//@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** If 0 then we are using uninitialized weights, 1 then full, + if 2 then uninitialized partial, 3 switchable */ + int mode_; + /// Life of weights + Persistence persistence_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible rows) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + CoinIndexedVector * savedWeights_; + /// Dubious weights + int * dubiousWeights_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpDummyMatrix.hpp b/thirdparty/linux/include/coin1/ClpDummyMatrix.hpp new file mode 100644 index 0000000..1b4a2d4 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDummyMatrix.hpp @@ -0,0 +1,183 @@ +/* $Id: ClpDummyMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDummyMatrix_H +#define ClpDummyMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a dummy matrix as derived from ClpMatrixBase. + This is so you can do ClpPdco but may come in useful elsewhere. + It just has dimensions but no data +*/ + + +class ClpDummyMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return numberElements_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const; + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const {} + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + + using ClpMatrixBase::transposeTimes ; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDummyMatrix(); + /// Constructor with data + ClpDummyMatrix(int numberColumns, int numberRows, + int numberElements); + /** Destructor */ + virtual ~ClpDummyMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDummyMatrix(const ClpDummyMatrix&); + /** The copy constructor from an CoinDummyMatrix. */ + ClpDummyMatrix(const CoinPackedMatrix&); + + ClpDummyMatrix& operator=(const ClpDummyMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Number of elements + int numberElements_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpDynamicExampleMatrix.hpp b/thirdparty/linux/include/coin1/ClpDynamicExampleMatrix.hpp new file mode 100644 index 0000000..81fe5ba --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDynamicExampleMatrix.hpp @@ -0,0 +1,186 @@ +/* $Id: ClpDynamicExampleMatrix.hpp 1936 2013-04-09 10:29:27Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicExampleMatrix_H +#define ClpDynamicExampleMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpDynamicMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpDynamicMatrix and knows that + the real matrix is gub. This acts just like ClpDynamicMatrix but generates columns. + This "generates" columns by choosing from stored set. It is maent as a starting point + as to how you could use shortest path to generate columns. + + So it has its own copy of all data needed. It populates ClpDynamicWatrix with enough + to allow for gub keys and active variables. In turn ClpDynamicMatrix populates + a CoinPackedMatrix with active columns and rows. + + As there is one copy here and one in ClpDynamicmatrix these names end in Gen_ + + It is obviously more efficient to just use ClpDynamicMatrix but the ideas is to + show how much code a user would have to write. + + This does not work very well with bounds + +*/ + +class ClpDynamicExampleMatrix : public ClpDynamicMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** If addColumn forces compression then this allows descendant to know what to do. + If >= then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * in, int numberToPack); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicExampleMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#if 0 + /// This constructor just takes over ownership (except for lower, upper) + ClpDynamicExampleMatrix(ClpSimplex * model, int numberSets, + int numberColumns, int * starts, + const double * lower, const double * upper, + int * startColumn, int * row, + double * element, double * cost, + double * columnLower = NULL, double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL, + int numberIds = 0, const int *ids = NULL); +#endif + /** Destructor */ + virtual ~ClpDynamicExampleMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicExampleMatrix(const ClpDynamicExampleMatrix&); + ClpDynamicExampleMatrix& operator=(const ClpDynamicExampleMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Starts of each column + inline CoinBigIndex * startColumnGen() const { + return startColumnGen_; + } + /// rows + inline int * rowGen() const { + return rowGen_; + } + /// elements + inline double * elementGen() const { + return elementGen_; + } + /// costs + inline double * costGen() const { + return costGen_; + } + /// full starts + inline int * fullStartGen() const { + return fullStartGen_; + } + /// ids in next level matrix + inline int * idGen() const { + return idGen_; + } + /// Optional lower bounds on columns + inline double * columnLowerGen() const { + return columnLowerGen_; + } + /// Optional upper bounds on columns + inline double * columnUpperGen() const { + return columnUpperGen_; + } + /// size + inline int numberColumns() const { + return numberColumns_; + } + inline void setDynamicStatusGen(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatusGen_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatusGen(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatusGen_[sequence] & 7); + } + /// Whether flagged + inline bool flaggedGen(int i) const { + return (dynamicStatusGen_[i] & 8) != 0; + } + inline void setFlaggedGen(int i) { + dynamicStatusGen_[i] = static_cast<unsigned char>(dynamicStatusGen_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatusGen_[i] = static_cast<unsigned char>(dynamicStatusGen_[i] & ~8); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// size + int numberColumns_; + /// Starts of each column + CoinBigIndex * startColumnGen_; + /// rows + int * rowGen_; + /// elements + double * elementGen_; + /// costs + double * costGen_; + /// start of each set + int * fullStartGen_; + /// for status and which bound + unsigned char * dynamicStatusGen_; + /** identifier for each variable up one level (startColumn_, etc). This is + of length maximumGubColumns_. For this version it is just sequence number + at this level */ + int * idGen_; + /// Optional lower bounds on columns + double * columnLowerGen_; + /// Optional upper bounds on columns + double * columnUpperGen_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpDynamicMatrix.hpp b/thirdparty/linux/include/coin1/ClpDynamicMatrix.hpp new file mode 100644 index 0000000..da4e144 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpDynamicMatrix.hpp @@ -0,0 +1,381 @@ +/* $Id: ClpDynamicMatrix.hpp 1755 2011-06-28 18:24:31Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpDynamicMatrix_H +#define ClpDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements a dynamic matrix when we have a limit on the number of + "interesting rows". This version inherits from ClpPackedMatrix and knows that + the real matrix is gub. A later version could use shortest path to generate columns. + +*/ + +class ClpDynamicMatrix : public ClpPackedMatrix { + +public: + /// enums for status of various sorts + enum DynamicStatus { + soloKey = 0x00, + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big dynamic or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// Modifies rhs offset + void modifyOffset(int sequence, double amount); + /// Gets key value when none in small + double keyValue(int iSet) const; + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * model); + /** Creates a variable. This is called after partial pricing and will modify matrix. + Will update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /// Returns reduced cost of a variable + virtual double reducedCost( ClpSimplex * model, int sequence) const; + /// Does gub crash + void gubCrash(); + /// Writes out model (without names) + void writeMps(const char * name); + /// Populates initial matrix from dynamic status + void initialProblem(); + /** Adds in a column to gub structure (called from descendant) and returns sequence */ + int addColumn(int numberEntries, const int * row, const double * element, + double cost, double lower, double upper, int iSet, + DynamicStatus status); + /** If addColumn forces compression then this allows descendant to know what to do. + If >=0 then entry stayed in, if -1 then entry went out to lower bound.of zero. + Entries at upper bound (really nonzero) never go out (at present). + */ + virtual void packDown(const int * , int ) {} + /// Gets lower bound (to simplify coding) + inline double columnLower(int sequence) const { + if (columnLower_) return columnLower_[sequence]; + else return 0.0; + } + /// Gets upper bound (to simplify coding) + inline double columnUpper(int sequence) const { + if (columnUpper_) return columnUpper_[sequence]; + else return COIN_DBL_MAX; + } + + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpDynamicMatrix(); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + The contents of original matrix in model will be taken over and original matrix + will be sanitized so can be deleted (to avoid a very small memory leak) + */ + ClpDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const CoinBigIndex * startColumn, const int * row, + const double * element, const double * cost, + const double * columnLower = NULL, const double * columnUpper = NULL, + const unsigned char * status = NULL, + const unsigned char * dynamicStatus = NULL); + + /** Destructor */ + virtual ~ClpDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpDynamicMatrix(const ClpDynamicMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpDynamicMatrix(const CoinPackedMatrix&); + + ClpDynamicMatrix& operator=(const ClpDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// Status of row slacks + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast<ClpSimplex::Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + /// Whether flagged slack + inline bool flaggedSlack(int i) const { + return (status_[i] & 8) != 0; + } + inline void setFlaggedSlack(int i) { + status_[i] = static_cast<unsigned char>(status_[i] | 8); + } + inline void unsetFlaggedSlack(int i) { + status_[i] = static_cast<unsigned char>(status_[i] & ~8); + } + /// Number of sets (dynamic rows) + inline int numberSets() const { + return numberSets_; + } + /// Number of possible gub variables + inline int numberGubEntries() const + { return startSet_[numberSets_];} + /// Sets + inline int * startSets() const + { return startSet_;} + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * columnLower() const { + return columnLower_; + } + /// Optional upper bounds on columns + inline double * columnUpper() const { + return columnUpper_; + } + /// Lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// number of rows in original model + inline int numberStaticRows() const { + return numberStaticRows_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + inline int * keyVariable() const { + return keyVariable_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Saved best dual on gub row in pricing + double savedBestGubDual_; + /// Saved best set in pricing + int savedBestSet_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Key variable of set (only accurate if none in small problem) + mutable int * keyVariable_; + /// Backward pointer to extra row + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Number of sets (dynamic rows) + int numberSets_; + /// Number of active sets + int numberActiveSets_; + /// Saved value of objective offset + double objectiveOffset_; + /// Lower bounds on sets + double * lowerSet_; + /// Upper bounds on sets + double * upperSet_; + /// Status of slack on set + unsigned char * status_; + /// Pointer back to model + ClpSimplex * model_; + /// first free + int firstAvailable_; + /// first free when iteration started + int firstAvailableBefore_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// number of rows in original model + int numberStaticRows_; + /// size of working matrix (max) + int numberElements_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// size + int numberGubColumns_; + /// current maximum number of columns (then compress) + int maximumGubColumns_; + /// current maximum number of elemnts (then compress) + int maximumElements_; + /// Start of each set + int * startSet_; + /// next in chain + int * next_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * columnLower_; + /// Optional upper bounds on columns + double * columnUpper_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpEventHandler.hpp b/thirdparty/linux/include/coin1/ClpEventHandler.hpp new file mode 100644 index 0000000..0a49c83 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpEventHandler.hpp @@ -0,0 +1,186 @@ +/* $Id: ClpEventHandler.hpp 1825 2011-11-20 16:02:57Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpEventHandler_H +#define ClpEventHandler_H + +#include "ClpSimplex.hpp" +/** Base class for Clp event handling + +This is just here to allow for event handling. By event I mean a Clp event +e.g. end of values pass. + +One use would be to let a user handle a system event e.g. Control-C. This could be done +by deriving a class MyEventHandler which knows about such events. If one occurs +MyEventHandler::event() could clear event status and return 3 (stopped). + +Clp would then return to user code. + +As it is called every iteration this should be fine grained enough. + +User can derive and construct from CbcModel - not pretty + +*/ + +class ClpEventHandler { + +public: + /** enums for what sort of event. + + These will also be returned in ClpModel::secondaryStatus() as int + */ + enum Event { + endOfIteration = 100, // used to set secondary status + endOfFactorization, // after gutsOfSolution etc + endOfValuesPass, + node, // for Cbc + treeStatus, // for Cbc + solution, // for Cbc + theta, // hit in parametrics + pivotRow, // used to choose pivot row + presolveStart, // ClpSolve presolve start + presolveSize, // sees if ClpSolve presolve too big or too small + presolveInfeasible, // ClpSolve presolve infeasible + presolveBeforeSolve, // ClpSolve presolve before solve + presolveAfterFirstSolve, // ClpSolve presolve after solve + presolveAfterSolve, // ClpSolve presolve after solve + presolveEnd, // ClpSolve presolve end + goodFactorization, // before gutsOfSolution + complicatedPivotIn, // in modifyCoefficients + noCandidateInPrimal, // tentative end + looksEndInPrimal, // About to declare victory (or defeat) + endInPrimal, // Victory (or defeat) + beforeStatusOfProblemInPrimal, + startOfStatusOfProblemInPrimal, + complicatedPivotOut, // in modifyCoefficients + noCandidateInDual, // tentative end + looksEndInDual, // About to declare victory (or defeat) + endInDual, // Victory (or defeat) + beforeStatusOfProblemInDual, + startOfStatusOfProblemInDual, + startOfIterationInDual, + updateDualsInDual, + endOfCreateRim, + slightlyInfeasible, + modifyMatrixInMiniPresolve, + moreMiniPresolve, + modifyMatrixInMiniPostsolve, + noTheta // At end (because no pivot) + }; + /**@name Virtual method that the derived classes should provide. + The base class instance does nothing and as event() is only useful method + it would not be very useful NOT providing one! + */ + //@{ + /** This can do whatever it likes. If return code -1 then carries on + if 0 sets ClpModel::status() to 5 (stopped by event) and will return to user. + At present if <-1 carries on and if >0 acts as if 0 - this may change. + For ClpSolve 2 -> too big return status of -2 and -> too small 3 + */ + virtual int event(Event whichEvent); + /** This can do whatever it likes. Return code -1 means no action. + This passes in something + */ + virtual int eventWithInfo(Event whichEvent, void * info) ; + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpEventHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpEventHandler(); + // Copy + ClpEventHandler(const ClpEventHandler&); + // Assignment + ClpEventHandler& operator=(const ClpEventHandler&); + /// Clone + virtual ClpEventHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +/** Base class for Clp disaster handling + +This is here to allow for disaster handling. By disaster I mean that Clp +would otherwise give up + +*/ + +class ClpDisasterHandler { + +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex() = 0; + /// Checks if disaster + virtual bool check() const = 0; + /// saves information for next attempt + virtual void saveInfo() = 0; + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + ClpDisasterHandler(ClpSimplex * model = NULL); + /** Destructor */ + virtual ~ClpDisasterHandler(); + // Copy + ClpDisasterHandler(const ClpDisasterHandler&); + // Assignment + ClpDisasterHandler& operator=(const ClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const = 0; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setSimplex(ClpSimplex * model); + /// Get model + inline ClpSimplex * simplex() const { + return model_; + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to simplex + ClpSimplex * model_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/ClpFactorization.hpp b/thirdparty/linux/include/coin1/ClpFactorization.hpp new file mode 100644 index 0000000..dda8ff7 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpFactorization.hpp @@ -0,0 +1,432 @@ +/* $Id: ClpFactorization.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpFactorization_H +#define ClpFactorization_H + + +#include "CoinPragma.hpp" + +#include "CoinFactorization.hpp" +class ClpMatrixBase; +class ClpSimplex; +class ClpNetworkBasis; +class CoinOtherFactorization; +#ifndef CLP_MULTIPLE_FACTORIZATIONS +#define CLP_MULTIPLE_FACTORIZATIONS 4 +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS +#include "CoinDenseFactorization.hpp" +#include "ClpSimplex.hpp" +#endif +#ifndef COIN_FAST_CODE +#define COIN_FAST_CODE +#endif +#ifndef CLP_FACTORIZATION_NEW_TIMING +#define CLP_FACTORIZATION_NEW_TIMING 1 +#endif + +/** This just implements CoinFactorization when an ClpMatrixBase object + is passed. If a network then has a dummy CoinFactorization and + a genuine ClpNetworkBasis object +*/ +class ClpFactorization +#ifndef CLP_MULTIPLE_FACTORIZATIONS + : public CoinFactorization +#endif +{ + + //friend class CoinFactorization; + +public: + /**@name factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + if increasingRows_ >1. + Allows scaling + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize (ClpSimplex * model, int solveType, bool valuesPass); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpFactorization(); + /** Destructor */ + ~ClpFactorization(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor from an CoinFactorization. */ + ClpFactorization(const CoinFactorization&); + /** The copy constructor. */ + ClpFactorization(const ClpFactorization&, int denseIfSmaller = 0); +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /** The copy constructor from an CoinOtherFactorization. */ + ClpFactorization(const CoinOtherFactorization&); +#endif + ClpFactorization& operator=(const ClpFactorization&); + //@} + + /* **** below here is so can use networkish basis */ + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( const ClpSimplex * model, + CoinIndexedVector * regionSparse, + CoinIndexedVector * tableauColumn, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying = false, + double acceptablePivot = 1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room + region1 starts as zero and is zero at end */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** Updates one column (FTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3 = false) ; + /// For debug (no statistics update) + int updateColumnForDebug ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute = false) const; + /** Updates one column (BTRAN) from region2 + region1 starts as zero and is zero at end */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /**@name Lifted from CoinFactorization */ + //@{ + /// Total number of elements in factorization + inline int numberElements ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElements(); + else return coinFactorizationB_->numberElements() ; + } + /// Returns address of permute region + inline int *permute ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->permute(); + else return coinFactorizationB_->permute() ; + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotColumn(); + else return coinFactorizationB_->permute() ; + } + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->maximumPivots(); + else return coinFactorizationB_->maximumPivots() ; + } + /// Set maximum number of pivots between factorizations + inline void maximumPivots ( int value) { + if (coinFactorizationA_) coinFactorizationA_->maximumPivots(value); + else coinFactorizationB_->maximumPivots(value); + } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivots(); + else return coinFactorizationB_->pivots() ; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->areaFactor(); + else return 0.0 ; + } + /// Set whether larger areas needed + inline void areaFactor ( double value) { + if (coinFactorizationA_) coinFactorizationA_->areaFactor(value); + } + /// Zero tolerance + inline double zeroTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->zeroTolerance(); + else return coinFactorizationB_->zeroTolerance() ; + } + /// Set zero tolerance + inline void zeroTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->zeroTolerance(value); + else coinFactorizationB_->zeroTolerance(value); + } + /// Set tolerances to safer of existing and given + void saferTolerances ( double zeroTolerance, double pivotTolerance); + /** get sparse threshold */ + inline int sparseThreshold ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->sparseThreshold(); + else return 0 ; + } + /** Set sparse threshold */ + inline void sparseThreshold ( int value) { + if (coinFactorizationA_) coinFactorizationA_->sparseThreshold(value); + } + /// Returns status + inline int status ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->status(); + else return coinFactorizationB_->status() ; + } + /// Sets status + inline void setStatus ( int value) { + if (coinFactorizationA_) coinFactorizationA_->setStatus(value); + else coinFactorizationB_->setStatus(value) ; + } + /// Returns number of dense rows + inline int numberDense() const { + if (coinFactorizationA_) return coinFactorizationA_->numberDense(); + else return 0 ; + } +#if 1 + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsU(); + else return -1 ; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsL(); + else return -1 ; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberElementsR(); + else return 0 ; + } +#endif + bool timeToRefactorize() const; +#if CLP_FACTORIZATION_NEW_TIMING>1 + void statsRefactor(char when) const; +#endif + /// Level of detail of messages + inline int messageLevel ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->messageLevel(); + else return 1 ; + } + /// Set level of detail of messages + inline void messageLevel ( int value) { + if (coinFactorizationA_) coinFactorizationA_->messageLevel(value); + } + /// Get rid of all memory + inline void clearArrays() { + if (coinFactorizationA_) + coinFactorizationA_->clearArrays(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Number of Rows after factorization + inline int numberRows ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->numberRows(); + else return coinFactorizationB_->numberRows() ; + } + /// Gets dense threshold + inline int denseThreshold() const { + if (coinFactorizationA_) return coinFactorizationA_->denseThreshold(); + else return 0 ; + } + /// Sets dense threshold + inline void setDenseThreshold(int value) { + if (coinFactorizationA_) coinFactorizationA_->setDenseThreshold(value); + } + /// Pivot tolerance + inline double pivotTolerance ( ) const { + if (coinFactorizationA_) return coinFactorizationA_->pivotTolerance(); + else if (coinFactorizationB_) return coinFactorizationB_->pivotTolerance(); + return 1.0e-8 ; + } + /// Set pivot tolerance + inline void pivotTolerance ( double value) { + if (coinFactorizationA_) coinFactorizationA_->pivotTolerance(value); + else if (coinFactorizationB_) coinFactorizationB_->pivotTolerance(value); + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) { + if (coinFactorizationA_) coinFactorizationA_->relaxAccuracyCheck(value); + } + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const { + if (coinFactorizationA_) return coinFactorizationA_->persistenceFlag(); + else return 0 ; + } + inline void setPersistenceFlag(int value) { + if (coinFactorizationA_) coinFactorizationA_->setPersistenceFlag(value); + } + /// Delete all stuff (leaves as after CoinFactorization()) + inline void almostDestructor() { + if (coinFactorizationA_) + coinFactorizationA_->almostDestructor(); + else if (coinFactorizationB_) + coinFactorizationB_->clearArrays(); + } + /// Returns areaFactor but adjusted for dense + inline double adjustedAreaFactor() const { + if (coinFactorizationA_) return coinFactorizationA_->adjustedAreaFactor(); + else return 0.0 ; + } + inline void setBiasLU(int value) { + if (coinFactorizationA_) coinFactorizationA_->setBiasLU(value); + } + /// true if Forrest Tomlin update, false if PFI + inline void setForrestTomlin(bool value) { + if (coinFactorizationA_) coinFactorizationA_->setForrestTomlin(value); + } + /// Sets default values + inline void setDefaultValues() { + if (coinFactorizationA_) { + // row activities have negative sign +#ifndef COIN_FAST_CODE + coinFactorizationA_->slackValue(-1.0); +#endif + coinFactorizationA_->zeroTolerance(1.0e-13); + } + } + /// If nonzero force use of 1,dense 2,small 3,osl + void forceOtherFactorization(int which); + /// Get switch to osl if number rows <= this + inline int goOslThreshold() const { + return goOslThreshold_; + } + /// Set switch to osl if number rows <= this + inline void setGoOslThreshold(int value) { + goOslThreshold_ = value; + } + /// Get switch to dense if number rows <= this + inline int goDenseThreshold() const { + return goDenseThreshold_; + } + /// Set switch to dense if number rows <= this + inline void setGoDenseThreshold(int value) { + goDenseThreshold_ = value; + } + /// Get switch to small if number rows <= this + inline int goSmallThreshold() const { + return goSmallThreshold_; + } + /// Set switch to small if number rows <= this + inline void setGoSmallThreshold(int value) { + goSmallThreshold_ = value; + } + /// Go over to dense or small code if small enough + void goDenseOrSmall(int numberRows) ; + /// Sets factorization + void setFactorization(ClpFactorization & factorization); + /// Return 1 if dense code + inline int isDenseOrSmall() const { + return coinFactorizationB_ ? 1 : 0; + } +#else + inline bool timeToRefactorize() const { + return (pivots() * 3 > maximumPivots() * 2 && + numberElementsR() * 3 > (numberElementsL() + numberElementsU()) * 2 + 1000 && + !numberDense()); + } + /// Sets default values + inline void setDefaultValues() { + // row activities have negative sign +#ifndef COIN_FAST_CODE + slackValue(-1.0); +#endif + zeroTolerance(1.0e-13); + } + /// Go over to dense code + inline void goDense() {} +#endif + //@} + + /**@name other stuff */ + //@{ + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /// Cleans up i.e. gets rid of network basis + void cleanUp(); + /// Says whether to redo pivot order + bool needToReorder() const; +#ifndef SLIM_CLP + /// Says if a network basis + inline bool networkBasis() const { + return (networkBasis_ != NULL); + } +#else + /// Says if a network basis + inline bool networkBasis() const { + return false; + } +#endif + /// Fills weighted row list + void getWeights(int * weights) const; + //@} + +////////////////// data ////////////////// +private: + + /**@name data */ + //@{ + /// Pointer to network basis +#ifndef SLIM_CLP + ClpNetworkBasis * networkBasis_; +#endif +#ifdef CLP_MULTIPLE_FACTORIZATIONS + /// Pointer to CoinFactorization + CoinFactorization * coinFactorizationA_; + /// Pointer to CoinOtherFactorization + CoinOtherFactorization * coinFactorizationB_; +#ifdef CLP_REUSE_ETAS + /// Pointer to model + ClpSimplex * model_; +#endif + /// If nonzero force use of 1,dense 2,small 3,osl + int forceB_; + /// Switch to osl if number rows <= this + int goOslThreshold_; + /// Switch to small if number rows <= this + int goSmallThreshold_; + /// Switch to dense if number rows <= this + int goDenseThreshold_; +#endif +#ifdef CLP_FACTORIZATION_NEW_TIMING + /// For guessing when to re-factorize + mutable double shortestAverage_; + mutable double totalInR_; + mutable double totalInIncreasingU_; + mutable int endLengthU_; + mutable int lastNumberPivots_; + mutable int effectiveStartNumberU_; +#endif + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpGubDynamicMatrix.hpp b/thirdparty/linux/include/coin1/ClpGubDynamicMatrix.hpp new file mode 100644 index 0000000..2d13e6d --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpGubDynamicMatrix.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpGubDynamicMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubDynamicMatrix_H +#define ClpGubDynamicMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpGubMatrix.hpp" +/** This implements Gub rows plus a ClpPackedMatrix. + This a dynamic version which stores the gub part and dynamically creates matrix. + All bounds are assumed to be zero and infinity + + This is just a simple example for real column generation +*/ + +class ClpGubDynamicMatrix : public ClpGubMatrix { + +public: + /**@name Main functions provided */ + //@{ + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Add a new variable to a set + void insertNonBasic(int sequence, int iSet); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + + using ClpPackedMatrix::times ; + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /** Just for debug + Returns sum and number of primal infeasibilities. Recomputes keys + */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const; + /// Cleans data after setWarmStart + void cleanData(ClpSimplex * model); + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubDynamicMatrix(); + /** Destructor */ + virtual ~ClpGubDynamicMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubDynamicMatrix(const ClpGubDynamicMatrix&); + /** This is the real constructor. + It assumes factorization frequency will not be changed. + This resizes model !!!! + */ + ClpGubDynamicMatrix(ClpSimplex * model, int numberSets, + int numberColumns, const int * starts, + const double * lower, const double * upper, + const int * startColumn, const int * row, + const double * element, const double * cost, + const double * lowerColumn = NULL, const double * upperColumn = NULL, + const unsigned char * status = NULL); + + ClpGubDynamicMatrix& operator=(const ClpGubDynamicMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + //@} + /**@name gets and sets */ + //@{ + /// enums for status of various sorts + enum DynamicStatus { + inSmall = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03 + }; + /// Whether flagged + inline bool flagged(int i) const { + return (dynamicStatus_[i] & 8) != 0; + } + inline void setFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] | 8); + } + inline void unsetFlagged(int i) { + dynamicStatus_[i] = static_cast<unsigned char>(dynamicStatus_[i] & ~8); + } + inline void setDynamicStatus(int sequence, DynamicStatus status) { + unsigned char & st_byte = dynamicStatus_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + inline DynamicStatus getDynamicStatus(int sequence) const { + return static_cast<DynamicStatus> (dynamicStatus_[sequence] & 7); + } + /// Saved value of objective offset + inline double objectiveOffset() const { + return objectiveOffset_; + } + /// Starts of each column + inline CoinBigIndex * startColumn() const { + return startColumn_; + } + /// rows + inline int * row() const { + return row_; + } + /// elements + inline double * element() const { + return element_; + } + /// costs + inline double * cost() const { + return cost_; + } + /// full starts + inline int * fullStart() const { + return fullStart_; + } + /// ids of active columns (just index here) + inline int * id() const { + return id_; + } + /// Optional lower bounds on columns + inline double * lowerColumn() const { + return lowerColumn_; + } + /// Optional upper bounds on columns + inline double * upperColumn() const { + return upperColumn_; + } + /// Optional true lower bounds on sets + inline double * lowerSet() const { + return lowerSet_; + } + /// Optional true upper bounds on sets + inline double * upperSet() const { + return upperSet_; + } + /// size + inline int numberGubColumns() const { + return numberGubColumns_; + } + /// first free + inline int firstAvailable() const { + return firstAvailable_; + } + /// set first free + inline void setFirstAvailable(int value) { + firstAvailable_ = value; + } + /// first dynamic + inline int firstDynamic() const { + return firstDynamic_; + } + /// number of columns in dynamic model + inline int lastDynamic() const { + return lastDynamic_; + } + /// size of working matrix (max) + inline int numberElements() const { + return numberElements_; + } + /// Status region for gub slacks + inline unsigned char * gubRowStatus() const { + return status_; + } + /// Status region for gub variables + inline unsigned char * dynamicStatus() const { + return dynamicStatus_; + } + /// Returns which set a variable is in + int whichSet (int sequence) const; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Saved value of objective offset + double objectiveOffset_; + /// Starts of each column + CoinBigIndex * startColumn_; + /// rows + int * row_; + /// elements + double * element_; + /// costs + double * cost_; + /// full starts + int * fullStart_; + /// ids of active columns (just index here) + int * id_; + /// for status and which bound + unsigned char * dynamicStatus_; + /// Optional lower bounds on columns + double * lowerColumn_; + /// Optional upper bounds on columns + double * upperColumn_; + /// Optional true lower bounds on sets + double * lowerSet_; + /// Optional true upper bounds on sets + double * upperSet_; + /// size + int numberGubColumns_; + /// first free + int firstAvailable_; + /// saved first free + int savedFirstAvailable_; + /// first dynamic + int firstDynamic_; + /// number of columns in dynamic model + int lastDynamic_; + /// size of working matrix (max) + int numberElements_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpGubMatrix.hpp b/thirdparty/linux/include/coin1/ClpGubMatrix.hpp new file mode 100644 index 0000000..26c3f62 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpGubMatrix.hpp @@ -0,0 +1,358 @@ +/* $Id: ClpGubMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpGubMatrix_H +#define ClpGubMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpPackedMatrix.hpp" +class ClpSimplex; +/** This implements Gub rows plus a ClpPackedMatrix. + + There will be a version using ClpPlusMinusOne matrix but + there is no point doing one with ClpNetworkMatrix (although + an embedded network is attractive). + +*/ + +class ClpGubMatrix : public ClpPackedMatrix { + +public: + /**@name Main functions provided */ + //@{ + /** Returns a new matrix in reverse order without gaps (GUB wants NULL) */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + //@} + + /**@name Matrix times vector methods */ + //@{ + + using ClpPackedMatrix::transposeTimes ; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added if mode 0. + If mode 1 deletes extra entries + + This active in Gub + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /// Sets up an effective RHS and does gub crash if needed + virtual void useEffectiveRhs(ClpSimplex * model, bool cheapest = true); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /** This is local to Gub to allow synchronization: + mode=0 when status of basis is good + mode=1 when variable is flagged + mode=2 when all variables unflagged (returns number flagged) + mode=3 just reset costs (primal) + mode=4 correct number of dual infeasibilities + mode=5 return 4 if time to re-factorize + mode=6 - return 1 if there may be changing bounds on variable (column generation) + mode=7 - do extra restores for column generation + mode=8 - make sure set is clean + mode=9 - adjust lower, upper on set by incoming + */ + virtual int synchronize(ClpSimplex * model, int mode); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpGubMatrix(); + /** Destructor */ + virtual ~ClpGubMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpGubMatrix(const ClpGubMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpGubMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpGubMatrix (const ClpGubMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpGubMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpGubMatrix(CoinPackedMatrix * matrix); + + /** This takes over ownership (for space reasons) and is the + real constructor*/ + ClpGubMatrix(ClpPackedMatrix * matrix, int numberSets, + const int * start, const int * end, + const double * lower, const double * upper, + const unsigned char * status = NULL); + + ClpGubMatrix& operator=(const ClpGubMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /** redoes next_ for a set. */ + void redoSet(ClpSimplex * model, int newKey, int oldKey, int iSet); + //@} + /**@name gets and sets */ + //@{ + /// Status + inline ClpSimplex::Status getStatus(int sequence) const { + return static_cast<ClpSimplex::Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, ClpSimplex::Status status) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | status); + } + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64); + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say key is above ub + inline void setAbove( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = static_cast<unsigned char>(iStat | 16); + } + /// To say key is feasible + inline void setFeasible( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = static_cast<unsigned char>(iStat | 8); + } + /// To say key is below lb + inline void setBelow( int sequence) { + unsigned char iStat = status_[sequence]; + iStat = static_cast<unsigned char>(iStat & ~24); + status_[sequence] = iStat; + } + inline double weight( int sequence) const { + int iStat = status_[sequence] & 31; + iStat = iStat >> 3; + return static_cast<double> (iStat - 1); + } + /// Starts + inline int * start() const { + return start_; + } + /// End + inline int * end() const { + return end_; + } + /// Lower bounds on sets + inline double * lower() const { + return lower_; + } + /// Upper bounds on sets + inline double * upper() const { + return upper_; + } + /// Key variable of set + inline int * keyVariable() const { + return keyVariable_; + } + /// Backward pointer to set number + inline int * backward() const { + return backward_; + } + /// Number of sets (gub rows) + inline int numberSets() const { + return numberSets_; + } + /// Switches off dj checking each factorization (for BIG models) + void switchOffCheck(); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Infeasibility weight when last full pass done + double infeasibilityWeight_; + /// Starts + int * start_; + /// End + int * end_; + /// Lower bounds on sets + double * lower_; + /// Upper bounds on sets + double * upper_; + /// Status of slacks + mutable unsigned char * status_; + /// Saved status of slacks + unsigned char * saveStatus_; + /// Saved key variables + int * savedKeyVariable_; + /// Backward pointer to set number + int * backward_; + /// Backward pointer to pivot row !!! + int * backToPivotRow_; + /// Change in costs for keys + double * changeCost_; + /// Key variable of set + mutable int * keyVariable_; + /** Next basic variable in set - starts at key and end with -(set+1). + Now changes to -(nonbasic+1). + next_ has extra space for 2* longest set */ + mutable int * next_; + /// Backward pointer to index in CoinIndexedVector + int * toIndex_; + // Reverse pointer from index to set + int * fromIndex_; + /// Pointer back to model + ClpSimplex * model_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /** If pricing will declare victory (i.e. no check every factorization). + -1 - always check + 0 - don't check + 1 - in don't check mode but looks optimal + */ + int noCheck_; + /// Number of sets (gub rows) + int numberSets_; + /// Number in vector without gub extension + int saveNumber_; + /// Pivot row of possible next key + int possiblePivotKey_; + /// Gub slack in (set number or -1) + int gubSlackIn_; + /// First gub variables (same as start_[0] at present) + int firstGub_; + /// last gub variable (same as end_[numberSets_-1] at present) + int lastGub_; + /** type of gub - 0 not contiguous, 1 contiguous + add 8 bit to say no ubs on individual variables */ + int gubType_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpInterior.hpp b/thirdparty/linux/include/coin1/ClpInterior.hpp new file mode 100644 index 0000000..7f87e1e --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpInterior.hpp @@ -0,0 +1,570 @@ +/* $Id: ClpInterior.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Tomlin (pdco) + John Forrest (standard predictor-corrector) + + Note JJF has added arrays - this takes more memory but makes + flow easier to understand and hopefully easier to extend + + */ +#ifndef ClpInterior_H +#define ClpInterior_H + +#include <iostream> +#include <cfloat> +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "CoinDenseVector.hpp" +class ClpLsqr; +class ClpPdcoBase; +/// ******** DATA to be moved into protected section of ClpInterior +typedef struct { + double atolmin; + double r3norm; + double LSdamp; + double* deltay; +} Info; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double atolold; + double atolnew; + double r3ratio; + int istop; + int itncg; +} Outfo; +/// ******** DATA to be moved into protected section of ClpInterior + +typedef struct { + double gamma; + double delta; + int MaxIter; + double FeaTol; + double OptTol; + double StepTol; + double x0min; + double z0min; + double mu0; + int LSmethod; // 1=Cholesky 2=QR 3=LSQR + int LSproblem; // See below + int LSQRMaxIter; + double LSQRatol1; // Initial atol + double LSQRatol2; // Smallest atol (unless atol1 is smaller) + double LSQRconlim; + int wait; +} Options; +class Lsqr; +class ClpCholeskyBase; +// ***** END +/** This solves LPs using interior point methods + + It inherits from ClpModel and all its arrays are created at + algorithm time. + +*/ + +class ClpInterior : public ClpModel { + friend void ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpInterior ( ); + + /// Copy constructor. + ClpInterior(const ClpInterior &); + /// Copy constructor from model. + ClpInterior(const ClpModel &); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpInterior (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Assignment operator. This copies the data + ClpInterior & operator=(const ClpInterior & rhs); + /// Destructor + ~ClpInterior ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one. */ + void borrowModel(ClpModel & otherModel); + /** Return model - updates any scalars */ + void returnModel(ClpModel & otherModel); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Pdco algorithm - see ClpPdco.hpp for method */ + int pdco(); + // ** Temporary version + int pdco( ClpPdcoBase * stuff, Options &options, Info &info, Outfo &outfo); + /// Primal-Dual Predictor-Corrector barrier + int primalDual(); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (sumPrimalInfeasibilities_ <= 1.0e-5); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (sumDualInfeasibilities_ <= 1.0e-5); + } + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Sum of dual infeasibilities + inline CoinWorkDouble sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + /// Sum of primal infeasibilities + inline CoinWorkDouble sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + /// dualObjective. + inline CoinWorkDouble dualObjective() const { + return dualObjective_; + } + /// primalObjective. + inline CoinWorkDouble primalObjective() const { + return primalObjective_; + } + /// diagonalNorm + inline CoinWorkDouble diagonalNorm() const { + return diagonalNorm_; + } + /// linearPerturbation + inline CoinWorkDouble linearPerturbation() const { + return linearPerturbation_; + } + inline void setLinearPerturbation(CoinWorkDouble value) { + linearPerturbation_ = value; + } + /// projectionTolerance + inline CoinWorkDouble projectionTolerance() const { + return projectionTolerance_; + } + inline void setProjectionTolerance(CoinWorkDouble value) { + projectionTolerance_ = value; + } + /// diagonalPerturbation + inline CoinWorkDouble diagonalPerturbation() const { + return diagonalPerturbation_; + } + inline void setDiagonalPerturbation(CoinWorkDouble value) { + diagonalPerturbation_ = value; + } + /// gamma + inline CoinWorkDouble gamma() const { + return gamma_; + } + inline void setGamma(CoinWorkDouble value) { + gamma_ = value; + } + /// delta + inline CoinWorkDouble delta() const { + return delta_; + } + inline void setDelta(CoinWorkDouble value) { + delta_ = value; + } + /// ComplementarityGap + inline CoinWorkDouble complementarityGap() const { + return complementarityGap_; + } + //@} + + /**@name most useful gets and sets */ + //@{ + /// Largest error on Ax-b + inline CoinWorkDouble largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline CoinWorkDouble largestDualError() const { + return largestDualError_; + } + /// Maximum iterations + inline int maximumBarrierIterations() const { + return maximumBarrierIterations_; + } + inline void setMaximumBarrierIterations(int value) { + maximumBarrierIterations_ = value; + } + /// Set cholesky (and delete present one) + void setCholesky(ClpCholeskyBase * cholesky); + /// Return number fixed to see if worth presolving + int numberFixed() const; + /** fix variables interior says should be. If reallyFix false then just + set values to exact bounds */ + void fixFixed(bool reallyFix = true); + /// Primal erturbation vector + inline CoinWorkDouble * primalR() const { + return primalR_; + } + /// Dual erturbation vector + inline CoinWorkDouble * dualR() const { + return dualR_; + } + //@} + +protected: + /**@name protected methods */ + //@{ + /// Does most of deletion + void gutsOfDelete(); + /// Does most of copying + void gutsOfCopy(const ClpInterior & rhs); + /// Returns true if data looks okay, false if not + bool createWorkingData(); + void deleteWorkingData(); + /// Sanity check on input rim data + bool sanityCheck(); + /// This does housekeeping + int housekeeping(); + //@} +public: + /**@name public methods */ + //@{ + /// Raw objective value (so always minimize) + inline CoinWorkDouble rawObjectiveValue() const { + return objectiveValue_; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Checks solution + void checkSolution(); + /** Modifies djs to allow for quadratic. + returns quadratic offset */ + CoinWorkDouble quadraticDjs(CoinWorkDouble * djRegion, const CoinWorkDouble * solution, + CoinWorkDouble scaleFactor); + + /// To say a variable is fixed + inline void setFixed( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 1) ; + } + inline void clearFixed( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~1) ; + } + inline bool fixed(int sequence) const { + return ((status_[sequence] & 1) != 0); + } + + /// To flag a variable + inline void setFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 2) ; + } + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~2) ; + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 2) != 0); + } + + /// To say a variable is fixed OR free + inline void setFixedOrFree( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 4) ; + } + inline void clearFixedOrFree( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~4) ; + } + inline bool fixedOrFree(int sequence) const { + return ((status_[sequence] & 4) != 0); + } + + /// To say a variable has lower bound + inline void setLowerBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 8) ; + } + inline void clearLowerBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~8) ; + } + inline bool lowerBound(int sequence) const { + return ((status_[sequence] & 8) != 0); + } + + /// To say a variable has upper bound + inline void setUpperBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 16) ; + } + inline void clearUpperBound( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~16) ; + } + inline bool upperBound(int sequence) const { + return ((status_[sequence] & 16) != 0); + } + + /// To say a variable has fake lower bound + inline void setFakeLower( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 32) ; + } + inline void clearFakeLower( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~32) ; + } + inline bool fakeLower(int sequence) const { + return ((status_[sequence] & 32) != 0); + } + + /// To say a variable has fake upper bound + inline void setFakeUpper( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 64) ; + } + inline void clearFakeUpper( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64) ; + } + inline bool fakeUpper(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /// Largest error on Ax-b + CoinWorkDouble largestPrimalError_; + /// Largest error on basic duals + CoinWorkDouble largestDualError_; + /// Sum of dual infeasibilities + CoinWorkDouble sumDualInfeasibilities_; + /// Sum of primal infeasibilities + CoinWorkDouble sumPrimalInfeasibilities_; + /// Worst complementarity + CoinWorkDouble worstComplementarity_; + /// +public: + CoinWorkDouble xsize_; + CoinWorkDouble zsize_; +protected: + /// Working copy of lower bounds (Owner of arrays below) + CoinWorkDouble * lower_; + /// Row lower bounds - working copy + CoinWorkDouble * rowLowerWork_; + /// Column lower bounds - working copy + CoinWorkDouble * columnLowerWork_; + /// Working copy of upper bounds (Owner of arrays below) + CoinWorkDouble * upper_; + /// Row upper bounds - working copy + CoinWorkDouble * rowUpperWork_; + /// Column upper bounds - working copy + CoinWorkDouble * columnUpperWork_; + /// Working copy of objective + CoinWorkDouble * cost_; +public: + /// Rhs + CoinWorkDouble * rhs_; + CoinWorkDouble * x_; + CoinWorkDouble * y_; + CoinWorkDouble * dj_; +protected: + /// Pointer to Lsqr object + ClpLsqr * lsqrObject_; + /// Pointer to stuff + ClpPdcoBase * pdcoStuff_; + /// Below here is standard barrier stuff + /// mu. + CoinWorkDouble mu_; + /// objectiveNorm. + CoinWorkDouble objectiveNorm_; + /// rhsNorm. + CoinWorkDouble rhsNorm_; + /// solutionNorm. + CoinWorkDouble solutionNorm_; + /// dualObjective. + CoinWorkDouble dualObjective_; + /// primalObjective. + CoinWorkDouble primalObjective_; + /// diagonalNorm. + CoinWorkDouble diagonalNorm_; + /// stepLength + CoinWorkDouble stepLength_; + /// linearPerturbation + CoinWorkDouble linearPerturbation_; + /// diagonalPerturbation + CoinWorkDouble diagonalPerturbation_; + // gamma from Saunders and Tomlin regularized + CoinWorkDouble gamma_; + // delta from Saunders and Tomlin regularized + CoinWorkDouble delta_; + /// targetGap + CoinWorkDouble targetGap_; + /// projectionTolerance + CoinWorkDouble projectionTolerance_; + /// maximumRHSError. maximum Ax + CoinWorkDouble maximumRHSError_; + /// maximumBoundInfeasibility. + CoinWorkDouble maximumBoundInfeasibility_; + /// maximumDualError. + CoinWorkDouble maximumDualError_; + /// diagonalScaleFactor. + CoinWorkDouble diagonalScaleFactor_; + /// scaleFactor. For scaling objective + CoinWorkDouble scaleFactor_; + /// actualPrimalStep + CoinWorkDouble actualPrimalStep_; + /// actualDualStep + CoinWorkDouble actualDualStep_; + /// smallestInfeasibility + CoinWorkDouble smallestInfeasibility_; + /// historyInfeasibility. +#define LENGTH_HISTORY 5 + CoinWorkDouble historyInfeasibility_[LENGTH_HISTORY]; + /// complementarityGap. + CoinWorkDouble complementarityGap_; + /// baseObjectiveNorm + CoinWorkDouble baseObjectiveNorm_; + /// worstDirectionAccuracy + CoinWorkDouble worstDirectionAccuracy_; + /// maximumRHSChange + CoinWorkDouble maximumRHSChange_; + /// errorRegion. i.e. Ax + CoinWorkDouble * errorRegion_; + /// rhsFixRegion. + CoinWorkDouble * rhsFixRegion_; + /// upperSlack + CoinWorkDouble * upperSlack_; + /// lowerSlack + CoinWorkDouble * lowerSlack_; + /// diagonal + CoinWorkDouble * diagonal_; + /// solution + CoinWorkDouble * solution_; + /// work array + CoinWorkDouble * workArray_; + /// delta X + CoinWorkDouble * deltaX_; + /// delta Y + CoinWorkDouble * deltaY_; + /// deltaZ. + CoinWorkDouble * deltaZ_; + /// deltaW. + CoinWorkDouble * deltaW_; + /// deltaS. + CoinWorkDouble * deltaSU_; + CoinWorkDouble * deltaSL_; + /// Primal regularization array + CoinWorkDouble * primalR_; + /// Dual regularization array + CoinWorkDouble * dualR_; + /// rhs B + CoinWorkDouble * rhsB_; + /// rhsU. + CoinWorkDouble * rhsU_; + /// rhsL. + CoinWorkDouble * rhsL_; + /// rhsZ. + CoinWorkDouble * rhsZ_; + /// rhsW. + CoinWorkDouble * rhsW_; + /// rhs C + CoinWorkDouble * rhsC_; + /// zVec + CoinWorkDouble * zVec_; + /// wVec + CoinWorkDouble * wVec_; + /// cholesky. + ClpCholeskyBase * cholesky_; + /// numberComplementarityPairs i.e. ones with lower and/or upper bounds (not fixed) + int numberComplementarityPairs_; + /// numberComplementarityItems_ i.e. number of active bounds + int numberComplementarityItems_; + /// Maximum iterations + int maximumBarrierIterations_; + /// gonePrimalFeasible. + bool gonePrimalFeasible_; + /// goneDualFeasible. + bool goneDualFeasible_; + /// Which algorithm being used + int algorithm_; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpInterior class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpInteriorUnitTest(const std::string & mpsDir, + const std::string & netlibDir); + + +#endif diff --git a/thirdparty/linux/include/coin1/ClpLinearObjective.hpp b/thirdparty/linux/include/coin1/ClpLinearObjective.hpp new file mode 100644 index 0000000..ff035d4 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpLinearObjective.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpLinearObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpLinearObjective_H +#define ClpLinearObjective_H + +#include "ClpObjective.hpp" + +//############################################################################# + +/** Linear Objective Class + +*/ + +class ClpLinearObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns objective coefficients. + + Offset is always set to 0.0. All other parameters unused. + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + /// Resize objective + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpLinearObjective(); + + /// Constructor from objective + ClpLinearObjective(const double * objective, int numberColumns); + + /// Copy constructor + ClpLinearObjective(const ClpLinearObjective &); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpLinearObjective (const ClpLinearObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpLinearObjective & operator=(const ClpLinearObjective& rhs); + + /// Destructor + virtual ~ClpLinearObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Objective + double * objective_; + /// number of columns + int numberColumns_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpMatrixBase.hpp b/thirdparty/linux/include/coin1/ClpMatrixBase.hpp new file mode 100644 index 0000000..06dc523 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpMatrixBase.hpp @@ -0,0 +1,524 @@ +/* $Id: ClpMatrixBase.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMatrixBase_H +#define ClpMatrixBase_H + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" + +#include "CoinPackedMatrix.hpp" +class CoinIndexedVector; +class ClpSimplex; +class ClpModel; +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +/** Abstract base class for Clp Matrices + +Since this class is abstract, no object of this type can be created. + +If a derived class provides all methods then all Clp algorithms +should work. Some can be very inefficient e.g. getElements etc is +only used for tightening bounds for dual and the copies are +deleted. Many methods can just be dummy i.e. abort(); if not +all features are being used. So if column generation was being done +then it makes no sense to do steepest edge so there would be +no point providing subsetTransposeTimes. +*/ + +class ClpMatrixBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const = 0; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const = 0; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const = 0; + /** Number of columns. */ + virtual int getNumCols() const = 0; + /** Number of rows. */ + virtual int getNumRows() const = 0; + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const = 0; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const = 0; + + virtual const CoinBigIndex * getVectorStarts() const = 0; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const = 0 ; + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const ; + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel) = 0; + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel) = 0; +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false); + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + + /** Returns a new matrix in reverse order without gaps + Is allowed to return NULL if doesn't want to have row copy */ + virtual ClpMatrixBase * reverseOrderedCopy() const { + return NULL; + } + + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic) = 0; + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element) = 0; + /** Creates scales for column copy (rowCopy in model may be modified) + default does not allow scaling + returns non-zero if no scaling done */ + virtual int scale(ClpModel * , const ClpSimplex * = NULL) const { + return 1; + } + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * ) const { } + /// Returns true if can create row copy + virtual bool canGetRowCopy() const { + return true; + } + /** Realy really scales column copy + Only called if scales already exist. + Up to user to delete */ + inline virtual ClpMatrixBase * scaledColumnCopy(ClpModel * ) const { + return this->clone(); + } + + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * , + double , double , + int = 15) { + return true; + } + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + If returns zeros then can't tell anything */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const = 0; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const = 0; + /** Purely for column generation and similar ideas. Allows + matrix and any bounds or costs to be updated (sensibly). + Returns non-zero if any changes. + */ + virtual int refresh(ClpSimplex * ) { + return 0; + } + + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + Default returns vector of ones + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const = 0; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const = 0; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const = 0; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Returns number of hidden rows e.g. gub + virtual int hiddenRows() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /** expands an updated column to allow for extra rows which the main + solver does not know about and returns number added. + + This will normally be a no-op - it is in for GUB but may get extended to + general non-overlapping and embedded networks. + + mode 0 - extend + mode 1 - delete etc + */ + virtual int extendUpdated(ClpSimplex * model, CoinIndexedVector * update, int mode); + /** + utility primal function for dealing with dynamic constraints + mode=0 - Set up before "update" and "times" for primal solution using extended rows + mode=1 - Cleanup primal solution after "times" using extended rows. + mode=2 - Check (or report on) primal infeasibilities + */ + virtual void primalExpanded(ClpSimplex * model, int mode); + /** + utility dual function for dealing with dynamic constraints + mode=0 - Set up before "updateTranspose" and "transposeTimes" for duals using extended + updates array (and may use other if dual values pass) + mode=1 - Update dual solution after "transposeTimes" using extended rows. + mode=2 - Compute all djs and compute key dual infeasibilities + mode=3 - Report on key dual infeasibilities + mode=4 - Modify before updateTranspose in partial pricing + */ + virtual void dualExpanded(ClpSimplex * model, CoinIndexedVector * array, + double * other, int mode); + /** + general utility function for dealing with dynamic constraints + mode=0 - Create list of non-key basics in pivotVariable_ using + number as numberBasic in and out + mode=1 - Set all key variables as basic + mode=2 - return number extra rows needed, number gives maximum number basic + mode=3 - before replaceColumn + mode=4 - return 1 if can do primal, 2 if dual, 3 if both + mode=5 - save any status stuff (when in good state) + mode=6 - restore status stuff + mode=7 - flag given variable (normally sequenceIn) + mode=8 - unflag all variables + mode=9 - synchronize costs and bounds + mode=10 - return 1 if there may be changing bounds on variable (column generation) + mode=11 - make sure set is clean (used when a variable rejected - but not flagged) + mode=12 - after factorize but before permute stuff + mode=13 - at end of simplex to delete stuff + + */ + virtual int generalExpanded(ClpSimplex * model, int mode, int & number); + /** + update information for a pivot (and effective rhs) + */ + virtual int updatePivot(ClpSimplex * model, double oldInValue, double oldOutValue); + /** Creates a variable. This is called after partial pricing and may modify matrix. + May update bestSequence. + */ + virtual void createVariable(ClpSimplex * model, int & bestSequence); + /** Just for debug if odd type matrix. + Returns number of primal infeasibilities. */ + virtual int checkFeasible(ClpSimplex * model, double & sum) const ; + /// Returns reduced cost of a variable + double reducedCost(ClpSimplex * model, int sequence) const; + /// Correct sequence in and out to give true value (if both -1 maybe do whole matrix) + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return <code>y + A * x * scalar</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void times(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y) const = 0; + /** And for scaling - default aborts for when scaling not supported + (unless pointers NULL when as normal) + */ + virtual void transposeTimes(double scalar, + const double * COIN_RESTRICT x, double * COIN_RESTRICT y, + const double * COIN_RESTRICT rowScale, + const double * COIN_RESTRICT columnScale, + double * COIN_RESTRICT spare = NULL) const; +#if COIN_LONG_WORK + // For long double versions (aborts if not supported) + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * COIN_RESTRICT x, CoinWorkDouble * COIN_RESTRICT y) const ; +#endif + /** Return <code>x * scalar *A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + This is only needed for primal steepest edge. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const = 0; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * , + const CoinIndexedVector * ) const { + return false; + } + /// Updates two arrays for steepest and does devex weights (need not be coded) + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights (need not be coded) + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /** Return <code>x *A</code> in <code>z</code> but + just for number indices in y. + Default cheats with fake CoinIndexedVector and + then calls subsetTransposeTimes */ + virtual void listTransposeTimes(const ClpSimplex * model, + double * x, + int * y, + int number, + double * z) const; + //@} + //@{ + ///@name Other + /// Clone + virtual ClpMatrixBase * clone() const = 0; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const; + /// Gets rid of any mutable by products + virtual void backToBasics() {} + /** Returns type. + The types which code may need to know about are: + 1 - ClpPackedMatrix + 11 - ClpNetworkMatrix + 12 - ClpPlusMinusOneMatrix + */ + inline int type() const { + return type_; + } + /// Sets type + void setType(int newtype) { + type_ = newtype; + } + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); + /** Returns effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive. This may re-compute */ + virtual double * rhsOffset(ClpSimplex * model, bool forceRefresh = false, + bool check = false); + /// If rhsOffset used this is iteration last refreshed + inline int lastRefresh() const { + return lastRefresh_; + } + /// If rhsOffset used this is refresh frequency (0==off) + inline int refreshFrequency() const { + return refreshFrequency_; + } + inline void setRefreshFrequency(int value) { + refreshFrequency_ = value; + } + /// whether to skip dual checks most of time + inline bool skipDualCheck() const { + return skipDualCheck_; + } + inline void setSkipDualCheck(bool yes) { + skipDualCheck_ = yes; + } + /** Partial pricing tuning parameter - minimum number of "objects" to scan. + e.g. number of Gub sets but could be number of variables */ + inline int minimumObjectsScan() const { + return minimumObjectsScan_; + } + inline void setMinimumObjectsScan(int value) { + minimumObjectsScan_ = value; + } + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + inline int minimumGoodReducedCosts() const { + return minimumGoodReducedCosts_; + } + inline void setMinimumGoodReducedCosts(int value) { + minimumGoodReducedCosts_ = value; + } + /// Current start of search space in matrix (as fraction) + inline double startFraction() const { + return startFraction_; + } + inline void setStartFraction(double value) { + startFraction_ = value; + } + /// Current end of search space in matrix (as fraction) + inline double endFraction() const { + return endFraction_; + } + inline void setEndFraction(double value) { + endFraction_ = value; + } + /// Current best reduced cost + inline double savedBestDj() const { + return savedBestDj_; + } + inline void setSavedBestDj(double value) { + savedBestDj_ = value; + } + /// Initial number of negative reduced costs wanted + inline int originalWanted() const { + return originalWanted_; + } + inline void setOriginalWanted(int value) { + originalWanted_ = value; + } + /// Current number of negative reduced costs which we still need + inline int currentWanted() const { + return currentWanted_; + } + inline void setCurrentWanted(int value) { + currentWanted_ = value; + } + /// Current best sequence + inline int savedBestSequence() const { + return savedBestSequence_; + } + inline void setSavedBestSequence(int value) { + savedBestSequence_ = value; + } + //@} + + +protected: + + /**@name Constructors, destructor<br> + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpMatrixBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpMatrixBase(); +protected: + // Copy + ClpMatrixBase(const ClpMatrixBase&); + // Assignment + ClpMatrixBase& operator=(const ClpMatrixBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** Effective RHS offset if it is being used. This is used for long problems + or big gub or anywhere where going through full columns is + expensive */ + double * rhsOffset_; + /// Current start of search space in matrix (as fraction) + double startFraction_; + /// Current end of search space in matrix (as fraction) + double endFraction_; + /// Best reduced cost so far + double savedBestDj_; + /// Initial number of negative reduced costs wanted + int originalWanted_; + /// Current number of negative reduced costs which we still need + int currentWanted_; + /// Saved best sequence in pricing + int savedBestSequence_; + /// type (may be useful) + int type_; + /// If rhsOffset used this is iteration last refreshed + int lastRefresh_; + /// If rhsOffset used this is refresh frequency (0==off) + int refreshFrequency_; + /// Partial pricing tuning parameter - minimum number of "objects" to scan + int minimumObjectsScan_; + /// Partial pricing tuning parameter - minimum number of negative reduced costs to get + int minimumGoodReducedCosts_; + /// True sequence in (i.e. from larger problem) + int trueSequenceIn_; + /// True sequence out (i.e. from larger problem) + int trueSequenceOut_; + /// whether to skip dual checks most of time + bool skipDualCheck_; + //@} +}; +// bias for free variables +#define FREE_BIAS 1.0e1 +// Acceptance criteria for free variables +#define FREE_ACCEPT 1.0e2 + +#endif diff --git a/thirdparty/linux/include/coin1/ClpMessage.hpp b/thirdparty/linux/include/coin1/ClpMessage.hpp new file mode 100644 index 0000000..5eb3653 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpMessage.hpp @@ -0,0 +1,131 @@ +/* $Id: ClpMessage.hpp 1926 2013-03-26 15:23:38Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpMessage_H +#define ClpMessage_H + + +#include "CoinPragma.hpp" +#include <cstring> + +// This deals with Clp messages (as against Osi messages etc) + +#include "CoinMessageHandler.hpp" +enum CLP_Message { + CLP_SIMPLEX_FINISHED, + CLP_SIMPLEX_INFEASIBLE, + CLP_SIMPLEX_UNBOUNDED, + CLP_SIMPLEX_STOPPED, + CLP_SIMPLEX_ERROR, + CLP_SIMPLEX_INTERRUPT, + CLP_SIMPLEX_STATUS, + CLP_DUAL_BOUNDS, + CLP_SIMPLEX_ACCURACY, + CLP_SIMPLEX_BADFACTOR, + CLP_SIMPLEX_BOUNDTIGHTEN, + CLP_SIMPLEX_INFEASIBILITIES, + CLP_SIMPLEX_FLAG, + CLP_SIMPLEX_GIVINGUP, + CLP_DUAL_CHECKB, + CLP_DUAL_ORIGINAL, + CLP_SIMPLEX_PERTURB, + CLP_PRIMAL_ORIGINAL, + CLP_PRIMAL_WEIGHT, + CLP_PRIMAL_OPTIMAL, + CLP_SINGULARITIES, + CLP_MODIFIEDBOUNDS, + CLP_RIMSTATISTICS1, + CLP_RIMSTATISTICS2, + CLP_RIMSTATISTICS3, + CLP_POSSIBLELOOP, + CLP_SMALLELEMENTS, + CLP_DUPLICATEELEMENTS, + CLP_SIMPLEX_HOUSE1, + CLP_SIMPLEX_HOUSE2, + CLP_SIMPLEX_NONLINEAR, + CLP_SIMPLEX_FREEIN, + CLP_SIMPLEX_PIVOTROW, + CLP_DUAL_CHECK, + CLP_PRIMAL_DJ, + CLP_PACKEDSCALE_INITIAL, + CLP_PACKEDSCALE_WHILE, + CLP_PACKEDSCALE_FINAL, + CLP_PACKEDSCALE_FORGET, + CLP_INITIALIZE_STEEP, + CLP_UNABLE_OPEN, + CLP_BAD_BOUNDS, + CLP_BAD_MATRIX, + CLP_LOOP, + CLP_IMPORT_RESULT, + CLP_IMPORT_ERRORS, + CLP_EMPTY_PROBLEM, + CLP_CRASH, + CLP_END_VALUES_PASS, + CLP_QUADRATIC_BOTH, + CLP_QUADRATIC_PRIMAL_DETAILS, + CLP_IDIOT_ITERATION, + CLP_INFEASIBLE, + CLP_MATRIX_CHANGE, + CLP_TIMING, + CLP_INTERVAL_TIMING, + CLP_SPRINT, + CLP_BARRIER_ITERATION, + CLP_BARRIER_OBJECTIVE_GAP, + CLP_BARRIER_GONE_INFEASIBLE, + CLP_BARRIER_CLOSE_TO_OPTIMAL, + CLP_BARRIER_COMPLEMENTARITY, + CLP_BARRIER_EXIT2, + CLP_BARRIER_STOPPING, + CLP_BARRIER_EXIT, + CLP_BARRIER_SCALING, + CLP_BARRIER_MU, + CLP_BARRIER_INFO, + CLP_BARRIER_END, + CLP_BARRIER_ACCURACY, + CLP_BARRIER_SAFE, + CLP_BARRIER_NEGATIVE_GAPS, + CLP_BARRIER_REDUCING, + CLP_BARRIER_DIAGONAL, + CLP_BARRIER_SLACKS, + CLP_BARRIER_DUALINF, + CLP_BARRIER_KILLED, + CLP_BARRIER_ABS_DROPPED, + CLP_BARRIER_ABS_ERROR, + CLP_BARRIER_FEASIBLE, + CLP_BARRIER_STEP, + CLP_BARRIER_KKT, + CLP_RIM_SCALE, + CLP_SLP_ITER, + CLP_COMPLICATED_MODEL, + CLP_BAD_STRING_VALUES, + CLP_CRUNCH_STATS, + CLP_PARAMETRICS_STATS, + CLP_PARAMETRICS_STATS2, +#ifndef NO_FATHOM_PRINT + CLP_FATHOM_STATUS, + CLP_FATHOM_SOLUTION, + CLP_FATHOM_FINISH, +#endif + CLP_GENERAL, + CLP_GENERAL2, + CLP_GENERAL_WARNING, + CLP_DUMMY_END +}; + +/** This deals with Clp messages (as against Osi messages etc) + */ +class ClpMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /** Constructor */ + ClpMessage(Language language = us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpModel.hpp b/thirdparty/linux/include/coin1/ClpModel.hpp new file mode 100644 index 0000000..4a22539 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpModel.hpp @@ -0,0 +1,1307 @@ +/* $Id: ClpModel.hpp 2074 2014-12-10 09:43:54Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpModel_H +#define ClpModel_H + +#include "ClpConfig.h" + +#include <iostream> +#include <cassert> +#include <cmath> +#include <vector> +#include <string> +//#ifndef COIN_USE_CLP +//#define COIN_USE_CLP +//#endif +#include "ClpPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" +#include "ClpParameters.hpp" +#include "ClpObjective.hpp" +class ClpEventHandler; +/** This is the base class for Linear and quadratic Models + This knows nothing about the algorithm, but it seems to + have a reasonable amount of information + + I would welcome suggestions for what should be in this and + how it relates to OsiSolverInterface. Some methods look + very similar. + +*/ +class CoinBuild; +class CoinModel; +class ClpModel { + +public: + + /**@name Constructors and destructor + Note - copy methods copy ALL data so can chew up memory + until other copy is freed + */ + //@{ + /// Default constructor + ClpModel (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 auto-but-as-initialSolve-in-bab + */ + ClpModel(const ClpModel & rhs, int scalingMode = -1); + /// Assignment operator. This copies the data + ClpModel & operator=(const ClpModel & rhs); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + */ + ClpModel (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true); + /// Destructor + ~ClpModel ( ); + //@} + + /**@name Load model - loads some stuff and initializes others */ + //@{ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + + modelObject not const as may be changed as part of process + If tryPlusMinusOne then will try adding as +-1 matrix + */ + int loadProblem ( CoinModel & modelObject, bool tryPlusMinusOne = false); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + /// This just loads up a row objective + void setRowObjective(const double * rowObjective); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Copy in integer informations + void copyInIntegerInformation(const char * information); + /// Drop integer informations + void deleteIntegerInformation(); + /** Set the index-th variable to be a continuous variable */ + void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + void setInteger(int index); + /** Return true if the index-th variable is an integer variable */ + bool isInteger(int index) const; + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + /// Deletes rows + void deleteRows(int number, const int * which); + /// Add one row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower = -COIN_DBL_MAX, + double rowUpper = COIN_DBL_MAX); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * columns, + const double * elements); + /// Add rows + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinBigIndex * rowStarts, const int * rowLengths, + const int * columns, + const double * elements); +#ifndef CLP_NO_VECTOR + void addRows(int number, const double * rowLower, + const double * rowUpper, + const CoinPackedVectorBase * const * rows); +#endif + /** Add rows from a build object. + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addRows(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add rows from a model object. returns + -1 if object in bad state (i.e. has column information) + otherwise number of errors. + + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addRows(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + + /// Deletes columns + void deleteColumns(int number, const int * which); + /// Deletes rows AND columns (keeps old sizes) + void deleteRowsAndColumns(int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /// Add one column + void addColumn(int numberInColumn, + const int * rows, + const double * elements, + double columnLower = 0.0, + double columnUpper = COIN_DBL_MAX, + double objective = 0.0); + /// Add columns + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * rows, + const double * elements); + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinBigIndex * columnStarts, const int * columnLengths, + const int * rows, + const double * elements); +#ifndef CLP_NO_VECTOR + void addColumns(int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const CoinPackedVectorBase * const * columns); +#endif + /** Add columns from a build object + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + Returns number of errors e.g. duplicates + */ + int addColumns(const CoinBuild & buildObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + If tryPlusMinusOne then will try adding as +-1 matrix + if no matrix exists. + */ + int addColumns(CoinModel & modelObject, bool tryPlusMinusOne = false, + bool checkDuplicates = true); + /// Modify one element of a matrix + inline void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Change row lower bounds */ + void chgRowLower(const double * rowLower); + /** Change row upper bounds */ + void chgRowUpper(const double * rowUpper); + /** Change column lower bounds */ + void chgColumnLower(const double * columnLower); + /** Change column upper bounds */ + void chgColumnUpper(const double * columnUpper); + /** Change objective coefficients */ + void chgObjCoefficients(const double * objIn); + /** Borrow model. This is so we don't have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm */ + void borrowModel(ClpModel & otherModel); + /** Return model - nulls all arrays so can be deleted safely + also updates any scalars */ + void returnModel(ClpModel & otherModel); + + /// Create empty ClpPackedMatrix + void createEmptyMatrix(); + /** Really clean up matrix (if ClpPackedMatrix). + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated or -1 if not ClpPackedMatrix + */ + int cleanMatrix(double threshold = 1.0e-20); + /// Copy contents - resizing if necessary - otherwise re-use memory + void copy(const ClpMatrixBase * from, ClpMatrixBase * & to); +#ifndef CLP_NO_STD + /// Drops names - makes lengthnames 0 and names empty + void dropNames(); + /// Copies in names + void copyNames(const std::vector<std::string> & rowNames, + const std::vector<std::string> & columnNames); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const std::vector<std::string> & rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last); + /// Copies in Row names - modifies names first .. last-1 + void copyRowNames(const char * const * rowNames, int first, int last); + /// Copies in Column names - modifies names first .. last-1 + void copyColumnNames(const char * const * columnNames, int first, int last); + /// Set name of row + void setRowName(int rowIndex, std::string & name) ; + /// Set name of col + void setColumnName(int colIndex, std::string & name) ; +#endif + /** Find a network subset. + rotate array should be numberRows. On output + -1 not in network + 0 in network as is + 1 in network with signs swapped + Returns number of network rows + */ + int findNetwork(char * rotate, double fractionNeeded = 0.75); + /** This creates a coinModel object + */ + CoinModel * createCoinModel() const; + + /** Write the problem in MPS format to the specified file. + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex + </ul> + + Returns non-zero on I/O error + */ + int writeMps(const char *filename, + int formatType = 0, int numberAcross = 2, + double objSense = 0.0) const ; + //@} + /**@name gets and sets */ + //@{ + /// Number of rows + inline int numberRows() const { + return numberRows_; + } + inline int getNumRows() const { + return numberRows_; + } + /// Number of columns + inline int getNumCols() const { + return numberColumns_; + } + inline int numberColumns() const { + return numberColumns_; + } + /// Primal tolerance to use + inline double primalTolerance() const { + return dblParam_[ClpPrimalTolerance]; + } + void setPrimalTolerance( double value) ; + /// Dual tolerance to use + inline double dualTolerance() const { + return dblParam_[ClpDualTolerance]; + } + void setDualTolerance( double value) ; + /// Primal objective limit + inline double primalObjectiveLimit() const { + return dblParam_[ClpPrimalObjectiveLimit]; + } + void setPrimalObjectiveLimit(double value); + /// Dual objective limit + inline double dualObjectiveLimit() const { + return dblParam_[ClpDualObjectiveLimit]; + } + void setDualObjectiveLimit(double value); + /// Objective offset + inline double objectiveOffset() const { + return dblParam_[ClpObjOffset]; + } + void setObjectiveOffset(double value); + /// Presolve tolerance to use + inline double presolveTolerance() const { + return dblParam_[ClpPresolveTolerance]; + } +#ifndef CLP_NO_STD + inline const std::string & problemName() const { + return strParam_[ClpProbName]; + } +#endif + /// Number of iterations + inline int numberIterations() const { + return numberIterations_; + } + inline int getIterationCount() const { + return numberIterations_; + } + inline void setNumberIterations(int numberIterationsNew) { + numberIterations_ = numberIterationsNew; + } + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + inline int solveType() const { + return solveType_; + } + inline void setSolveType(int type) { + solveType_ = type; + } + /// Maximum number of iterations + inline int maximumIterations() const { + return intParam_[ClpMaxNumIteration]; + } + void setMaximumIterations(int value); + /// Maximum time in seconds (from when set called) + inline double maximumSeconds() const { + return dblParam_[ClpMaxSeconds]; + } + void setMaximumSeconds(double value); + void setMaximumWallSeconds(double value); + /// Returns true if hit maximum iterations (or time) + bool hitMaximumIterations() const; + /** Status of problem: + -1 - unknown e.g. before solve or if postSolve says not optimal + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations or time + 4 - stopped due to errors + 5 - stopped by event handler (virtual int ClpEventHandler::event()) + */ + inline int status() const { + return problemStatus_; + } + inline int problemStatus() const { + return problemStatus_; + } + /// Set problem status + inline void setProblemStatus(int problemStatusNew) { + problemStatus_ = problemStatusNew; + } + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached OR (probably primal + infeasible but can't prove it - main status was 4) + 2 - scaled problem optimal - unscaled problem has primal infeasibilities + 3 - scaled problem optimal - unscaled problem has dual infeasibilities + 4 - scaled problem optimal - unscaled problem has primal and dual infeasibilities + 5 - giving up in primal with flagged variables + 6 - failed due to empty problem check + 7 - postSolve says not optimal + 8 - failed due to bad element check + 9 - status was 3 and stopped on time + 10 - status was 3 but stopped as primal feasible + 100 up - translation of enum from ClpEventHandler + */ + inline int secondaryStatus() const { + return secondaryStatus_; + } + inline void setSecondaryStatus(int newstatus) { + secondaryStatus_ = newstatus; + } + /// Are there a numerical difficulties? + inline bool isAbandoned() const { + return problemStatus_ == 4; + } + /// Is optimality proven? + inline bool isProvenOptimal() const { + return problemStatus_ == 0; + } + /// Is primal infeasiblity proven? + inline bool isProvenPrimalInfeasible() const { + return problemStatus_ == 1; + } + /// Is dual infeasiblity proven? + inline bool isProvenDualInfeasible() const { + return problemStatus_ == 2; + } + /// Is the given primal objective limit reached? + bool isPrimalObjectiveLimitReached() const ; + /// Is the given dual objective limit reached? + bool isDualObjectiveLimitReached() const ; + /// Iteration limit reached? + inline bool isIterationLimitReached() const { + return problemStatus_ == 3; + } + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + inline double getObjSense() const { + return optimizationDirection_; + } + void setOptimizationDirection(double value); + /// Primal row solution + inline double * primalRowSolution() const { + return rowActivity_; + } + inline const double * getRowActivity() const { + return rowActivity_; + } + /// Primal column solution + inline double * primalColumnSolution() const { + return columnActivity_; + } + inline const double * getColSolution() const { + return columnActivity_; + } + inline void setColSolution(const double * input) { + memcpy(columnActivity_, input, numberColumns_ * sizeof(double)); + } + /// Dual row solution + inline double * dualRowSolution() const { + return dual_; + } + inline const double * getRowPrice() const { + return dual_; + } + /// Reduced costs + inline double * dualColumnSolution() const { + return reducedCost_; + } + inline const double * getReducedCost() const { + return reducedCost_; + } + /// Row lower + inline double* rowLower() const { + return rowLower_; + } + inline const double* getRowLower() const { + return rowLower_; + } + /// Row upper + inline double* rowUpper() const { + return rowUpper_; + } + inline const double* getRowUpper() const { + return rowUpper_; + } + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double lower, double upper ) { + setColumnBounds(elementIndex, lower, upper); + } + + /** Set the bounds on a number of columns simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + //@} + /// Scaling + inline const double * rowScale() const { + return rowScale_; + } + inline const double * columnScale() const { + return columnScale_; + } + inline const double * inverseRowScale() const { + return inverseRowScale_; + } + inline const double * inverseColumnScale() const { + return inverseColumnScale_; + } + inline double * mutableRowScale() const { + return rowScale_; + } + inline double * mutableColumnScale() const { + return columnScale_; + } + inline double * mutableInverseRowScale() const { + return inverseRowScale_; + } + inline double * mutableInverseColumnScale() const { + return inverseColumnScale_; + } + inline double * swapRowScale(double * newScale) { + double * oldScale = rowScale_; + rowScale_ = newScale; + return oldScale; + } + void setRowScale(double * scale) ; + void setColumnScale(double * scale); + /// Scaling of objective + inline double objectiveScale() const { + return objectiveScale_; + } + inline void setObjectiveScale(double value) { + objectiveScale_ = value; + } + /// Scaling of rhs and bounds + inline double rhsScale() const { + return rhsScale_; + } + inline void setRhsScale(double value) { + rhsScale_ = value; + } + /// Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 auto-but-as-initialSolve-in-bab + void scaling(int mode = 1); + /** If we constructed a "really" scaled model then this reverses the operation. + Quantities may not be exactly as they were before due to rounding errors */ + void unscale(); + /// Gets scalingFlag + inline int scalingFlag() const { + return scalingFlag_; + } + /// Objective + inline double * objective() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + inline double * objective(const double * solution, double & offset, bool refresh = true) const { + offset = 0.0; + if (objective_) { + return objective_->gradient(NULL, solution, offset, refresh); + } else { + return NULL; + } + } + inline const double * getObjCoefficients() const { + if (objective_) { + double offset; + return objective_->gradient(NULL, NULL, offset, false); + } else { + return NULL; + } + } + /// Row Objective + inline double * rowObjective() const { + return rowObjective_; + } + inline const double * getRowObjCoefficients() const { + return rowObjective_; + } + /// Column Lower + inline double * columnLower() const { + return columnLower_; + } + inline const double * getColLower() const { + return columnLower_; + } + /// Column Upper + inline double * columnUpper() const { + return columnUpper_; + } + inline const double * getColUpper() const { + return columnUpper_; + } + /// Matrix (if not ClpPackedmatrix be careful about memory leak + inline CoinPackedMatrix * matrix() const { + if ( matrix_ == NULL ) return NULL; + else return matrix_->getPackedMatrix(); + } + /// Number of elements in matrix + inline int getNumElements() const { + return matrix_->getNumElements(); + } + /** Small element value - elements less than this set to zero, + default is 1.0e-20 */ + inline double getSmallElementValue() const { + return smallElement_; + } + inline void setSmallElementValue(double value) { + smallElement_ = value; + } + /// Row Matrix + inline ClpMatrixBase * rowCopy() const { + return rowCopy_; + } + /// Set new row matrix + void setNewRowCopy(ClpMatrixBase * newCopy); + /// Clp Matrix + inline ClpMatrixBase * clpMatrix() const { + return matrix_; + } + /// Scaled ClpPackedMatrix + inline ClpPackedMatrix * clpScaledMatrix() const { + return scaledMatrix_; + } + /// Sets pointer to scaled ClpPackedMatrix + inline void setClpScaledMatrix(ClpPackedMatrix * scaledMatrix) { + delete scaledMatrix_; + scaledMatrix_ = scaledMatrix; + } + /// Swaps pointer to scaled ClpPackedMatrix + inline ClpPackedMatrix * swapScaledMatrix(ClpPackedMatrix * scaledMatrix) { + ClpPackedMatrix * oldMatrix = scaledMatrix_; + scaledMatrix_ = scaledMatrix; + return oldMatrix; + } + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) + So up to user to delete current. This was used where + matrices were being rotated. ClpModel takes ownership. + */ + void replaceMatrix(ClpMatrixBase * matrix, bool deleteCurrent = false); + /** Replace Clp Matrix (current is not deleted unless told to + and new is used) So up to user to delete current. This was used where + matrices were being rotated. This version changes CoinPackedMatrix + to ClpPackedMatrix. ClpModel takes ownership. + */ + inline void replaceMatrix(CoinPackedMatrix * newmatrix, + bool deleteCurrent = false) { + replaceMatrix(new ClpPackedMatrix(newmatrix), deleteCurrent); + } + /// Objective value + inline double objectiveValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + inline void setObjectiveValue(double value) { + objectiveValue_ = (value + dblParam_[ClpObjOffset]) / optimizationDirection_; + } + inline double getObjValue() const { + return objectiveValue_ * optimizationDirection_ - dblParam_[ClpObjOffset]; + } + /// Integer information + inline char * integerInformation() const { + return integerType_; + } + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + double * unboundedRay() const; + /// For advanced users - no need to delete - sign not changed + inline double * ray() const + { return ray_;} + /// just test if infeasibility or unbounded Ray exists + inline bool rayExists() const { + return (ray_!=NULL); + } + /// just delete ray if exists + inline void deleteRay() { + delete [] ray_; + ray_=NULL; + } + /// Access internal ray storage. Users should call infeasibilityRay() or unboundedRay() instead. + inline const double * internalRay() const { + return ray_; + } + /// See if status (i.e. basis) array exists (partly for OsiClp) + inline bool statusExists() const { + return (status_ != NULL); + } + /// Return address of status (i.e. basis) array (char[numberRows+numberColumns]) + inline unsigned char * statusArray() const { + return status_; + } + /** Return copy of status (i.e. basis) array (char[numberRows+numberColumns]), + use delete [] */ + unsigned char * statusCopy() const; + /// Copy in status (basis) vector + void copyinStatus(const unsigned char * statusArray); + + /// User pointer for whatever reason + inline void setUserPointer (void * pointer) { + userPointer_ = pointer; + } + inline void * getUserPointer () const { + return userPointer_; + } + /// Trusted user pointer + inline void setTrustedUserPointer (ClpTrustedData * pointer) { + trustedUserPointer_ = pointer; + } + inline ClpTrustedData * getTrustedUserPointer () const { + return trustedUserPointer_; + } + /// What has changed in model (only for masochistic users) + inline int whatsChanged() const { + return whatsChanged_; + } + inline void setWhatsChanged(int value) { + whatsChanged_ = value; + } + /// Number of threads (not really being used) + inline int numberThreads() const { + return numberThreads_; + } + inline void setNumberThreads(int value) { + numberThreads_ = value; + } + //@} + /**@name Message handling */ + //@{ + /// Pass in Message handler (not deleted at end) + void passInMessageHandler(CoinMessageHandler * handler); + /// Pass in Message handler (not deleted at end) and return current + CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler, + bool & oldDefault); + /// back to previous message handler + void popMessageHandler(CoinMessageHandler * oldHandler, bool oldDefault); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) { + newLanguage(language); + } + /// Overrides message handler with a default one + void setDefaultMessageHandler(); + /// Return handler + inline CoinMessageHandler * messageHandler() const { + return handler_; + } + /// Return messages + inline CoinMessages messages() const { + return messages_; + } + /// Return pointer to messages + inline CoinMessages * messagesPointer() { + return & messages_; + } + /// Return Coin messages + inline CoinMessages coinMessages() const { + return coinMessages_; + } + /// Return pointer to Coin messages + inline CoinMessages * coinMessagesPointer() { + return & coinMessages_; + } + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + inline void setLogLevel(int value) { + handler_->setLogLevel(value); + } + inline int logLevel() const { + return handler_->logLevel(); + } + /// Return true if default handler + inline bool defaultHandler() const { + return defaultHandler_; + } + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Event handler + inline ClpEventHandler * eventHandler() const { + return eventHandler_; + } + /// Thread specific random number generator + inline CoinThreadRandom * randomNumberGenerator() { + return &randomNumberGenerator_; + } + /// Thread specific random number generator + inline CoinThreadRandom & mutableRandomNumberGenerator() { + return randomNumberGenerator_; + } + /// Set seed for thread specific random number generator + inline void setRandomSeed(int value) { + randomNumberGenerator_.setSeed(value); + } + /// length of names (0 means no names0 + inline int lengthNames() const { + return lengthNames_; + } +#ifndef CLP_NO_STD + /// length of names (0 means no names0 + inline void setLengthNames(int value) { + lengthNames_ = value; + } + /// Row names + inline const std::vector<std::string> * rowNames() const { + return &rowNames_; + } + inline const std::string& rowName(int iRow) const { + return rowNames_[iRow]; + } + /// Return name or Rnnnnnnn + std::string getRowName(int iRow) const; + /// Column names + inline const std::vector<std::string> * columnNames() const { + return &columnNames_; + } + inline const std::string& columnName(int iColumn) const { + return columnNames_[iColumn]; + } + /// Return name or Cnnnnnnn + std::string getColumnName(int iColumn) const; +#endif + /// Objective methods + inline ClpObjective * objectiveAsObject() const { + return objective_; + } + void setObjective(ClpObjective * objective); + inline void setObjectivePointer(ClpObjective * newobjective) { + objective_ = newobjective; + } + /** Solve a problem with no elements - return status and + dual and primal infeasibilites */ + int emptyProblem(int * infeasNumber = NULL, double * infeasSum = NULL, bool printMessage = true); + + //@} + + /**@name Matrix times vector methods + They can be faster if scalar is +- 1 + These are covers so user need not worry about scaling + Also for simplex I am not using basic/non-basic split */ + //@{ + /** Return <code>y + A * x * scalar</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + void times(double scalar, + const double * x, double * y) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + void transposeTimes(double scalar, + const double * x, double * y) const ; + //@} + + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + ** once it has been decided where solver sits this may be redone + */ + //@{ + /// Set an integer parameter + bool setIntParam(ClpIntParam key, int value) ; + /// Set an double parameter + bool setDblParam(ClpDblParam key, double value) ; +#ifndef CLP_NO_STD + /// Set an string parameter + bool setStrParam(ClpStrParam key, const std::string & value); +#endif + // Get an integer parameter + inline bool getIntParam(ClpIntParam key, int& value) const { + if (key < ClpLastIntParam) { + value = intParam_[key]; + return true; + } else { + return false; + } + } + // Get an double parameter + inline bool getDblParam(ClpDblParam key, double& value) const { + if (key < ClpLastDblParam) { + value = dblParam_[key]; + return true; + } else { + return false; + } + } +#ifndef CLP_NO_STD + // Get a string parameter + inline bool getStrParam(ClpStrParam key, std::string& value) const { + if (key < ClpLastStrParam) { + value = strParam_[key]; + return true; + } else { + return false; + } + } +#endif + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + /** For advanced options + 1 - Don't keep changing infeasibility weight + 2 - Keep nonLinearCost round solves + 4 - Force outgoing variables to exact bound (primal) + 8 - Safe to use dense initial factorization + 16 -Just use basic variables for operation if column generation + 32 -Create ray even in BAB + 64 -Treat problem as feasible until last minute (i.e. minimize infeasibilities) + 128 - Switch off all matrix sanity checks + 256 - No row copy + 512 - If not in values pass, solution guaranteed, skip as much as possible + 1024 - In branch and bound + 2048 - Don't bother to re-factorize if < 20 iterations + 4096 - Skip some optimality checks + 8192 - Do Primal when cleaning up primal + 16384 - In fast dual (so we can switch off things) + 32768 - called from Osi + 65536 - keep arrays around as much as possible (also use maximumR/C) + 131072 - transposeTimes is -1.0 and can skip basic and fixed + 262144 - extra copy of scaled matrix + 524288 - Clp fast dual + 1048576 - don't need to finish dual (can return 3) + 2097152 - zero costs! + 4194304 - don't scale integer variables + 8388608 - Idiot when not really sure about it + NOTE - many applications can call Clp but there may be some short cuts + which are taken which are not guaranteed safe from all applications. + Vetted applications will have a bit set and the code may test this + At present I expect a few such applications - if too many I will + have to re-think. It is up to application owner to change the code + if she/he needs these short cuts. I will not debug unless in Coin + repository. See COIN_CLP_VETTED comments. + 0x01000000 is Cbc (and in branch and bound) + 0x02000000 is in a different branch and bound + */ + inline unsigned int specialOptions() const { + return specialOptions_; + } + void setSpecialOptions(unsigned int value); +#define COIN_CBC_USING_CLP 0x01000000 + inline bool inCbcBranchAndBound() const { + return (specialOptions_ & COIN_CBC_USING_CLP) != 0; + } + //@} + + /**@name private or protected methods */ + //@{ +protected: + /// Does most of deletion (0 = all, 1 = most) + void gutsOfDelete(int type); + /** Does most of copying + If trueCopy 0 then just points to arrays + If -1 leaves as much as possible */ + void gutsOfCopy(const ClpModel & rhs, int trueCopy = 1); + /// gets lower and upper bounds on rows + void getRowBound(int iRow, double& lower, double& upper) const; + /// puts in format I like - 4 array matrix - may make row copy + void gutsOfLoadModel ( int numberRows, int numberColumns, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// Does much of scaling + void gutsOfScaling(); + /// Objective value - always minimize + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// If we are using maximumRows_ and Columns_ + inline bool permanentArrays() const { + return (specialOptions_ & 65536) != 0; + } + /// Start using maximumRows_ and Columns_ + void startPermanentArrays(); + /// Stop using maximumRows_ and Columns_ + void stopPermanentArrays(); + /// Create row names as char ** + const char * const * rowNamesAsChar() const; + /// Create column names as char ** + const char * const * columnNamesAsChar() const; + /// Delete char * version of names + void deleteNamesAsChar(const char * const * names, int number) const; + /// On stopped - sets secondary status + void onStopped(); + //@} + + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Array of double parameters + double dblParam_[ClpLastDblParam]; + /// Objective value + double objectiveValue_; + /// Small element value + double smallElement_; + /// Scaling of objective + double objectiveScale_; + /// Scaling of rhs and bounds + double rhsScale_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// Row activities + double * rowActivity_; + /// Column activities + double * columnActivity_; + /// Duals + double * dual_; + /// Reduced costs + double * reducedCost_; + /// Row lower + double* rowLower_; + /// Row upper + double* rowUpper_; + /// Objective + ClpObjective * objective_; + /// Row Objective (? sign) - may be NULL + double * rowObjective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Packed matrix + ClpMatrixBase * matrix_; + /// Row copy if wanted + ClpMatrixBase * rowCopy_; + /// Scaled packed matrix + ClpPackedMatrix * scaledMatrix_; + /// Infeasible/unbounded ray + double * ray_; + /// Row scale factors for matrix + double * rowScale_; + /// Column scale factors + double * columnScale_; + /// Inverse row scale factors for matrix (end of rowScale_) + double * inverseRowScale_; + /// Inverse column scale factors for matrix (end of columnScale_) + double * inverseColumnScale_; + /** Scale flag, 0 none, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic, + 5 geometric on rows */ + int scalingFlag_; + /** Status (i.e. basis) Region. I know that not all algorithms need a status + array, but it made sense for things like crossover and put + all permanent stuff in one place. No assumption is made + about what is in status array (although it might be good to reserve + bottom 3 bits (i.e. 0-7 numeric) for classic status). This + is number of columns + number of rows long (in that order). + */ + unsigned char * status_; + /// Integer information + char * integerType_; + /// User pointer for whatever reason + void * userPointer_; + /// Trusted user pointer e.g. for heuristics + ClpTrustedData * trustedUserPointer_; + /// Array of integer parameters + int intParam_[ClpLastIntParam]; + /// Number of iterations + int numberIterations_; + /** Solve type - 1 simplex, 2 simplex interface, 3 Interior.*/ + int solveType_; + /** Whats changed since last solve. This is a work in progress + It is designed so careful people can make go faster. + It is only used when startFinishOptions used in dual or primal. + Bit 1 - number of rows/columns has not changed (so work arrays valid) + 2 - matrix has not changed + 4 - if matrix has changed only by adding rows + 8 - if matrix has changed only by adding columns + 16 - row lbs not changed + 32 - row ubs not changed + 64 - column objective not changed + 128 - column lbs not changed + 256 - column ubs not changed + 512 - basis not changed (up to user to set this to 0) + top bits may be used internally + shift by 65336 is 3 all same, 1 all except col bounds + */ +#define ROW_COLUMN_COUNTS_SAME 1 +#define MATRIX_SAME 2 +#define MATRIX_JUST_ROWS_ADDED 4 +#define MATRIX_JUST_COLUMNS_ADDED 8 +#define ROW_LOWER_SAME 16 +#define ROW_UPPER_SAME 32 +#define OBJECTIVE_SAME 64 +#define COLUMN_LOWER_SAME 128 +#define COLUMN_UPPER_SAME 256 +#define BASIS_SAME 512 +#define ALL_SAME 65339 +#define ALL_SAME_EXCEPT_COLUMN_BOUNDS 65337 + unsigned int whatsChanged_; + /// Status of problem + int problemStatus_; + /// Secondary status of problem + int secondaryStatus_; + /// length of names (0 means no names) + int lengthNames_; + /// Number of threads (not very operational) + int numberThreads_; + /** For advanced options + See get and set for meaning + */ + unsigned int specialOptions_; + /// Message handler + CoinMessageHandler * handler_; + /// Flag to say if default handler (so delete) + bool defaultHandler_; + /// Thread specific random number generator + CoinThreadRandom randomNumberGenerator_; + /// Event handler + ClpEventHandler * eventHandler_; +#ifndef CLP_NO_STD + /// Row names + std::vector<std::string> rowNames_; + /// Column names + std::vector<std::string> columnNames_; +#endif + /// Messages + CoinMessages messages_; + /// Coin messages + CoinMessages coinMessages_; + /// Maximum number of columns in model + int maximumColumns_; + /// Maximum number of rows in model + int maximumRows_; + /// Maximum number of columns (internal arrays) in model + int maximumInternalColumns_; + /// Maximum number of rows (internal arrays) in model + int maximumInternalRows_; + /// Base packed matrix + CoinPackedMatrix baseMatrix_; + /// Base row copy + CoinPackedMatrix baseRowCopy_; + /// Saved row scale factors for matrix + double * savedRowScale_; + /// Saved column scale factors + double * savedColumnScale_; +#ifndef CLP_NO_STD + /// Array of string parameters + std::string strParam_[ClpLastStrParam]; +#endif + //@} +}; +/** This is a tiny class where data can be saved round calls. + */ +class ClpDataSave { + +public: + /**@name Constructors and destructor + */ + //@{ + /// Default constructor + ClpDataSave ( ); + + /// Copy constructor. + ClpDataSave(const ClpDataSave &); + /// Assignment operator. This copies the data + ClpDataSave & operator=(const ClpDataSave & rhs); + /// Destructor + ~ClpDataSave ( ); + + //@} + +////////////////// data ////////////////// +public: + + /**@name data - with same names as in other classes*/ + //@{ + double dualBound_; + double infeasibilityCost_; + double pivotTolerance_; + double zeroFactorizationTolerance_; + double zeroSimplexTolerance_; + double acceptablePivot_; + double objectiveScale_; + int sparseThreshold_; + int perturbation_; + int forceFactorization_; + int scalingFlag_; + unsigned int specialOptions_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpNetworkMatrix.hpp b/thirdparty/linux/include/coin1/ClpNetworkMatrix.hpp new file mode 100644 index 0000000..ec650a4 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpNetworkMatrix.hpp @@ -0,0 +1,229 @@ +/* $Id: ClpNetworkMatrix.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNetworkMatrix_H +#define ClpNetworkMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple network matrix as derived from ClpMatrixBase. + +If you want more sophisticated version then you could inherit from this. +Also you might want to allow networks with gain */ + +class ClpNetworkMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return true; + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return 2 * numberColumns_; + } + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed format + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const ; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + //@} + + /**@name Other */ + //@{ + /// Return true if really network, false if has slacks + inline bool trueNetwork() const { + return trueNetwork_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNetworkMatrix(); + /** Constructor from two arrays */ + ClpNetworkMatrix(int numberColumns, const int * head, + const int * tail); + /** Destructor */ + virtual ~ClpNetworkMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpNetworkMatrix(const ClpNetworkMatrix&); + /** The copy constructor from an CoinNetworkMatrix. */ + ClpNetworkMatrix(const CoinPackedMatrix&); + + ClpNetworkMatrix& operator=(const ClpNetworkMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpNetworkMatrix (const ClpNetworkMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; + /// True if all entries have two elements + bool trueNetwork_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpNode.hpp b/thirdparty/linux/include/coin1/ClpNode.hpp new file mode 100644 index 0000000..671d62f --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpNode.hpp @@ -0,0 +1,349 @@ +/* $Id: ClpNode.hpp 1910 2013-01-27 02:00:13Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNode_H +#define ClpNode_H + +#include "CoinPragma.hpp" + +// This implements all stuff for Clp fathom +/** This contains what is in a Clp "node" + + */ + +class ClpFactorization; +class ClpDualRowSteepest; +class ClpNodeStuff; +class ClpNode { + +public: + /**@name Useful methods */ + //@{ + /** Applies node to model + 0 - just tree bounds + 1 - tree bounds and basis etc + 2 - saved bounds and basis etc + */ + void applyNode(ClpSimplex * model, int doBoundsEtc ); + /// Choose a new variable + void chooseVariable(ClpSimplex * model, ClpNodeStuff * info); + /// Fix on reduced costs + int fixOnReducedCosts(ClpSimplex * model); + /// Create odd arrays + void createArrays(ClpSimplex * model); + /// Clean up as crunch is different model + void cleanUpForCrunch(); + //@} + + /**@name Gets and sets */ + //@{ + /// Objective value + inline double objectiveValue() const { + return objectiveValue_; + } + /// Set objective value + inline void setObjectiveValue(double value) { + objectiveValue_ = value; + } + /// Primal solution + inline const double * primalSolution() const { + return primalSolution_; + } + /// Dual solution + inline const double * dualSolution() const { + return dualSolution_; + } + /// Initial value of integer variable + inline double branchingValue() const { + return branchingValue_; + } + /// Sum infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Number infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Relative depth + inline int depth() const { + return depth_; + } + /// Estimated solution value + inline double estimatedSolution() const { + return estimatedSolution_; + } + /** Way for integer variable -1 down , +1 up */ + int way() const; + /// Return true if branch exhausted + bool fathomed() const; + /// Change state of variable i.e. go other way + void changeState(); + /// Sequence number of integer variable (-1 if none) + inline int sequence() const { + return sequence_; + } + /// If odd arrays exist + inline bool oddArraysExist() const { + return lower_ != NULL; + } + /// Status array + inline const unsigned char * statusArray() const { + return status_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNode(); + /// Constructor from model + ClpNode (ClpSimplex * model, const ClpNodeStuff * stuff, int depth); + /// Does work of constructor (partly so gdb will work) + void gutsOfConstructor(ClpSimplex * model, const ClpNodeStuff * stuff, + int arraysExist, int depth); + /** Destructor */ + virtual ~ClpNode(); + //@} + + /**@name Copy methods (at present illegal - will abort) */ + //@{ + /** The copy constructor. */ + ClpNode(const ClpNode&); + /// Operator = + ClpNode& operator=(const ClpNode&); + //@} + +protected: +// For state of branch + typedef struct { + unsigned int firstBranch: 1; // nonzero if first branch on variable is up + unsigned int branch: 2; // 0 means do first branch next, 1 second, 2 finished + unsigned int spare: 29; + } branchState; + /**@name Data */ + //@{ + /// Initial value of integer variable + double branchingValue_; + /// Value of objective + double objectiveValue_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Estimated solution value + double estimatedSolution_; + /// Factorization + ClpFactorization * factorization_; + /// Steepest edge weights + ClpDualRowSteepest * weights_; + /// Status vector + unsigned char * status_; + /// Primal solution + double * primalSolution_; + /// Dual solution + double * dualSolution_; + /// Integer lower bounds (only used in fathomMany) + int * lower_; + /// Integer upper bounds (only used in fathomMany) + int * upper_; + /// Pivot variables for factorization + int * pivotVariables_; + /// Variables fixed by reduced costs (at end of branch) 0x10000000 added if fixed to UB + int * fixed_; + /// State of branch + branchState branchState_; + /// Sequence number of integer variable (-1 if none) + int sequence_; + /// Number of infeasibilities + int numberInfeasibilities_; + /// Relative depth + int depth_; + /// Number fixed by reduced cost + int numberFixed_; + /// Flags - 1 duals scaled + int flags_; + /// Maximum number fixed by reduced cost + int maximumFixed_; + /// Maximum rows so far + int maximumRows_; + /// Maximum columns so far + int maximumColumns_; + /// Maximum Integers so far + int maximumIntegers_; + //@} +}; +class ClpNodeStuff { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpNodeStuff(); + /** Destructor */ + virtual ~ClpNodeStuff(); + //@} + + /**@name Copy methods (only copies ints etc, nulls arrays) */ + //@{ + /** The copy constructor. */ + ClpNodeStuff(const ClpNodeStuff&); + /// Operator = + ClpNodeStuff& operator=(const ClpNodeStuff&); + /// Zaps stuff 1 - arrays, 2 ints, 3 both + void zap(int type); + //@} + + + /**@name Fill methods */ + //@{ + /** Fill with pseudocosts */ + void fillPseudoCosts(const double * down, const double * up, + const int * priority, + const int * numberDown, const int * numberUp, + const int * numberDownInfeasible, const int * numberUpInfeasible, + int number); + /// Update pseudo costs + void update(int way, int sequence, double change, bool feasible); + /// Return maximum number of nodes + int maximumNodes() const; + /// Return maximum space for nodes + int maximumSpace() const; + //@} + +public: + /**@name Data */ + //@{ + /// Integer tolerance + double integerTolerance_; + /// Integer increment + double integerIncrement_; + /// Small change in branch + double smallChange_; + /// Down pseudo costs + double * downPseudo_; + /// Up pseudo costs + double * upPseudo_; + /// Priority + int * priority_; + /// Number of times down + int * numberDown_; + /// Number of times up + int * numberUp_; + /// Number of times down infeasible + int * numberDownInfeasible_; + /// Number of times up infeasible + int * numberUpInfeasible_; + /// Copy of costs (local) + double * saveCosts_; + /// Array of ClpNodes + ClpNode ** nodeInfo_; + /// Large model if crunched + ClpSimplex * large_; + /// Which rows in large model + int * whichRow_; + /// Which columns in large model + int * whichColumn_; +#ifndef NO_FATHOM_PRINT + /// Cbc's message handler + CoinMessageHandler * handler_; +#endif + /// Number bounds in large model + int nBound_; + /// Save of specialOptions_ (local) + int saveOptions_; + /** Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + 32 - just create up to nDepth_+1 nodes + 65536 - set if activated + */ + int solverOptions_; + /// Maximum number of nodes to do + int maximumNodes_; + /// Number before trust from CbcModel + int numberBeforeTrust_; + /// State of search from CbcModel + int stateOfSearch_; + /// Number deep + int nDepth_; + /// Number nodes returned (-1 if fathom aborted) + int nNodes_; + /// Number of nodes explored + int numberNodesExplored_; + /// Number of iterations + int numberIterations_; + /// Type of presolve - 0 none, 1 crunch + int presolveType_; +#ifndef NO_FATHOM_PRINT + /// Depth passed in + int startingDepth_; + /// Node at which called + int nodeCalled_; +#endif + //@} +}; +class ClpHashValue { + +public: + /**@name Useful methods */ + //@{ + /// Return index or -1 if not found + int index(double value) const; + /// Add value to list and return index + int addValue(double value) ; + /// Number of different entries + inline int numberEntries() const { + return numberHash_; + } + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpHashValue(); + /** Useful constructor. */ + ClpHashValue(ClpSimplex * model); + /** Destructor */ + virtual ~ClpHashValue(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpHashValue(const ClpHashValue&); + /// = + ClpHashValue& operator=(const ClpHashValue&); + //@} +private: + /**@name private stuff */ + //@{ + /** returns hash */ + int hash(double value) const; + /// Resizes + void resize(bool increaseMax); + //@} + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + // for hashing + typedef struct { + double value; + int index, next; + } CoinHashLink; + /// Hash table + mutable CoinHashLink *hash_; + /// Number of entries in hash table + int numberHash_; + /// Maximum number of entries in hash table i.e. size + int maxHash_; + /// Last used space + int lastUsed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/ClpNonLinearCost.hpp b/thirdparty/linux/include/coin1/ClpNonLinearCost.hpp new file mode 100644 index 0000000..1007865 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpNonLinearCost.hpp @@ -0,0 +1,401 @@ +/* $Id: ClpNonLinearCost.hpp 1769 2011-07-26 09:31:51Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpNonLinearCost_H +#define ClpNonLinearCost_H + + +#include "CoinPragma.hpp" + +class ClpSimplex; +class CoinIndexedVector; + +/** Trivial class to deal with non linear costs + + I don't make any explicit assumptions about convexity but I am + sure I do make implicit ones. + + One interesting idea for normal LP's will be to allow non-basic + variables to come into basis as infeasible i.e. if variable at + lower bound has very large positive reduced cost (when problem + is infeasible) could it reduce overall problem infeasibility more + by bringing it into basis below its lower bound. + + Another feature would be to automatically discover when problems + are convex piecewise linear and re-formulate to use non-linear. + I did some work on this many years ago on "grade" problems, but + while it improved primal interior point algorithms were much better + for that particular problem. +*/ +/* status has original status and current status + 0 - below lower so stored is upper + 1 - in range + 2 - above upper so stored is lower + 4 - (for current) - same as original +*/ +#define CLP_BELOW_LOWER 0 +#define CLP_FEASIBLE 1 +#define CLP_ABOVE_UPPER 2 +#define CLP_SAME 4 +inline int originalStatus(unsigned char status) +{ + return (status & 15); +} +inline int currentStatus(unsigned char status) +{ + return (status >> 4); +} +inline void setOriginalStatus(unsigned char & status, int value) +{ + status = static_cast<unsigned char>(status & ~15); + status = static_cast<unsigned char>(status | value); +} +inline void setCurrentStatus(unsigned char &status, int value) +{ + status = static_cast<unsigned char>(status & ~(15 << 4)); + status = static_cast<unsigned char>(status | (value << 4)); +} +inline void setInitialStatus(unsigned char &status) +{ + status = static_cast<unsigned char>(CLP_FEASIBLE | (CLP_SAME << 4)); +} +inline void setSameStatus(unsigned char &status) +{ + status = static_cast<unsigned char>(status & ~(15 << 4)); + status = static_cast<unsigned char>(status | (CLP_SAME << 4)); +} +// Use second version to get more speed +//#define FAST_CLPNON +#ifndef FAST_CLPNON +#define CLP_METHOD1 ((method_&1)!=0) +#define CLP_METHOD2 ((method_&2)!=0) +#else +#define CLP_METHOD1 (false) +#define CLP_METHOD2 (true) +#endif +class ClpNonLinearCost { + +public: + +public: + + /**@name Constructors, destructor */ + //@{ + /// Default constructor. + ClpNonLinearCost(); + /** Constructor from simplex. + This will just set up wasteful arrays for linear, but + later may do dual analysis and even finding duplicate columns . + */ + ClpNonLinearCost(ClpSimplex * model, int method = 1); + /** Constructor from simplex and list of non-linearities (columns only) + First lower of each column has to match real lower + Last lower has to be <= upper (if == then cost ignored) + This could obviously be changed to make more user friendly + */ + ClpNonLinearCost(ClpSimplex * model, const int * starts, + const double * lower, const double * cost); + /// Destructor + ~ClpNonLinearCost(); + // Copy + ClpNonLinearCost(const ClpNonLinearCost&); + // Assignment + ClpNonLinearCost& operator=(const ClpNonLinearCost&); + //@} + + + /**@name Actual work in primal */ + //@{ + /** Changes infeasible costs and computes number and cost of infeas + Puts all non-basic (non free) variables to bounds + and all free variables to zero if oldTolerance is non-zero + - but does not move those <= oldTolerance away*/ + void checkInfeasibilities(double oldTolerance = 0.0); + /** Changes infeasible costs for each variable + The indices are row indices and need converting to sequences + */ + void checkInfeasibilities(int numberInArray, const int * index); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + On input array is empty (but indices exist). On exit just + changed costs will be stored as normal CoinIndexedVector + */ + void checkChanged(int numberInArray, CoinIndexedVector * update); + /** Goes through one bound for each variable. + If multiplier*work[iRow]>0 goes down, otherwise up. + The indices are row indices and need converting to sequences + Temporary offsets may be set + Rhs entries are increased + */ + void goThru(int numberInArray, double multiplier, + const int * index, const double * work, + double * rhs); + /** Takes off last iteration (i.e. offsets closer to 0) + */ + void goBack(int numberInArray, const int * index, + double * rhs); + /** Puts back correct infeasible costs for each variable + The input indices are row indices and need converting to sequences + for costs. + At the end of this all temporary offsets are zero + */ + void goBackAll(const CoinIndexedVector * update); + /// Temporary zeroing of feasible costs + void zapCosts(); + /// Refreshes costs always makes row costs zero + void refreshCosts(const double * columnCosts); + /// Puts feasible bounds into lower and upper + void feasibleBounds(); + /// Refresh - assuming regions OK + void refresh(); + /** Sets bounds and cost for one variable + Returns change in cost + May need to be inline for speed */ + double setOne(int sequence, double solutionValue); + /** Sets bounds and infeasible cost and true cost for one variable + This is for gub and column generation etc */ + void setOne(int sequence, double solutionValue, double lowerValue, double upperValue, + double costValue = 0.0); + /** Sets bounds and cost for outgoing variable + may change value + Returns direction */ + int setOneOutgoing(int sequence, double &solutionValue); + /// Returns nearest bound + double nearest(int sequence, double solutionValue); + /** Returns change in cost - one down if alpha >0.0, up if <0.0 + Value is current - new + */ + inline double changeInCost(int sequence, double alpha) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = cost_[iRange] - cost_[iRange+1]; + } + if (CLP_METHOD2) { + returnValue = (alpha > 0.0) ? infeasibilityWeight_ : -infeasibilityWeight_; + } + return returnValue; + } + inline double changeUpInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange + 1 != start_[sequence+1] && !infeasible(iRange + 1)) + returnValue = cost_[iRange] - cost_[iRange+1]; + else + returnValue = -1.0e100; + } + if (CLP_METHOD2) { + returnValue = -infeasibilityWeight_; + } + return returnValue; + } + inline double changeDownInCost(int sequence) const { + double returnValue = 0.0; + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (iRange != start_[sequence] && !infeasible(iRange - 1)) + returnValue = cost_[iRange] - cost_[iRange-1]; + else + returnValue = 1.0e100; + } + if (CLP_METHOD2) { + returnValue = infeasibilityWeight_; + } + return returnValue; + } + /// This also updates next bound + inline double changeInCost(int sequence, double alpha, double &rhs) { + double returnValue = 0.0; +#ifdef NONLIN_DEBUG + double saveRhs = rhs; +#endif + if (CLP_METHOD1) { + int iRange = whichRange_[sequence] + offset_[sequence]; + if (alpha > 0.0) { + assert(iRange - 1 >= start_[sequence]); + offset_[sequence]--; + rhs += lower_[iRange] - lower_[iRange-1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange-1]); + } else { + assert(iRange + 1 < start_[sequence+1] - 1); + offset_[sequence]++; + rhs += lower_[iRange+2] - lower_[iRange+1]; + returnValue = alpha * (cost_[iRange] - cost_[iRange+1]); + } + } + if (CLP_METHOD2) { +#ifdef NONLIN_DEBUG + double saveRhs1 = rhs; + rhs = saveRhs; +#endif + unsigned char iStatus = status_[sequence]; + int iWhere = currentStatus(iStatus); + if (iWhere == CLP_SAME) + iWhere = originalStatus(iStatus); + // rhs always increases + if (iWhere == CLP_FEASIBLE) { + if (alpha > 0.0) { + // going below + iWhere = CLP_BELOW_LOWER; + rhs = COIN_DBL_MAX; + } else { + // going above + iWhere = CLP_ABOVE_UPPER; + rhs = COIN_DBL_MAX; + } + } else if (iWhere == CLP_BELOW_LOWER) { + assert (alpha < 0); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += bound_[sequence] - model_->upperRegion()[sequence]; + } else { + assert (iWhere == CLP_ABOVE_UPPER); + // going feasible + iWhere = CLP_FEASIBLE; + rhs += model_->lowerRegion()[sequence] - bound_[sequence]; + } + setCurrentStatus(status_[sequence], iWhere); +#ifdef NONLIN_DEBUG + assert(saveRhs1 == rhs); +#endif + returnValue = fabs(alpha) * infeasibilityWeight_; + } + return returnValue; + } + /// Returns current lower bound + inline double lower(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence]]; + } + /// Returns current upper bound + inline double upper(int sequence) const { + return lower_[whichRange_[sequence] + offset_[sequence] + 1]; + } + /// Returns current cost + inline double cost(int sequence) const { + return cost_[whichRange_[sequence] + offset_[sequence]]; + } + //@} + + + /**@name Gets and sets */ + //@{ + /// Number of infeasibilities + inline int numberInfeasibilities() const { + return numberInfeasibilities_; + } + /// Change in cost + inline double changeInCost() const { + return changeCost_; + } + /// Feasible cost + inline double feasibleCost() const { + return feasibleCost_; + } + /// Feasible cost with offset and direction (i.e. for reporting) + double feasibleReportCost() const; + /// Sum of infeasibilities + inline double sumInfeasibilities() const { + return sumInfeasibilities_; + } + /// Largest infeasibility + inline double largestInfeasibility() const { + return largestInfeasibility_; + } + /// Average theta + inline double averageTheta() const { + return averageTheta_; + } + inline void setAverageTheta(double value) { + averageTheta_ = value; + } + inline void setChangeInCost(double value) { + changeCost_ = value; + } + inline void setMethod(int value) { + method_ = value; + } + /// See if may want to look both ways + inline bool lookBothWays() const { + return bothWays_; + } + //@} + ///@name Private functions to deal with infeasible regions + inline bool infeasible(int i) const { + return ((infeasible_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setInfeasible(int i, bool trueFalse) { + unsigned int & value = infeasible_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + inline unsigned char * statusArray() const { + return status_; + } + /// For debug + void validate(); + //@} + +private: + /**@name Data members */ + //@{ + /// Change in cost because of infeasibilities + double changeCost_; + /// Feasible cost + double feasibleCost_; + /// Current infeasibility weight + double infeasibilityWeight_; + /// Largest infeasibility + double largestInfeasibility_; + /// Sum of infeasibilities + double sumInfeasibilities_; + /// Average theta - kept here as only for primal + double averageTheta_; + /// Number of rows (mainly for checking and copy) + int numberRows_; + /// Number of columns (mainly for checking and copy) + int numberColumns_; + /// Starts for each entry (columns then rows) + int * start_; + /// Range for each entry (columns then rows) + int * whichRange_; + /// Temporary range offset for each entry (columns then rows) + int * offset_; + /** Lower bound for each range (upper bound is next lower). + For various reasons there is always an infeasible range + at bottom - even if lower bound is - infinity */ + double * lower_; + /// Cost for each range + double * cost_; + /// Model + ClpSimplex * model_; + // Array to say which regions are infeasible + unsigned int * infeasible_; + /// Number of infeasibilities found + int numberInfeasibilities_; + // new stuff + /// Contains status at beginning and current + unsigned char * status_; + /// Bound which has been replaced in lower_ or upper_ + double * bound_; + /// Feasible cost array + double * cost2_; + /// Method 1 old, 2 new, 3 both! + int method_; + /// If all non-linear costs convex + bool convex_; + /// If we should look both ways for djs + bool bothWays_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpObjective.hpp b/thirdparty/linux/include/coin1/ClpObjective.hpp new file mode 100644 index 0000000..f98903a --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpObjective.hpp @@ -0,0 +1,134 @@ +/* $Id: ClpObjective.hpp 1825 2011-11-20 16:02:57Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpObjective_H +#define ClpObjective_H + + +//############################################################################# +class ClpSimplex; +class ClpModel; + +/** Objective Abstract Base Class + +Abstract Base Class for describing an objective function + +*/ +class ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Linear then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, + double & offset, bool refresh, + int includeLinear = 2) = 0; + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts) = 0; + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj) = 0; + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const = 0; + /// Resize objective + virtual void resize(int newNumberColumns) = 0; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) = 0; + /// Scale objective + virtual void reallyScale(const double * columnScale) = 0; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + /// Say we have new primal solution - so may need to recompute + virtual void newXValues() {} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpObjective(); + + /// Copy constructor + ClpObjective(const ClpObjective &); + + /// Assignment operator + ClpObjective & operator=(const ClpObjective& rhs); + + /// Destructor + virtual ~ClpObjective (); + + /// Clone + virtual ClpObjective * clone() const = 0; + /** Subset clone. Duplicates are allowed + and order is as given. + Derived classes need not provide this as it may not always make + sense */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + //@} + + ///@name Other + //@{ + /// Returns type (above 63 is extra information) + inline int type() const { + return type_; + } + /// Sets type (above 63 is extra information) + inline void setType(int value) { + type_ = value; + } + /// Whether activated + inline int activated() const { + return activated_; + } + /// Set whether activated + inline void setActivated(int value) { + activated_ = value; + } + + /// Objective offset + inline double nonlinearOffset () const { + return offset_; + } + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Value of non-linear part of objective + double offset_; + /// Type of objective - linear is 1 + int type_; + /// Whether activated + int activated_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpPackedMatrix.hpp b/thirdparty/linux/include/coin1/ClpPackedMatrix.hpp new file mode 100644 index 0000000..ec0c0b9 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPackedMatrix.hpp @@ -0,0 +1,638 @@ +/* $Id: ClpPackedMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPackedMatrix_H +#define ClpPackedMatrix_H + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements CoinPackedMatrix as derived from ClpMatrixBase. + + It adds a few methods that know about model as well as matrix + + For details see CoinPackedMatrix */ + +class ClpPackedMatrix2; +class ClpPackedMatrix3; +class ClpPackedMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const { + return matrix_; + } + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const { + return matrix_->isColOrdered(); + } + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const { + return matrix_->getNumElements(); + } + /** Number of columns. */ + virtual int getNumCols() const { + return matrix_->getNumCols(); + } + /** Number of rows. */ + virtual int getNumRows() const { + return matrix_->getNumRows(); + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const { + return matrix_->getElements(); + } + /// Mutable elements + inline double * getMutableElements() const { + return matrix_->getMutableElements(); + } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return matrix_->getIndices(); + } + + virtual const CoinBigIndex * getVectorStarts() const { + return matrix_->getVectorStarts(); + } + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const { + return matrix_->getVectorLengths(); + } + /** The length of a single major-dimension vector. */ + virtual int getVectorLength(int index) const { + return matrix_->getVectorSize(index); + } + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); +#ifndef CLP_NO_VECTOR + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#endif + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); + /** Replace the elements of a vector. The indices remain the same. + This is only needed if scaling and a row copy is used. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + virtual void replaceVector(const int index, + const int numReplace, const double * newElements) { + matrix_->replaceVector(index, numReplace, newElements); + } + /** Modify one element of packed matrix. An element may be added. + This works for either ordering If the new element is zero it will be + deleted unless keepZero true */ + virtual void modifyCoefficient(int row, int column, double newElement, + bool keepZero = false) { + matrix_->modifyCoefficient(row, column, newElement, keepZero); + } + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis(const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Creates scales for column copy (rowCopy in model may be modified) + returns non-zero if no scaling done */ + virtual int scale(ClpModel * model, const ClpSimplex * baseModel = NULL) const ; + /** Scales rowCopy if column copy scaled + Only called if scales already exist */ + virtual void scaleRowCopy(ClpModel * model) const ; + /// Creates scaled column copy if scales exist + void createScaledMatrix(ClpSimplex * model) const; + /** Realy really scales column copy + Only called if scales already exist. + Up to user ro delete */ + virtual ClpMatrixBase * scaledColumnCopy(ClpModel * model) const ; + /** Checks if all elements are in valid range. Can just + return true if you are not paranoid. For Clp I will + probably expect no zeros. Code can modify matrix to get rid of + small elements. + check bits (can be turned off to save time) : + 1 - check if matrix has gaps + 2 - check if zero elements + 4 - check and compress duplicates + 8 - report on large and small + */ + virtual bool allElementsInRange(ClpModel * model, + double smallest, double largest, + int check = 15); + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinPackedMatrix to be deleted + virtual void releasePackedMatrix() const { } + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + /// makes sure active columns correct + virtual int refresh(ClpSimplex * model); + // Really scale matrix + virtual void reallyScale(const double * rowScale, const double * columnScale); + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return <code>y - pi * A</code> in <code>y</code>. + @pre <code>pi</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> + This just does subset (but puts in correct place in y) */ + void transposeTimesSubset( int number, + const int * which, + const double * pi, double * y, + const double * rowScale, + const double * columnScale, + double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Note - If x packed mode - then z packed mode + This does by column and knows no gaps + Squashes small elements and knows about ClpSimplex */ + void transposeTimesByColumn(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Sets up an effective RHS + void useEffectiveRhs(ClpSimplex * model); +#if COIN_LONG_WORK + // For long double versions + virtual void times(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; + virtual void transposeTimes(CoinWorkDouble scalar, + const CoinWorkDouble * x, CoinWorkDouble * y) const ; +#endif +//@} + + /**@name Other */ + //@{ + /// Returns CoinPackedMatrix (non const) + inline CoinPackedMatrix * matrix() const { + return matrix_; + } + /** Just sets matrix_ to NULL so it can be used elsewhere. + used in GUB + */ + inline void setMatrixNull() { + matrix_ = NULL; + } + /// Say we want special column copy + inline void makeSpecialColumnCopy() { + flags_ |= 16; + } + /// Say we don't want special column copy + void releaseSpecialColumnCopy(); + /// Are there zeros? + inline bool zeros() const { + return ((flags_ & 1) != 0); + } + /// Do we want special column copy + inline bool wantsSpecialColumnCopy() const { + return ((flags_ & 16) != 0); + } + /// Flags + inline int flags() const { + return flags_; + } + /// Sets flags_ correctly + inline void checkGaps() { + flags_ = (matrix_->hasGaps()) ? (flags_ | 2) : (flags_ & (~2)); + } + /// number of active columns (normally same as number of columns) + inline int numberActiveColumns() const + { return numberActiveColumns_;} + /// Set number of active columns (normally same as number of columns) + inline void setNumberActiveColumns(int value) + { numberActiveColumns_ = value;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix(); + /** Destructor */ + virtual ~ClpPackedMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix(const ClpPackedMatrix&); + /** The copy constructor from an CoinPackedMatrix. */ + ClpPackedMatrix(const CoinPackedMatrix&); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPackedMatrix (const ClpPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + ClpPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /** This takes over ownership (for space reasons) */ + ClpPackedMatrix(CoinPackedMatrix * matrix); + + ClpPackedMatrix& operator=(const ClpPackedMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /// Copy contents - resizing if necessary - otherwise re-use memory + virtual void copy(const ClpPackedMatrix * from); + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// make special row copy + void specialRowCopy(ClpSimplex * model, const ClpMatrixBase * rowCopy); + /// make special column copy + void specialColumnCopy(ClpSimplex * model); + /// Correct sequence in and out to give true value + virtual void correctSequence(const ClpSimplex * model, int & sequenceIn, int & sequenceOut) ; + //@} +private: + /// Meat of transposeTimes by column when not scaled + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when scaled + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const double tolerance) const; + /// Meat of transposeTimes by column when not scaled and skipping + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /** Meat of transposeTimes by column when not scaled and skipping + and doing part of dualColumn */ + int gutsOfTransposeTimesUnscaled(const double * COIN_RESTRICT pi, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + int * COIN_RESTRICT spareIndex, + double * COIN_RESTRICT spareArray, + const double * COIN_RESTRICT reducedCost, + double & upperTheta, + double & bestPossible, + double acceptablePivot, + double dualTolerance, + int & numberRemaining, + const double zeroTolerance) const; + /// Meat of transposeTimes by column when scaled and skipping + int gutsOfTransposeTimesScaled(const double * COIN_RESTRICT pi, + const double * COIN_RESTRICT columnScale, + int * COIN_RESTRICT index, + double * COIN_RESTRICT array, + const unsigned char * status, + const double tolerance) const; + /// Meat of transposeTimes by row n > K if packed - returns number nonzero + int gutsOfTransposeTimesByRowGEK(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int numberColumns, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + double * COIN_RESTRICT array2, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n > 2 if packed - returns number nonzero + int gutsOfTransposeTimesByRowGE3a(const CoinIndexedVector * COIN_RESTRICT piVector, + int * COIN_RESTRICT index, + double * COIN_RESTRICT output, + int * COIN_RESTRICT lookup, + char * COIN_RESTRICT marked, + const double tolerance, + const double scalar) const; + /// Meat of transposeTimes by row n == 2 if packed + void gutsOfTransposeTimesByRowEQ2(const CoinIndexedVector * piVector, CoinIndexedVector * output, + CoinIndexedVector * spareVector, const double tolerance, const double scalar) const; + /// Meat of transposeTimes by row n == 1 if packed + void gutsOfTransposeTimesByRowEQ1(const CoinIndexedVector * piVector, CoinIndexedVector * output, + const double tolerance, const double scalar) const; + /// Gets rid of special copies + void clearCopies(); + + +protected: + /// Check validity + void checkFlags(int type) const; + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Data + CoinPackedMatrix * matrix_; + /// number of active columns (normally same as number of columns) + int numberActiveColumns_; + /** Flags - + 1 - has zero elements + 2 - has gaps + 4 - has special row copy + 8 - has special column copy + 16 - wants special column copy + */ + mutable int flags_; + /// Special row copy + ClpPackedMatrix2 * rowCopy_; + /// Special column copy + ClpPackedMatrix3 * columnCopy_; + //@} +}; +#ifdef THREAD +#include <pthread.h> +typedef struct { + double acceptablePivot; + const ClpSimplex * model; + double * spare; + int * spareIndex; + double * arrayTemp; + int * indexTemp; + int * numberInPtr; + double * bestPossiblePtr; + double * upperThetaPtr; + int * posFreePtr; + double * freePivotPtr; + int * numberOutPtr; + const unsigned short * count; + const double * pi; + const CoinBigIndex * rowStart; + const double * element; + const unsigned short * column; + int offset; + int numberInRowArray; + int numberLook; +} dualColumn0Struct; +#endif +class ClpPackedMatrix2 { + +public: + /**@name Useful methods */ + //@{ + /** Return <code>x * -1 * A in <code>z</code>. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const CoinPackedMatrix * rowCopy, + const CoinIndexedVector * x, + CoinIndexedVector * spareArray, + CoinIndexedVector * z) const; + /// Returns true if copy has useful information + inline bool usefulInfo() const { + return rowStart_ != NULL; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix2(); + /** Constructor from copy. */ + ClpPackedMatrix2(ClpSimplex * model, const CoinPackedMatrix * rowCopy); + /** Destructor */ + virtual ~ClpPackedMatrix2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix2(const ClpPackedMatrix2&); + ClpPackedMatrix2& operator=(const ClpPackedMatrix2&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of rows + int numberRows_; + /// Column offset for each block (plus one at end) + int * offset_; + /// Counts of elements in each part of row + mutable unsigned short * count_; + /// Row starts + mutable CoinBigIndex * rowStart_; + /// columns within block + unsigned short * column_; + /// work arrays + double * work_; +#ifdef THREAD + pthread_t * threadId_; + dualColumn0Struct * info_; +#endif + //@} +}; +typedef struct { + CoinBigIndex startElements_; // point to data + int startIndices_; // point to column_ + int numberInBlock_; + int numberPrice_; // at beginning + int numberElements_; // number elements per column +} blockStruct; +class ClpPackedMatrix3 { + +public: + /**@name Useful methods */ + //@{ + /** Return <code>x * -1 * A in <code>z</code>. + Note - x packed and z will be packed mode + Squashes small elements and knows about ClpSimplex */ + void transposeTimes(const ClpSimplex * model, + const double * pi, + CoinIndexedVector * output) const; + /// Updates two arrays for steepest + void transposeTimes2(const ClpSimplex * model, + const double * pi, CoinIndexedVector * dj1, + const double * piWeight, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPackedMatrix3(); + /** Constructor from copy. */ + ClpPackedMatrix3(ClpSimplex * model, const CoinPackedMatrix * columnCopy); + /** Destructor */ + virtual ~ClpPackedMatrix3(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPackedMatrix3(const ClpPackedMatrix3&); + ClpPackedMatrix3& operator=(const ClpPackedMatrix3&); + //@} + /**@name Sort methods */ + //@{ + /** Sort blocks */ + void sortBlocks(const ClpSimplex * model); + /// Swap one variable + void swapOne(const ClpSimplex * model, const ClpPackedMatrix * matrix, + int iColumn); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Number of blocks + int numberBlocks_; + /// Number of columns + int numberColumns_; + /// Column indices and reverse lookup (within block) + int * column_; + /// Starts for odd/long vectors + CoinBigIndex * start_; + /// Rows + int * row_; + /// Elements + double * element_; + /// Blocks (ordinary start at 0 and go to first block) + blockStruct * block_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpParameters.hpp b/thirdparty/linux/include/coin1/ClpParameters.hpp new file mode 100644 index 0000000..7252d2b --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpParameters.hpp @@ -0,0 +1,126 @@ +/* $Id: ClpParameters.hpp 2046 2014-08-14 04:13:10Z tkr $ */ +// Copyright (C) 2000, 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _ClpParameters_H +#define _ClpParameters_H + +/** This is where to put any useful stuff. + +*/ +enum ClpIntParam { + /** The maximum number of iterations Clp can execute in the simplex methods + */ + ClpMaxNumIteration = 0, + /** The maximum number of iterations Clp can execute in hotstart before + terminating */ + ClpMaxNumIterationHotStart, + /** The name discipline; specifies how the solver will handle row and + column names. + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + ClpNameDiscipline, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastIntParam +}; + +enum ClpDblParam { + /** Set Dual objective limit. This is to be used as a termination criteria + in methods where the dual objective monotonically changes (dual + simplex). */ + ClpDualObjectiveLimit, + /** Primal objective limit. This is to be used as a termination + criteria in methods where the primal objective monotonically changes + (e.g., primal simplex) */ + ClpPrimalObjectiveLimit, + /** The maximum amount the dual constraints can be violated and still be + considered feasible. */ + ClpDualTolerance, + /** The maximum amount the primal constraints can be violated and still be + considered feasible. */ + ClpPrimalTolerance, + /** Objective function constant. This the value of the constant term in + the objective function. */ + ClpObjOffset, + /// Maximum time in seconds - after, this action is as max iterations + ClpMaxSeconds, + /// Maximum wallclock running time in seconds - after, this action is as max iterations + ClpMaxWallSeconds, + /// Tolerance to use in presolve + ClpPresolveTolerance, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastDblParam +}; + + +enum ClpStrParam { + /** Name of the problem. This is the found on the Name card of + an mps file. */ + ClpProbName = 0, + /** Just a marker, so that we can allocate a static sized array to store + parameters. */ + ClpLastStrParam +}; + +/// Copy (I don't like complexity of Coin version) +template <class T> inline void +ClpDisjointCopyN( const T * array, const int size, T * newArray) +{ + memcpy(reinterpret_cast<void *> (newArray), array, size * sizeof(T)); +} +/// And set +template <class T> inline void +ClpFillN( T * array, const int size, T value) +{ + int i; + for (i = 0; i < size; i++) + array[i] = value; +} +/// This returns a non const array filled with input from scalar or actual array +template <class T> inline T* +ClpCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) + ClpDisjointCopyN(array, size, arrayNew); + else + ClpFillN ( arrayNew, size, value); + return arrayNew; +} + +/// This returns a non const array filled with actual array (or NULL) +template <class T> inline T* +ClpCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + ClpDisjointCopyN(array, size, arrayNew); + return arrayNew; + } else { + return NULL; + } +} +/// For a structure to be used by trusted code +typedef struct { + int typeStruct; // allocated as 1,2 etc + int typeCall; + void * data; +} ClpTrustedData; +#endif diff --git a/thirdparty/linux/include/coin1/ClpPdcoBase.hpp b/thirdparty/linux/include/coin1/ClpPdcoBase.hpp new file mode 100644 index 0000000..cb8fd8f --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPdcoBase.hpp @@ -0,0 +1,103 @@ +/* $Id: ClpPdcoBase.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPdcoBase_H +#define ClpPdcoBase_H + +#include "CoinPragma.hpp" + +#include "CoinPackedMatrix.hpp" +#include "CoinDenseVector.hpp" +class ClpInterior; + +/** Abstract base class for tailoring everything for Pcdo + + Since this class is abstract, no object of this type can be created. + + If a derived class provides all methods then all ClpPcdo algorithms + should work. + + Eventually we should be able to use ClpObjective and ClpMatrixBase. +*/ + +class ClpPdcoBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + virtual void matVecMult(ClpInterior * model, int mode, double * x, double * y) const = 0; + + virtual void getGrad(ClpInterior * model, CoinDenseVector<double> &x, CoinDenseVector<double> &grad) const = 0; + + virtual void getHessian(ClpInterior * model, CoinDenseVector<double> &x, CoinDenseVector<double> &H) const = 0; + + virtual double getObj(ClpInterior * model, CoinDenseVector<double> &x) const = 0; + + virtual void matPrecon(ClpInterior * model, double delta, double * x, double * y) const = 0; + + //@} + //@{ + ///@name Other + /// Clone + virtual ClpPdcoBase * clone() const = 0; + /// Returns type + inline int type() const { + return type_; + }; + /// Sets type + inline void setType(int type) { + type_ = type; + }; + /// Returns size of d1 + inline int sizeD1() const { + return 1; + }; + /// Returns d1 as scalar + inline double getD1() const { + return d1_; + }; + /// Returns size of d2 + inline int sizeD2() const { + return 1; + }; + /// Returns d2 as scalar + inline double getD2() const { + return d2_; + }; + //@} + + +protected: + + /**@name Constructors, destructor<br> + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + ClpPdcoBase(); + /** Destructor (has to be public) */ +public: + virtual ~ClpPdcoBase(); +protected: + // Copy + ClpPdcoBase(const ClpPdcoBase&); + // Assignment + ClpPdcoBase& operator=(const ClpPdcoBase&); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Should be dense vectors + double d1_; + double d2_; + /// type (may be useful) + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpPlusMinusOneMatrix.hpp b/thirdparty/linux/include/coin1/ClpPlusMinusOneMatrix.hpp new file mode 100644 index 0000000..0cf27a4 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPlusMinusOneMatrix.hpp @@ -0,0 +1,290 @@ +/* $Id: ClpPlusMinusOneMatrix.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPlusMinusOneMatrix_H +#define ClpPlusMinusOneMatrix_H + + +#include "CoinPragma.hpp" + +#include "ClpMatrixBase.hpp" + +/** This implements a simple +- one matrix as derived from ClpMatrixBase. + +*/ + +class ClpPlusMinusOneMatrix : public ClpMatrixBase { + +public: + /**@name Useful methods */ + //@{ + /// Return a complete CoinPackedMatrix + virtual CoinPackedMatrix * getPackedMatrix() const; + /** Whether the packed matrix is column major ordered or not. */ + virtual bool isColOrdered() const ; + /** Number of entries in the packed matrix. */ + virtual CoinBigIndex getNumElements() const; + /** Number of columns. */ + virtual int getNumCols() const { + return numberColumns_; + } + /** Number of rows. */ + virtual int getNumRows() const { + return numberRows_; + } + + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with vectorStarts and vectorLengths. */ + virtual const double * getElements() const; + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with vectorStarts and + vectorLengths. */ + virtual const int * getIndices() const { + return indices_; + } + // and for advanced use + int * getMutableIndices() const { + return indices_; + } + + virtual const CoinBigIndex * getVectorStarts() const; + /** The lengths of the major-dimension vectors. */ + virtual const int * getVectorLengths() const; + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + virtual void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + virtual void deleteRows(const int numDel, const int * indDel); + /// Append Columns + virtual void appendCols(int number, const CoinPackedVectorBase * const * columns); + /// Append Rows + virtual void appendRows(int number, const CoinPackedVectorBase * const * rows); +#ifndef SLIM_CLP + /** Append a set of rows/columns to the end of the matrix. Returns number of errors + i.e. if any of the new rows/columns contain an index that's larger than the + number of columns-1/rows-1 (if numberOther>0) or duplicates + If 0 then rows, 1 if columns */ + virtual int appendMatrix(int number, int type, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther = -1); +#endif + /** Returns a new matrix in reverse order without gaps */ + virtual ClpMatrixBase * reverseOrderedCopy() const; + /// Returns number of elements in column part of basis + virtual CoinBigIndex countBasis( + const int * whichColumn, + int & numberColumnBasic); + /// Fills in column part of basis + virtual void fillBasis(ClpSimplex * model, + const int * whichColumn, + int & numberColumnBasic, + int * row, int * start, + int * rowCount, int * columnCount, + CoinFactorizationDouble * element); + /** Given positive integer weights for each row fills in sum of weights + for each column (and slack). + Returns weights vector + */ + virtual CoinBigIndex * dubiousWeights(const ClpSimplex * model, int * inputWeights) const; + /** Returns largest and smallest elements of both signs. + Largest refers to largest absolute value. + */ + virtual void rangeOfElements(double & smallestNegative, double & largestNegative, + double & smallestPositive, double & largestPositive); + /** Unpacks a column into an CoinIndexedvector + */ + virtual void unpack(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column) const ; + /** Unpacks a column into an CoinIndexedvector + ** in packed foramt + Note that model is NOT const. Bounds and objective could + be modified if doing column generation (just for this variable) */ + virtual void unpackPacked(ClpSimplex * model, + CoinIndexedVector * rowArray, + int column) const; + /** Adds multiple of a column into an CoinIndexedvector + You can use quickAdd to add to vector */ + virtual void add(const ClpSimplex * model, CoinIndexedVector * rowArray, + int column, double multiplier) const ; + /** Adds multiple of a column into an array */ + virtual void add(const ClpSimplex * model, double * array, + int column, double multiplier) const; + /// Allow any parts of a created CoinMatrix to be deleted + virtual void releasePackedMatrix() const; + /** Set the dimensions of the matrix. In effect, append new empty + columns/rows to the matrix. A negative number for either dimension + means that that dimension doesn't change. Otherwise the new dimensions + MUST be at least as large as the current ones otherwise an exception + is thrown. */ + virtual void setDimensions(int numrows, int numcols); + /// Just checks matrix valid - will say if dimensions not quite right if detail + void checkValid(bool detail) const; + //@} + + /**@name Matrix times vector methods */ + //@{ + /** Return <code>y + A * scalar *x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + virtual void times(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void times(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale) const; + /** Return <code>y + x * scalar * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + virtual void transposeTimes(double scalar, + const double * x, double * y) const; + /// And for scaling + virtual void transposeTimes(double scalar, + const double * x, double * y, + const double * rowScale, + const double * columnScale, double * spare = NULL) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex */ + virtual void transposeTimes(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x * scalar * A + y</code> in <code>z</code>. + Can use y as temporary array (will be empty at end) + Note - If x packed mode - then z packed mode + Squashes small elements and knows about ClpSimplex. + This version uses row copy*/ + virtual void transposeTimesByRow(const ClpSimplex * model, double scalar, + const CoinIndexedVector * x, + CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Return <code>x *A</code> in <code>z</code> but + just for indices in y. + Note - z always packed mode */ + virtual void subsetTransposeTimes(const ClpSimplex * model, + const CoinIndexedVector * x, + const CoinIndexedVector * y, + CoinIndexedVector * z) const; + /** Returns true if can combine transposeTimes and subsetTransposeTimes + and if it would be faster */ + virtual bool canCombine(const ClpSimplex * model, + const CoinIndexedVector * pi) const; + /// Updates two arrays for steepest + virtual void transposeTimes2(const ClpSimplex * model, + const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, + CoinIndexedVector * spare, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + /// Updates second array for steepest and does devex weights + virtual void subsetTimes2(const ClpSimplex * model, + CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + double referenceIn, double devex, + // Array for exact devex to say what is in reference framework + unsigned int * reference, + double * weights, double scaleFactor); + //@} + + /**@name Other */ + //@{ + /// Return starts of +1s + inline CoinBigIndex * startPositive() const { + return startPositive_; + } + /// Return starts of -1s + inline CoinBigIndex * startNegative() const { + return startNegative_; + } + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + ClpPlusMinusOneMatrix(); + /** Destructor */ + virtual ~ClpPlusMinusOneMatrix(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + ClpPlusMinusOneMatrix(const ClpPlusMinusOneMatrix&); + /** The copy constructor from an CoinPlusMinusOneMatrix. + If not a valid matrix then getIndices will be NULL and + startPositive[0] will have number of +1, + startPositive[1] will have number of -1, + startPositive[2] will have number of others, + */ + ClpPlusMinusOneMatrix(const CoinPackedMatrix&); + /// Constructor from arrays + ClpPlusMinusOneMatrix(int numberRows, int numberColumns, + bool columnOrdered, const int * indices, + const CoinBigIndex * startPositive, const CoinBigIndex * startNegative); + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + ClpPlusMinusOneMatrix (const ClpPlusMinusOneMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + ClpPlusMinusOneMatrix& operator=(const ClpPlusMinusOneMatrix&); + /// Clone + virtual ClpMatrixBase * clone() const ; + /** Subset clone (without gaps). Duplicates are allowed + and order is as given */ + virtual ClpMatrixBase * subsetClone ( + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns) const ; + /// pass in copy (object takes ownership) + void passInCopy(int numberRows, int numberColumns, + bool columnOrdered, int * indices, + CoinBigIndex * startPositive, CoinBigIndex * startNegative); + /// Says whether it can do partial pricing + virtual bool canDoPartialPricing() const; + /// Partial pricing + virtual void partialPricing(ClpSimplex * model, double start, double end, + int & bestSequence, int & numberWanted); + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// For fake CoinPackedMatrix + mutable CoinPackedMatrix * matrix_; + mutable int * lengths_; + /// Start of +1's for each + CoinBigIndex * COIN_RESTRICT startPositive_; + /// Start of -1's for each + CoinBigIndex * COIN_RESTRICT startNegative_; + /// Data -1, then +1 rows in pairs (row==-1 if one entry) + int * COIN_RESTRICT indices_; + /// Number of rows + int numberRows_; + /// Number of columns + int numberColumns_; +#ifdef CLP_PLUS_ONE_MATRIX + /** Other flags (could have columnOrdered_?) + 1 bit - says just +1 + */ + mutable int otherFlags_; +#endif + /// True if column ordered + bool columnOrdered_; + + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpPresolve.hpp b/thirdparty/linux/include/coin1/ClpPresolve.hpp new file mode 100644 index 0000000..5e28289 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPresolve.hpp @@ -0,0 +1,299 @@ +/* $Id: ClpPresolve.hpp 2134 2015-03-22 16:40:43Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPresolve_H +#define ClpPresolve_H +#include "ClpSimplex.hpp" + +class CoinPresolveAction; +#include "CoinPresolveMatrix.hpp" +/** This is the Clp interface to CoinPresolve + +*/ +class ClpPresolve { +public: + /**@name Main Constructor, destructor */ + //@{ + /// Default constructor + ClpPresolve(); + + /// Virtual destructor + virtual ~ClpPresolve(); + //@} + /**@name presolve - presolves a model, transforming the model + * and saving information in the ClpPresolve object needed for postsolving. + * This underlying (protected) method is virtual; the idea is that in the future, + * one could override this method to customize how the various + * presolve techniques are applied. + + This version of presolve returns a pointer to a new presolved + model. NULL if infeasible or unbounded. + This should be paired with postsolve + below. The advantage of going back to original model is that it + will be exactly as it was i.e. 0.0 will not become 1.0e-19. + If keepIntegers is true then bounds may be tightened in + original. Bounds will be moved by up to feasibilityTolerance + to try and stay feasible. + Names will be dropped in presolved model if asked + */ + ClpSimplex * presolvedModel(ClpSimplex & si, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +#ifndef CLP_NO_STD + /** This version saves data in a file. The passed in model + is updated to be presolved model. + Returns non-zero if infeasible*/ + int presolvedModelToFile(ClpSimplex &si, std::string fileName, + double feasibilityTolerance = 0.0, + bool keepIntegers = true, + int numberPasses = 5, + bool dropNames = false, + bool doRowObjective = false); +#endif + /** Return pointer to presolved model, + Up to user to destroy */ + ClpSimplex * model() const; + /// Return pointer to original model + ClpSimplex * originalModel() const; + /// Set pointer to original model + void setOriginalModel(ClpSimplex * model); + + /// return pointer to original columns + const int * originalColumns() const; + /// return pointer to original rows + const int * originalRows() const; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) { + nonLinearValue_ = value; + } + inline double nonLinearValue() const { + return nonLinearValue_; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (presolveActions_ & 1) == 0; + } + inline void setDoDual(bool doDual) { + if (doDual) presolveActions_ &= ~1; + else presolveActions_ |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (presolveActions_ & 2) == 0; + } + inline void setDoSingleton(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~2; + else presolveActions_ |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (presolveActions_ & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton) { + if (doDoubleton) presolveActions_ &= ~4; + else presolveActions_ |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (presolveActions_ & 8) == 0; + } + inline void setDoTripleton(bool doTripleton) { + if (doTripleton) presolveActions_ &= ~8; + else presolveActions_ |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (presolveActions_ & 16) == 0; + } + inline void setDoTighten(bool doTighten) { + if (doTighten) presolveActions_ &= ~16; + else presolveActions_ |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (presolveActions_ & 32) == 0; + } + inline void setDoForcing(bool doForcing) { + if (doForcing) presolveActions_ &= ~32; + else presolveActions_ |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (presolveActions_ & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) presolveActions_ &= ~64; + else presolveActions_ |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (presolveActions_ & 128) == 0; + } + inline void setDoDupcol(bool doDupcol) { + if (doDupcol) presolveActions_ &= ~128; + else presolveActions_ |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (presolveActions_ & 256) == 0; + } + inline void setDoDuprow(bool doDuprow) { + if (doDuprow) presolveActions_ &= ~256; + else presolveActions_ |= 256; + } + /// Whether we want to do dependency part of presolve + inline bool doDependency() const { + return (presolveActions_ & 32768) != 0; + } + inline void setDoDependency(bool doDependency) { + if (doDependency) presolveActions_ |= 32768; + else presolveActions_ &= ~32768; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (presolveActions_ & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton) { + if (doSingleton) presolveActions_ &= ~512; + else presolveActions_ |= 512; + } + /// Whether we want to do gubrow part of presolve + inline bool doGubrow() const { + return (presolveActions_ & 1024) == 0; + } + inline void setDoGubrow(bool doGubrow) { + if (doGubrow) presolveActions_ &= ~1024; + else presolveActions_ |= 1024; + } + /// Whether we want to do twoxtwo part of presolve + inline bool doTwoxTwo() const { + return (presolveActions_ & 2048) != 0; + } + inline void setDoTwoxtwo(bool doTwoxTwo) { + if (!doTwoxTwo) presolveActions_ &= ~2048; + else presolveActions_ |= 2048; + } + /// Whether we want to allow duplicate intersections + inline bool doIntersection() const { + return (presolveActions_ & 4096) != 0; + } + inline void setDoIntersection(bool doIntersection) { + if (doIntersection) presolveActions_ &= ~4096; + else presolveActions_ |= 4096; + } + /** How much we want to zero small values from aggregation - ratio + 0 - 1.0e-12, 1 1.0e-11, 2 1.0e-10, 3 1.0e-9 */ + inline int zeroSmall() const { + return (presolveActions_&(8192|16384))>>13; + } + inline void setZeroSmall(int value) { + presolveActions_ &= ~(8192|16384); + presolveActions_ |= value<<13; + } + /// Set whole group + inline int presolveActions() const { + return presolveActions_ & 0xffff; + } + inline void setPresolveActions(int action) { + presolveActions_ = (presolveActions_ & 0xffff0000) | (action & 0xffff); + } + /// Substitution level + inline void setSubstitution(int value) { + substitution_ = value; + } + /// Asks for statistics + inline void statistics() { + presolveActions_ |= 0x80000000; + } + /// Return presolve status (0,1,2) + int presolveStatus() const; + + /**@name postsolve - postsolve the problem. If the problem + has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept + of "basic" rows/cols, then set updateStatus + + Note that if you modified the original problem after presolving, + then you must ``undo'' these modifications before calling postsolve. + This version updates original*/ + virtual void postsolve(bool updateStatus = true); + + /// Gets rid of presolve actions (e.g.when infeasible) + void destroyPresolve(); + + /**@name private or protected data */ +private: + /// Original model - must not be destroyed before postsolve + ClpSimplex * originalModel_; + + /// ClpPresolved model - up to user to destroy by deleteClpPresolvedModel + ClpSimplex * presolvedModel_; + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + /// Original column numbers + int * originalColumn_; + /// Original row numbers + int * originalRow_; + /// Row objective + double * rowObjective_; + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /// The postsolved problem will expand back to its former size + /// as postsolve transformations are applied. + /// It is efficient to allocate data structures for the final size + /// of the problem rather than expand them as needed. + /// These fields give the size of the original problem. + int ncols_; + int nrows_; + CoinBigIndex nelems_; + /// Number of major passes + int numberPasses_; + /// Substitution level + int substitution_; +#ifndef CLP_NO_STD + /// Name of saved model file + std::string saveFile_; +#endif + /** Whether we want to skip dual part of presolve etc. + 512 bit allows duplicate column processing on integer columns + and dual stuff on integers + */ + int presolveActions_; +protected: + /// If you want to apply the individual presolve routines differently, + /// or perhaps add your own to the mix, + /// define a derived class and override this method + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /// Postsolving is pretty generic; just apply the transformations + /// in reverse order. + /// You will probably only be interested in overriding this method + /// if you want to add code to test for consistency + /// while debugging new presolve techniques. + virtual void postsolve(CoinPostsolveMatrix &prob); + /** This is main part of Presolve */ + virtual ClpSimplex * gutsOfPresolvedModel(ClpSimplex * originalModel, + double feasibilityTolerance, + bool keepIntegers, + int numberPasses, + bool dropNames, + bool doRowObjective, + const char * prohibitedRows=NULL, + const char * prohibitedColumns=NULL); +}; +#endif diff --git a/thirdparty/linux/include/coin1/ClpPrimalColumnDantzig.hpp b/thirdparty/linux/include/coin1/ClpPrimalColumnDantzig.hpp new file mode 100644 index 0000000..7289ead --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPrimalColumnDantzig.hpp @@ -0,0 +1,72 @@ +/* $Id: ClpPrimalColumnDantzig.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnDantzig_H +#define ClpPrimalColumnDantzig_H + +#include "ClpPrimalColumnPivot.hpp" + +//############################################################################# + +/** Primal Column Pivot Dantzig Algorithm Class + +This is simplest choice - choose largest infeasibility + +*/ + +class ClpPrimalColumnDantzig : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + Lumbers over all columns - slow + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Can just do full price if you really want to be slow + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /// Just sets model + virtual void saveWeights(ClpSimplex * model, int) { + model_ = model; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnDantzig(); + + /// Copy constructor + ClpPrimalColumnDantzig(const ClpPrimalColumnDantzig &); + + /// Assignment operator + ClpPrimalColumnDantzig & operator=(const ClpPrimalColumnDantzig& rhs); + + /// Destructor + virtual ~ClpPrimalColumnDantzig (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpPrimalColumnPivot.hpp b/thirdparty/linux/include/coin1/ClpPrimalColumnPivot.hpp new file mode 100644 index 0000000..678da30 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPrimalColumnPivot.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpPrimalColumnPivot.hpp 1732 2011-05-31 08:09:41Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalcolumnPivot_H +#define ClpPrimalcolumnPivot_H + +class ClpSimplex; +class CoinIndexedVector; + +//############################################################################# + +/** Primal Column Pivot Abstract Base Class + +Abstract Base Class for describing an interface to an algorithm +to choose column pivot in primal simplex algorithm. For some algorithms +e.g. Dantzig choice then some functions may be null. For Dantzig +the only one of any importance is pivotColumn. + +If you wish to inherit from this look at ClpPrimalColumnDantzig.cpp +as that is simplest version. +*/ + +class ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none + + Normally updates reduced costs using result of last iteration + before selecting incoming column. + + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + + Inside pivotColumn the pivotRow_ and reduced cost from last iteration + are also used. + + So in the simplest case i.e. feasible we compute the row of the + tableau corresponding to last pivot and add a multiple of this + to current reduced costs. + + We can use other arrays to help updates + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2) = 0; + + /// Updates weights - part 1 (may be empty) + virtual void updateWeights(CoinIndexedVector * input); + + /** Saves any weights round factorization as pivot rows may change + Will be empty unless steepest edge (will save model) + May also recompute infeasibility stuff + 1) before factorization + 2) after good factorization (if weights empty may initialize) + 3) after something happened but no factorization + (e.g. check for infeasible) + 4) as 2 but restore weights from previous snapshot + 5) forces some initialization e.g. weights + Also sets model + */ + virtual void saveWeights(ClpSimplex * model, int mode) = 0; + /** Signals pivot row choice: + -2 (default) - use normal pivot row choice + -1 to numberRows-1 - use this (will be checked) + way should be -1 to go to lower bound, +1 to upper bound + */ + virtual int pivotRow(double & way) { + way = 0; + return -2; + } + /// Gets rid of all arrays (may be empty) + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const { + return looksOptimal_; + } + /// Sets optimality flag (for advanced use) + virtual void setLooksOptimal(bool flag) { + looksOptimal_ = flag; + } + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpPrimalColumnPivot(); + + /// Copy constructor + ClpPrimalColumnPivot(const ClpPrimalColumnPivot &); + + /// Assignment operator + ClpPrimalColumnPivot & operator=(const ClpPrimalColumnPivot& rhs); + + /// Destructor + virtual ~ClpPrimalColumnPivot (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const = 0; + + //@} + + ///@name Other + //@{ + /// Returns model + inline ClpSimplex * model() { + return model_; + } + /// Sets model + inline void setModel(ClpSimplex * newmodel) { + model_ = newmodel; + } + + /// Returns type (above 63 is extra information) + inline int type() { + return type_; + } + + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + /// Called when maximum pivots changes + virtual void maximumPivotsChanged() {} + + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected member data + //@{ + /// Pointer to model + ClpSimplex * model_; + /// Type of column pivot algorithm + int type_; + /// Says if looks optimal (normally computed) + bool looksOptimal_; + //@} +}; +#ifndef CLP_PRIMAL_SLACK_MULTIPLIER +#define CLP_PRIMAL_SLACK_MULTIPLIER 1.01 +#endif +#endif diff --git a/thirdparty/linux/include/coin1/ClpPrimalColumnSteepest.hpp b/thirdparty/linux/include/coin1/ClpPrimalColumnSteepest.hpp new file mode 100644 index 0000000..2da7542 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpPrimalColumnSteepest.hpp @@ -0,0 +1,247 @@ +/* $Id: ClpPrimalColumnSteepest.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpPrimalColumnSteepest_H +#define ClpPrimalColumnSteepest_H + +#include "ClpPrimalColumnPivot.hpp" +#include <bitset> + +//############################################################################# +class CoinIndexedVector; + + +/** Primal Column Pivot Steepest Edge Algorithm Class + +See Forrest-Goldfarb paper for algorithm + +*/ + + +class ClpPrimalColumnSteepest : public ClpPrimalColumnPivot { + +public: + + ///@name Algorithmic methods + //@{ + + /** Returns pivot column, -1 if none. + The Packed CoinIndexedVector updates has cost updates - for normal LP + that is just +-weight where a feasibility changed. It also has + reduced cost from last iteration in pivot row + Parts of operation split out into separate functions for + profiling and speed + */ + virtual int pivotColumn(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// For quadratic or funny nonlinearities + int pivotColumnOldMethod(CoinIndexedVector * updates, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Just update djs + void justDjs(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs doing partial pricing (dantzig) + int partialPricing(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + int numberWanted, + int numberLook); + /// Update djs, weights for Devex using djs + void djsAndDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using djs + void djsAndSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Devex using pivot row + void djsAndDevex2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update djs, weights for Steepest using pivot row + void djsAndSteepest2(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Devex + void justDevex(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Update weights for Steepest + void justSteepest(CoinIndexedVector * updates, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + /// Updates two arrays for steepest + void transposeTimes2(const CoinIndexedVector * pi1, CoinIndexedVector * dj1, + const CoinIndexedVector * pi2, CoinIndexedVector * dj2, + CoinIndexedVector * spare, double scaleFactor); + + /// Updates weights - part 1 - also checks accuracy + virtual void updateWeights(CoinIndexedVector * input); + + /// Checks accuracy - just for debug + void checkAccuracy(int sequence, double relativeTolerance, + CoinIndexedVector * rowArray1, + CoinIndexedVector * rowArray2); + + /// Initialize weights + void initializeWeights(); + + /** Save weights - this may initialize weights as well + mode is - + 1) before factorization + 2) after factorization + 3) just redo infeasibilities + 4) restore weights + 5) at end of values pass (so need initialization) + */ + virtual void saveWeights(ClpSimplex * model, int mode); + /// Gets rid of last update + virtual void unrollWeights(); + /// Gets rid of all arrays + virtual void clearArrays(); + /// Returns true if would not find any column + virtual bool looksOptimal() const; + /// Called when maximum pivots changes + virtual void maximumPivotsChanged(); + //@} + + /**@name gets and sets */ + //@{ + /// Mode + inline int mode() const { + return mode_; + } + /** Returns number of extra columns for sprint algorithm - 0 means off. + Also number of iterations before recompute + */ + virtual int numberSprintColumns(int & numberIterations) const; + /// Switch off sprint idea + virtual void switchOffSprint(); + +//@} + + /** enums for persistence + */ + enum Persistence { + normal = 0x00, // create (if necessary) and destroy + keep = 0x01 // create (if necessary) and leave + }; + + ///@name Constructors and destructors + //@{ + /** Default Constructor + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + */ + ClpPrimalColumnSteepest(int mode = 3); + + /// Copy constructor + ClpPrimalColumnSteepest(const ClpPrimalColumnSteepest & rhs); + + /// Assignment operator + ClpPrimalColumnSteepest & operator=(const ClpPrimalColumnSteepest& rhs); + + /// Destructor + virtual ~ClpPrimalColumnSteepest (); + + /// Clone + virtual ClpPrimalColumnPivot * clone(bool copyData = true) const; + + //@} + + ///@name Private functions to deal with devex + /** reference would be faster using ClpSimplex's status_, + but I prefer to keep modularity. + */ + inline bool reference(int i) const { + return ((reference_[i>>5] >> (i & 31)) & 1) != 0; + } + inline void setReference(int i, bool trueFalse) { + unsigned int & value = reference_[i>>5]; + int bit = i & 31; + if (trueFalse) + value |= (1 << bit); + else + value &= ~(1 << bit); + } + /// Set/ get persistence + inline void setPersistence(Persistence life) { + persistence_ = life; + } + inline Persistence persistence() const { + return persistence_ ; + } + + //@} + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + // Update weight + double devex_; + /// weight array + double * weights_; + /// square of infeasibility array (just for infeasible columns) + CoinIndexedVector * infeasible_; + /// alternate weight array (so we can unroll) + CoinIndexedVector * alternateWeights_; + /// save weight array (so we can use checkpoint) + double * savedWeights_; + // Array for exact devex to say what is in reference framework + unsigned int * reference_; + /** Status + 0) Normal + -1) Needs initialization + 1) Weights are stored by sequence number + */ + int state_; + /** + 0 is exact devex, 1 full steepest, 2 is partial exact devex + 3 switches between 0 and 2 depending on factorization + 4 starts as partial dantzig/devex but then may switch between 0 and 2. + 5 is always partial dantzig + By partial exact devex is meant that the weights are updated as normal + but only part of the nonbasic variables are scanned. + This can be faster on very easy problems. + + New dubious option is >=10 which does mini-sprint + + */ + int mode_; + /// Life of weights + Persistence persistence_; + /// Number of times switched from partial dantzig to 0/2 + int numberSwitched_; + // This is pivot row (or pivot sequence round re-factorization) + int pivotSequence_; + // This is saved pivot sequence + int savedPivotSequence_; + // This is saved outgoing variable + int savedSequenceOut_; + // Iteration when last rectified + int lastRectified_; + // Size of factorization at invert (used to decide algorithm) + int sizeFactorization_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpQuadraticObjective.hpp b/thirdparty/linux/include/coin1/ClpQuadraticObjective.hpp new file mode 100644 index 0000000..a52b097 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpQuadraticObjective.hpp @@ -0,0 +1,155 @@ +/* $Id: ClpQuadraticObjective.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef ClpQuadraticObjective_H +#define ClpQuadraticObjective_H + +#include "ClpObjective.hpp" +#include "CoinPackedMatrix.hpp" + +//############################################################################# + +/** Quadratic Objective Class + +*/ + +class ClpQuadraticObjective : public ClpObjective { + +public: + + ///@name Stuff + //@{ + + /** Returns gradient. If Quadratic then solution may be NULL, + also returns an offset (to be added to current one) + If refresh is false then uses last solution + Uses model for scaling + includeLinear 0 - no, 1 as is, 2 as feasible + */ + virtual double * gradient(const ClpSimplex * model, + const double * solution, double & offset, bool refresh, + int includeLinear = 2); + /// Resize objective + /** Returns reduced gradient.Returns an offset (to be added to current one). + */ + virtual double reducedGradient(ClpSimplex * model, double * region, + bool useFeasibleCosts); + /** Returns step length which gives minimum of objective for + solution + theta * change vector up to maximum theta. + + arrays are numberColumns+numberRows + Also sets current objective, predicted and at maximumTheta + */ + virtual double stepLength(ClpSimplex * model, + const double * solution, + const double * change, + double maximumTheta, + double & currentObj, + double & predictedObj, + double & thetaObj); + /// Return objective value (without any ClpModel offset) (model may be NULL) + virtual double objectiveValue(const ClpSimplex * model, const double * solution) const ; + virtual void resize(int newNumberColumns) ; + /// Delete columns in objective + virtual void deleteSome(int numberToDelete, const int * which) ; + /// Scale objective + virtual void reallyScale(const double * columnScale) ; + /** Given a zeroed array sets nonlinear columns to 1. + Returns number of nonlinear columns + */ + virtual int markNonlinear(char * which); + + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + ClpQuadraticObjective(); + + /// Constructor from objective + ClpQuadraticObjective(const double * linearObjective, int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns_ = -1); + + /** Copy constructor . + If type is -1 then make sure half symmetric, + if +1 then make sure full + */ + ClpQuadraticObjective(const ClpQuadraticObjective & rhs, int type = 0); + /** Subset constructor. Duplicates are allowed + and order is as given. + */ + ClpQuadraticObjective (const ClpQuadraticObjective &rhs, int numberColumns, + const int * whichColumns) ; + + /// Assignment operator + ClpQuadraticObjective & operator=(const ClpQuadraticObjective& rhs); + + /// Destructor + virtual ~ClpQuadraticObjective (); + + /// Clone + virtual ClpObjective * clone() const; + /** Subset clone. Duplicates are allowed + and order is as given. + */ + virtual ClpObjective * subsetClone (int numberColumns, + const int * whichColumns) const; + + /** Load up quadratic objective. This is stored as a CoinPackedMatrix */ + void loadQuadraticObjective(const int numberColumns, + const CoinBigIndex * start, + const int * column, const double * element, + int numberExtendedColumns = -1); + void loadQuadraticObjective ( const CoinPackedMatrix& matrix); + /// Get rid of quadratic objective + void deleteQuadraticObjective(); + //@} + ///@name Gets and sets + //@{ + /// Quadratic objective + inline CoinPackedMatrix * quadraticObjective() const { + return quadraticObjective_; + } + /// Linear objective + inline double * linearObjective() const { + return objective_; + } + /// Length of linear objective which could be bigger + inline int numberExtendedColumns() const { + return numberExtendedColumns_; + } + /// Number of columns in quadratic objective + inline int numberColumns() const { + return numberColumns_; + } + /// If a full or half matrix + inline bool fullMatrix() const { + return fullMatrix_; + } + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + /// Quadratic objective + CoinPackedMatrix * quadraticObjective_; + /// Objective + double * objective_; + /// Gradient + double * gradient_; + /// Useful to have number of columns about + int numberColumns_; + /// Also length of linear objective which could be bigger + int numberExtendedColumns_; + /// True if full symmetric matrix, false if half + bool fullMatrix_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ClpSimplex.hpp b/thirdparty/linux/include/coin1/ClpSimplex.hpp new file mode 100644 index 0000000..bab4506 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSimplex.hpp @@ -0,0 +1,1797 @@ +/* $Id: ClpSimplex.hpp 2114 2015-02-10 12:12:46Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplex_H +#define ClpSimplex_H + +#include <iostream> +#include <cfloat> +#include "ClpModel.hpp" +#include "ClpMatrixBase.hpp" +#include "ClpSolve.hpp" +#include "ClpConfig.h" +class ClpDualRowPivot; +class ClpPrimalColumnPivot; +class ClpFactorization; +class CoinIndexedVector; +class ClpNonLinearCost; +class ClpNodeStuff; +class CoinStructuredModel; +class OsiClpSolverInterface; +class CoinWarmStartBasis; +class ClpDisasterHandler; +class ClpConstraint; +/* + May want to use Clp defaults so that with ABC defined but not used + it behaves as Clp (and ABC used will be different than if not defined) + */ +#ifdef ABC_INHERIT +#ifndef CLP_INHERIT_MODE +#define CLP_INHERIT_MODE 1 +#endif +#ifndef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 0 +#endif +#else +#undef ABC_CLP_DEFAULTS +#define ABC_CLP_DEFAULTS 1 +#endif +#ifdef CLP_HAS_ABC +#include "AbcCommon.hpp" +class AbcTolerancesEtc; +class AbcSimplex; +#include "CoinAbcCommon.hpp" +#endif +/** This solves LPs using the simplex method + + It inherits from ClpModel and all its arrays are created at + algorithm time. Originally I tried to work with model arrays + but for simplicity of coding I changed to single arrays with + structural variables then row variables. Some coding is still + based on old style and needs cleaning up. + + For a description of algorithms: + + for dual see ClpSimplexDual.hpp and at top of ClpSimplexDual.cpp + for primal see ClpSimplexPrimal.hpp and at top of ClpSimplexPrimal.cpp + + There is an algorithm data member. + for primal variations + and - for dual variations + +*/ + +class ClpSimplex : public ClpModel { + friend void ClpSimplexUnitTest(const std::string & mpsDir); + +public: + /** enums for status of various sorts. + First 4 match CoinWarmStartBasis, + isFixed means fixed at lower bound and out of basis + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04, + isFixed = 0x05 + }; + // For Dual + enum FakeBound { + noFake = 0x00, + lowerFake = 0x01, + upperFake = 0x02, + bothFake = 0x03 + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplex (bool emptyMessages = false ); + + /** Copy constructor. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpSimplex & rhs, int scalingMode = -1); + /** Copy constructor from model. May scale depending on mode + -1 leave mode as is + 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) + */ + ClpSimplex(const ClpModel & rhs, int scalingMode = -1); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpModel * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** Subproblem constructor. A subset of whole model is created from the + row and column lists given. The new order is given by list order and + duplicates are allowed. Name and integer information can be dropped + Can optionally modify rhs to take into account variables NOT in list + in this case duplicates are not allowed (also see getbackSolution) + */ + ClpSimplex (const ClpSimplex * wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns, + bool dropNames = true, bool dropIntegers = true, + bool fixOthers = false); + /** This constructor modifies original ClpSimplex and stores + original stuff in created ClpSimplex. It is only to be used in + conjunction with originalModel */ + ClpSimplex (ClpSimplex * wholeModel, + int numberColumns, const int * whichColumns); + /** This copies back stuff from miniModel and then deletes miniModel. + Only to be used with mini constructor */ + void originalModel(ClpSimplex * miniModel); + inline int abcState() const + { return abcState_;} + inline void setAbcState(int state) + { abcState_=state;} +#ifdef ABC_INHERIT + inline AbcSimplex * abcSimplex() const + { return abcSimplex_;} + inline void setAbcSimplex(AbcSimplex * simplex) + { abcSimplex_=simplex;} + /// Returns 0 if dual can be skipped + int doAbcDual(); + /// Returns 0 if primal can be skipped + int doAbcPrimal(int ifValuesPass); +#endif + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + void setPersistenceFlag(int value); + /// Save a copy of model with certain state - normally without cuts + void makeBaseModel(); + /// Switch off base model + void deleteBaseModel(); + /// See if we have base model + inline ClpSimplex * baseModel() const { + return baseModel_; + } + /** Reset to base model (just size and arrays needed) + If model NULL use internal copy + */ + void setToBaseModel(ClpSimplex * model = NULL); + /// Assignment operator. This copies the data + ClpSimplex & operator=(const ClpSimplex & rhs); + /// Destructor + ~ClpSimplex ( ); + // Ones below are just ClpModel with some changes + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + void loadProblem ( const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + void loadProblem ( const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /// This one is for after presolve to save memory + void loadProblem ( const int numcols, const int numrows, + const CoinBigIndex* start, const int* index, + const double* value, const int * length, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + const double * rowObjective = NULL); + /** This loads a model from a coinModel object - returns number of errors. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinModel & modelObject, bool keepSolution = false); + /// Read an mps file from the given filename + int readMps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + /// Read GMPL files from the given filenames + int readGMPL(const char *filename, const char * dataName, + bool keepNames = false); + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + int readLp(const char *filename, const double epsilon = 1e-5); + /** Borrow model. This is so we dont have to copy large amounts + of data around. It assumes a derived class wants to overwrite + an empty model with a real one - while it does an algorithm. + This is same as ClpModel one, but sets scaling on etc. */ + void borrowModel(ClpModel & otherModel); + void borrowModel(ClpSimplex & otherModel); + /// Pass in Event handler (cloned and deleted at end) + void passInEventHandler(const ClpEventHandler * eventHandler); + /// Puts solution back into small model + void getbackSolution(const ClpSimplex & smallModel, const int * whichRow, const int * whichColumn); + /** Load nonlinear part of problem from AMPL info + Returns 0 if linear + 1 if quadratic objective + 2 if quadratic constraints + 3 if nonlinear objective + 4 if nonlinear constraints + -1 on failure + */ + int loadNonLinear(void * info, int & numberConstraints, + ClpConstraint ** & constraints); +#ifdef ABC_INHERIT + /// Loads tolerances etc + void loadTolerancesEtc(const AbcTolerancesEtc & data); + /// Unloads tolerances etc + void unloadTolerancesEtc(AbcTolerancesEtc & data); +#endif + //@} + + /**@name Functions most useful to user */ + //@{ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + int initialSolve(ClpSolve & options); + /// Default initial solve + int initialSolve(); + /// Dual initial solve + int initialDualSolve(); + /// Primal initial solve + int initialPrimalSolve(); + /// Barrier initial solve + int initialBarrierSolve(); + /// Barrier initial solve, not to be followed by crossover + int initialBarrierNoCrossSolve(); + /** Dual algorithm - see ClpSimplexDual.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int dual(int ifValuesPass = 0, int startFinishOptions = 0); + // If using Debug + int dualDebug(int ifValuesPass = 0, int startFinishOptions = 0); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method. + ifValuesPass==2 just does values pass and then stops. + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + */ + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + /** Solves nonlinear problem using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberPasses, double deltaTolerance); + /** Solves problem with nonlinear constraints using SLP - may be used as crash + for other algorithms when number of iterations small. + Also exits if all problematical variables are changing + less than deltaTolerance + */ + int nonlinearSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + /** Solves using barrier (assumes you have good cholesky factor code). + Does crossover to simplex if asked*/ + int barrier(bool crossover = true); + /** Solves non-linear using reduced gradient. Phase = 0 get feasible, + =1 use solution */ + int reducedGradient(int phase = 0); + /// Solve using structure of model and maybe in parallel + int solve(CoinStructuredModel * model); +#ifdef ABC_INHERIT + /** solvetype 0 for dual, 1 for primal + startup 1 for values pass + interrupt whether to pass across interrupt handler + add 10 to return AbcSimplex + */ + AbcSimplex * dealWithAbc(int solveType,int startUp,bool interrupt=false); + //void dealWithAbc(int solveType,int startUp,bool interrupt=false); +#endif + /** This loads a model from a CoinStructuredModel object - returns number of errors. + If originalOrder then keep to order stored in blocks, + otherwise first column/rows correspond to first block - etc. + If keepSolution true and size is same as current then + keeps current status and solution + */ + int loadProblem ( CoinStructuredModel & modelObject, + bool originalOrder = true, bool keepSolution = false); + /** + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + + return code as dual/primal + */ + int cleanup(int cleanupScaling); + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + Returns non-zero if infeasible unbounded etc + */ + int dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + Returns non-zero if infeasible unbounded etc + */ + int primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** + Modifies coefficients etc and if necessary pivots in and out. + All at same status will be done (basis may go singular). + User can tell which others have been done (i.e. if status matches). + If called from outside will change status and return 0. + If called from event handler returns non-zero if user has to take action. + indices>=numberColumns are slacks (obviously no coefficients) + status array is (char) Status enum + */ + int modifyCoefficientsAndPivot(int number, + const int * which, + const CoinBigIndex * start, + const int * row, + const double * newCoefficient, + const unsigned char * newStatus=NULL, + const double * newLower=NULL, + const double * newUpper=NULL, + const double * newObjective=NULL); + /** Take out duplicate rows (includes scaled rows and intersections). + On exit whichRows has rows to delete - return code is number can be deleted + or -1 if would be infeasible. + If tolerance is -1.0 use primalTolerance for equality rows and infeasibility + If cleanUp not zero then spend more time trying to leave more stable row + and make row bounds exact multiple of cleanUp if close enough + */ + int outDuplicateRows(int numberLook,int * whichRows, bool noOverlaps=false, double tolerance=-1.0, + double cleanUp=0.0); + /** Try simple crash like techniques to get closer to primal feasibility + returns final sum of infeasibilities */ + double moveTowardsPrimalFeasible(); + /** Try simple crash like techniques to remove super basic slacks + but only if > threshold */ + void removeSuperBasicSlacks(int threshold=0); + /** Mini presolve (faster) + Char arrays must be numberRows and numberColumns long + on entry second part must be filled in as follows - + 0 - possible + >0 - take out and do something (depending on value - TBD) + -1 row/column can't vanish but can have entries removed/changed + -2 don't touch at all + on exit <=0 ones will be in presolved problem + struct will be created and will be long enough + (information on length etc in first entry) + user must delete struct + */ + ClpSimplex * miniPresolve(char * rowType, char * columnType,void ** info); + /// After mini presolve + void miniPostsolve(const ClpSimplex * presolvedModel,void * info); + /// mini presolve and solve + void miniSolve(char * rowType, char *columnType,int algorithm, int startUp); + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex (later) + </ul> + + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /** Read a basis from the given filename, + returns -1 on file error, 0 if no values, 1 if values */ + int readBasis(const char *filename); + /// Returns a basis (to be deleted by user) + CoinWarmStartBasis * getBasis() const; + /// Passes in factorization + void setFactorization( ClpFactorization & factorization); + // Swaps factorization + ClpFactorization * swapFactorization( ClpFactorization * factorization); + /// Copies in factorization to existing one + void copyFactorization( ClpFactorization & factorization); + /** Tightens primal bounds to make dual faster. Unless + fixed or doTight>10, bounds are slightly looser than they could be. + This is to make dual go faster and is probably not needed + with a presolve. Returns non-zero if problem infeasible. + + Fudge for branch and bound - put bounds on columns of factor * + largest value (at continuous) - should improve stability + in branch and bound on infeasible branches (0.0 is off) + */ + int tightenPrimalBounds(double factor = 0.0, int doTight = 0, bool tightIntegers = false); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + ( If pivot -1 then can be made super basic!) + + If "pivot" is + -1 No pivoting - always primal + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + int crash(double gap, int pivot); + /// Sets row pivot choice algorithm in dual + void setDualRowPivotAlgorithm(ClpDualRowPivot & choice); + /// Sets column pivot choice algorithm in primal + void setPrimalColumnPivotAlgorithm(ClpPrimalColumnPivot & choice); + /// Create a hotstart point of the optimization process + void markHotStart(void * & saveStuff); + /// Optimize starting from the hotstart + void solveFromHotStart(void * saveStuff); + /// Delete the snapshot + void unmarkHotStart(void * saveStuff); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// Fathom - 1 if solution + int fathom(void * stuff); + /** Do up to N deep - returns + -1 - no solution nNodes_ valid nodes + >= if solution and that node gives solution + ClpNode array is 2**N long. Values for N and + array are in stuff (nNodes_ also in stuff) */ + int fathomMany(void * stuff); + /// Double checks OK + double doubleCheck(); + /// Starts Fast dual2 + int startFastDual2(ClpNodeStuff * stuff); + /// Like Fast dual + int fastDual2(ClpNodeStuff * stuff); + /// Stops Fast dual2 + void stopFastDual2(ClpNodeStuff * stuff); + /** Deals with crunch aspects + mode 0 - in + 1 - out with solution + 2 - out without solution + returns small model or NULL + */ + ClpSimplex * fastCrunch(ClpNodeStuff * stuff, int mode); + //@} + + /**@name Needed for functionality of OsiSimplexInterface */ + //@{ + /** Pivot in a variable and out a variable. Returns 0 if okay, + 1 if inaccuracy forced re-factorization, -1 if would be singular. + Also updates primal/dual infeasibilities. + Assumes sequenceIn_ and pivotRow_ set and also directionIn and Out. + */ + int pivot(); + + /** Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ (or NULL if no pivot) + Return codes as before but -1 means no acceptable pivot + */ + int primalPivotResult(); + + /** Pivot out a variable and choose an incoing one. Assumes dual + feasible - will not go through a reduced cost. + Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int dualPivotResultPart1(); + /** Do actual pivot + state is 0 if need tableau column, 1 if in rowArray_[1] + */ + int pivotResultPart2(int algorithm,int state); + + /** Common bits of coding for dual and primal. Return 0 if okay, + 1 if bad matrix, 2 if very bad factorization + + startFinishOptions - bits + 1 - do not delete work areas and factorization at end + 2 - use old factorization if same number of rows + 4 - skip as much initialization of work areas as possible + (based on whatsChanged in clpmodel.hpp) ** work in progress + maybe other bits later + + */ + int startup(int ifValuesPass, int startFinishOptions = 0); + void finish(int startFinishOptions = 0); + + /** Factorizes and returns true if optimal. Used by user */ + bool statusOfProblem(bool initial = false); + /// If user left factorization frequency then compute + void defaultFactorizationFrequency(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(const ClpSimplex * rhs); + //@} + + /**@name most useful gets and sets */ + //@{ + /// If problem is primal feasible + inline bool primalFeasible() const { + return (numberPrimalInfeasibilities_ == 0); + } + /// If problem is dual feasible + inline bool dualFeasible() const { + return (numberDualInfeasibilities_ == 0); + } + /// factorization + inline ClpFactorization * factorization() const { + return factorization_; + } + /// Sparsity on or off + bool sparseFactorization() const; + void setSparseFactorization(bool value); + /// Factorization frequency + int factorizationFrequency() const; + void setFactorizationFrequency(int value); + /// Dual bound + inline double dualBound() const { + return dualBound_; + } + void setDualBound(double value); + /// Infeasibility cost + inline double infeasibilityCost() const { + return infeasibilityCost_; + } + void setInfeasibilityCost(double value); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + inline int perturbation() const { + return perturbation_; + } + void setPerturbation(int value); + /// Current (or last) algorithm + inline int algorithm() const { + return algorithm_; + } + /// Set algorithm + inline void setAlgorithm(int value) { + algorithm_ = value; + } + /// Return true if the objective limit test can be relied upon + bool isObjectiveLimitTestValid() const ; + /// Sum of dual infeasibilities + inline double sumDualInfeasibilities() const { + return sumDualInfeasibilities_; + } + inline void setSumDualInfeasibilities(double value) { + sumDualInfeasibilities_ = value; + } + /// Sum of relaxed dual infeasibilities + inline double sumOfRelaxedDualInfeasibilities() const { + return sumOfRelaxedDualInfeasibilities_; + } + inline void setSumOfRelaxedDualInfeasibilities(double value) { + sumOfRelaxedDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities + inline int numberDualInfeasibilities() const { + return numberDualInfeasibilities_; + } + inline void setNumberDualInfeasibilities(int value) { + numberDualInfeasibilities_ = value; + } + /// Number of dual infeasibilities (without free) + inline int numberDualInfeasibilitiesWithoutFree() const { + return numberDualInfeasibilitiesWithoutFree_; + } + /// Sum of primal infeasibilities + inline double sumPrimalInfeasibilities() const { + return sumPrimalInfeasibilities_; + } + inline void setSumPrimalInfeasibilities(double value) { + sumPrimalInfeasibilities_ = value; + } + /// Sum of relaxed primal infeasibilities + inline double sumOfRelaxedPrimalInfeasibilities() const { + return sumOfRelaxedPrimalInfeasibilities_; + } + inline void setSumOfRelaxedPrimalInfeasibilities(double value) { + sumOfRelaxedPrimalInfeasibilities_ = value; + } + /// Number of primal infeasibilities + inline int numberPrimalInfeasibilities() const { + return numberPrimalInfeasibilities_; + } + inline void setNumberPrimalInfeasibilities(int value) { + numberPrimalInfeasibilities_ = value; + } + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + int saveModel(const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + int restoreModel(const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc. + If setToBounds 0 then primal column values not changed + and used to compute primal row activity values. If 1 or 2 + then status used - so all nonbasic variables set to + indicated bound and if any values changed (or ==2) basic values re-computed. + */ + void checkSolution(int setToBounds = 0); + /** Just check solution (for internal use) - sets sum of + infeasibilities etc. */ + void checkSolutionInternal(); + /// Check unscaled primal solution but allow for rounding error + void checkUnscaledSolution(); + /// Useful row length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * rowArray(int index) const { + return rowArray_[index]; + } + /// Useful column length arrays (0,1,2,3,4,5) + inline CoinIndexedVector * columnArray(int index) const { + return columnArray_[index]; + } + //@} + + /******************** End of most useful part **************/ + /**@name Functions less likely to be useful to casual user */ + //@{ + /** Given an existing factorization computes and checks + primal and dual solutions. Uses input arrays for variables at + bounds. Returns feasibility states */ + int getSolution ( const double * rowActivities, + const double * columnActivities); + /** Given an existing factorization computes and checks + primal and dual solutions. Uses current problem arrays for + bounds. Returns feasibility states */ + int getSolution (); + /** Constructs a non linear cost from list of non-linearities (columns only) + First lower of each column is taken as real lower + Last lower is taken as real upper and cost ignored + + Returns nonzero if bad data e.g. lowers not monotonic + */ + int createPiecewiseLinearCosts(const int * starts, + const double * lower, const double * gradient); + /// dual row pivot choice + inline ClpDualRowPivot * dualRowPivot() const { + return dualRowPivot_; + } + /// primal column pivot choice + inline ClpPrimalColumnPivot * primalColumnPivot() const { + return primalColumnPivot_; + } + /// Returns true if model looks OK + inline bool goodAccuracy() const { + return (largestPrimalError_ < 1.0e-7 && largestDualError_ < 1.0e-7); + } + /** Return model - updates any scalars */ + void returnModel(ClpSimplex & otherModel); + /** Factorizes using current basis. + solveType - 1 iterating, 0 initial, -1 external + If 10 added then in primal values pass + Return codes are as from ClpFactorization unless initial factorization + when total number of singularities is returned. + Special case is numberRows_+1 -> all slack basis. + */ + int internalFactorize(int solveType); + /// Save data + ClpDataSave saveData() ; + /// Restore data + void restoreData(ClpDataSave saved); + /// Clean up status + void cleanStatus(); + /// Factorizes using current basis. For external use + int factorize(); + /** Computes duals from scratch. If givenDjs then + allows for nonzero basic djs */ + void computeDuals(double * givenDjs); + /// Computes primals from scratch + void computePrimals ( const double * rowActivities, + const double * columnActivities); + /** Adds multiple of a column into an array */ + void add(double * array, + int column, double multiplier) const; + /** + Unpacks one column of the matrix into indexed array + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray) const ; + /** + Unpacks one column of the matrix into indexed array + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpack(CoinIndexedVector * rowArray, int sequence) const; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Uses sequenceIn_ + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray) ; + /** + Unpacks one column of the matrix into indexed array + ** as packed vector + Slack if sequence>= numberColumns + Also applies scaling if needed + */ + void unpackPacked(CoinIndexedVector * rowArray, int sequence); +#ifndef CLP_USER_DRIVEN +protected: +#endif + /** + This does basis housekeeping and does values for in/out variables. + Can also decide to re-factorize + */ + int housekeeping(double objectiveChange); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Primal) */ + void checkPrimalSolution(const double * rowActivities = NULL, + const double * columnActivies = NULL); + /** This sets largest infeasibility and most infeasible and sum + and number of infeasibilities (Dual) */ + void checkDualSolution(); + /** This sets sum and number of infeasibilities (Dual and Primal) */ + void checkBothSolutions(); + /** If input negative scales objective so maximum <= -value + and returns scale factor used. If positive unscales and also + redoes dual stuff + */ + double scaleObjective(double value); + /// Solve using Dantzig-Wolfe decomposition and maybe in parallel + int solveDW(CoinStructuredModel * model, ClpSolve & options); + /// Solve using Benders decomposition and maybe in parallel + int solveBenders(CoinStructuredModel * model, ClpSolve & options); +public: + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility + or incoming largest infeasibility. + If allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + void setValuesPassAction(double incomingInfeasibility, + double allowedInfeasibility); + /** Get a clean factorization - i.e. throw out singularities + may do more later */ + int cleanFactorization(int ifValuesPass); + //@} + /**@name most useful gets and sets */ + //@{ +public: + /// Initial value for alpha accuracy calculation (-1.0 off) + inline double alphaAccuracy() const { + return alphaAccuracy_; + } + inline void setAlphaAccuracy(double value) { + alphaAccuracy_ = value; + } +public: + /// Objective value + //inline double objectiveValue() const { + //return (objectiveValue_-bestPossibleImprovement_)*optimizationDirection_ - dblParam_[ClpObjOffset]; + //} + /// Set disaster handler + inline void setDisasterHandler(ClpDisasterHandler * handler) { + disasterArea_ = handler; + } + /// Get disaster handler + inline ClpDisasterHandler * disasterHandler() const { + return disasterArea_; + } + /// Large bound value (for complementarity etc) + inline double largeValue() const { + return largeValue_; + } + void setLargeValue( double value) ; + /// Largest error on Ax-b + inline double largestPrimalError() const { + return largestPrimalError_; + } + /// Largest error on basic duals + inline double largestDualError() const { + return largestDualError_; + } + /// Largest error on Ax-b + inline void setLargestPrimalError(double value) { + largestPrimalError_ = value; + } + /// Largest error on basic duals + inline void setLargestDualError(double value) { + largestDualError_ = value; + } + /// Get zero tolerance + inline double zeroTolerance() const { + return zeroTolerance_;/*factorization_->zeroTolerance();*/ + } + /// Set zero tolerance + inline void setZeroTolerance( double value) { + zeroTolerance_ = value; + } + /// Basic variables pivoting on which rows + inline int * pivotVariable() const { + return pivotVariable_; + } + /// If automatic scaling on + inline bool automaticScaling() const { + return automaticScale_ != 0; + } + inline void setAutomaticScaling(bool onOff) { + automaticScale_ = onOff ? 1 : 0; + } + /// Current dual tolerance + inline double currentDualTolerance() const { + return dualTolerance_; + } + inline void setCurrentDualTolerance(double value) { + dualTolerance_ = value; + } + /// Current primal tolerance + inline double currentPrimalTolerance() const { + return primalTolerance_; + } + inline void setCurrentPrimalTolerance(double value) { + primalTolerance_ = value; + } + /// How many iterative refinements to do + inline int numberRefinements() const { + return numberRefinements_; + } + void setNumberRefinements( int value) ; + /// Alpha (pivot element) for use by classes e.g. steepestedge + inline double alpha() const { + return alpha_; + } + inline void setAlpha(double value) { + alpha_ = value; + } + /// Reduced cost of last incoming for use by classes e.g. steepestedge + inline double dualIn() const { + return dualIn_; + } + /// Set reduced cost of last incoming to force error + inline void setDualIn(double value) { + dualIn_ = value; + } + /// Pivot Row for use by classes e.g. steepestedge + inline int pivotRow() const { + return pivotRow_; + } + inline void setPivotRow(int value) { + pivotRow_ = value; + } + /// value of incoming variable (in Dual) + double valueIncomingDual() const; + //@} + +#ifndef CLP_USER_DRIVEN +protected: +#endif + /**@name protected methods */ + //@{ + /** May change basis and then returns number changed. + Computation of solutions may be overriden by given pi and solution + */ + int gutsOfSolution ( double * givenDuals, + const double * givenPrimals, + bool valuesPass = false); + /// Does most of deletion (0 = all, 1 = most, 2 most + factorization) + void gutsOfDelete(int type); + /// Does most of copying + void gutsOfCopy(const ClpSimplex & rhs); + /** puts in format I like (rowLower,rowUpper) also see StandardMatrix + 1 bit does rows (now and columns), (2 bit does column bounds), 4 bit does objective(s). + 8 bit does solution scaling in + 16 bit does rowArray and columnArray indexed vectors + and makes row copy if wanted, also sets columnStart_ etc + Also creates scaling arrays if needed. It does scaling if needed. + 16 also moves solutions etc in to work arrays + On 16 returns false if problem "bad" i.e. matrix or bounds bad + If startFinishOptions is -1 then called by user in getSolution + so do arrays but keep pivotVariable_ + */ + bool createRim(int what, bool makeRowCopy = false, int startFinishOptions = 0); + /// Does rows and columns + void createRim1(bool initial); + /// Does objective + void createRim4(bool initial); + /// Does rows and columns and objective + void createRim5(bool initial); + /** releases above arrays and does solution scaling out. May also + get rid of factorization data - + 0 get rid of nothing, 1 get rid of arrays, 2 also factorization + */ + void deleteRim(int getRidOfFactorizationData = 2); + /// Sanity check on input rim data (after scaling) - returns true if okay + bool sanityCheck(); + //@} +public: + /**@name public methods */ + //@{ + /** Return row or column sections - not as much needed as it + once was. These just map into single arrays */ + inline double * solutionRegion(int section) const { + if (!section) return rowActivityWork_; + else return columnActivityWork_; + } + inline double * djRegion(int section) const { + if (!section) return rowReducedCost_; + else return reducedCostWork_; + } + inline double * lowerRegion(int section) const { + if (!section) return rowLowerWork_; + else return columnLowerWork_; + } + inline double * upperRegion(int section) const { + if (!section) return rowUpperWork_; + else return columnUpperWork_; + } + inline double * costRegion(int section) const { + if (!section) return rowObjectiveWork_; + else return objectiveWork_; + } + /// Return region as single array + inline double * solutionRegion() const { + return solution_; + } + inline double * djRegion() const { + return dj_; + } + inline double * lowerRegion() const { + return lower_; + } + inline double * upperRegion() const { + return upper_; + } + inline double * costRegion() const { + return cost_; + } + inline Status getStatus(int sequence) const { + return static_cast<Status> (status_[sequence] & 7); + } + inline void setStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + /// Start or reset using maximumRows_ and Columns_ - true if change + bool startPermanentArrays(); + /** Normally the first factorization does sparse coding because + the factorization could be singular. This allows initial dense + factorization when it is known to be safe + */ + void setInitialDenseFactorization(bool onOff); + bool initialDenseFactorization() const; + /** Return sequence In or Out */ + inline int sequenceIn() const { + return sequenceIn_; + } + inline int sequenceOut() const { + return sequenceOut_; + } + /** Set sequenceIn or Out */ + inline void setSequenceIn(int sequence) { + sequenceIn_ = sequence; + } + inline void setSequenceOut(int sequence) { + sequenceOut_ = sequence; + } + /** Return direction In or Out */ + inline int directionIn() const { + return directionIn_; + } + inline int directionOut() const { + return directionOut_; + } + /** Set directionIn or Out */ + inline void setDirectionIn(int direction) { + directionIn_ = direction; + } + inline void setDirectionOut(int direction) { + directionOut_ = direction; + } + /// Value of Out variable + inline double valueOut() const { + return valueOut_; + } + /// Set value of out variable + inline void setValueOut(double value) { + valueOut_ = value; + } + /// Dual value of Out variable + inline double dualOut() const { + return dualOut_; + } + /// Set dual value of out variable + inline void setDualOut(double value) { + dualOut_ = value; + } + /// Set lower of out variable + inline void setLowerOut(double value) { + lowerOut_ = value; + } + /// Set upper of out variable + inline void setUpperOut(double value) { + upperOut_ = value; + } + /// Set theta of out variable + inline void setTheta(double value) { + theta_ = value; + } + /// Returns 1 if sequence indicates column + inline int isColumn(int sequence) const { + return sequence < numberColumns_ ? 1 : 0; + } + /// Returns sequence number within section + inline int sequenceWithin(int sequence) const { + return sequence < numberColumns_ ? sequence : sequence - numberColumns_; + } + /// Return row or column values + inline double solution(int sequence) { + return solution_[sequence]; + } + /// Return address of row or column values + inline double & solutionAddress(int sequence) { + return solution_[sequence]; + } + inline double reducedCost(int sequence) { + return dj_[sequence]; + } + inline double & reducedCostAddress(int sequence) { + return dj_[sequence]; + } + inline double lower(int sequence) { + return lower_[sequence]; + } + /// Return address of row or column lower bound + inline double & lowerAddress(int sequence) { + return lower_[sequence]; + } + inline double upper(int sequence) { + return upper_[sequence]; + } + /// Return address of row or column upper bound + inline double & upperAddress(int sequence) { + return upper_[sequence]; + } + inline double cost(int sequence) { + return cost_[sequence]; + } + /// Return address of row or column cost + inline double & costAddress(int sequence) { + return cost_[sequence]; + } + /// Return original lower bound + inline double originalLower(int iSequence) const { + if (iSequence < numberColumns_) return columnLower_[iSequence]; + else + return rowLower_[iSequence-numberColumns_]; + } + /// Return original lower bound + inline double originalUpper(int iSequence) const { + if (iSequence < numberColumns_) return columnUpper_[iSequence]; + else + return rowUpper_[iSequence-numberColumns_]; + } + /// Theta (pivot change) + inline double theta() const { + return theta_; + } + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + inline double bestPossibleImprovement() const { + return bestPossibleImprovement_; + } + /// Return pointer to details of costs + inline ClpNonLinearCost * nonLinearCost() const { + return nonLinearCost_; + } + /** Return more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - if factorization kept can still declare optimal at once + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + */ + inline int moreSpecialOptions() const { + return moreSpecialOptions_; + } + /** Set more special options + 1 bit - if presolve says infeasible in ClpSolve return + 2 bit - if presolved problem infeasible return + 4 bit - keep arrays like upper_ around + 8 bit - no free or superBasic variables + 16 bit - if checking replaceColumn accuracy before updating + 32 bit - say optimal if primal feasible! + 64 bit - give up easily in dual (and say infeasible) + 128 bit - no objective, 0-1 and in B&B + 256 bit - in primal from dual or vice versa + 512 bit - alternative use of solveType_ + 1024 bit - don't do row copy of factorization + 2048 bit - perturb in complete fathoming + 4096 bit - try more for complete fathoming + 8192 bit - don't even think of using primal if user asks for dual (and vv) + 16384 bit - in initialSolve so be more flexible + 32768 bit - don't swap algorithms from dual if small infeasibility + 65536 bit - perturb in postsolve cleanup (even if < 10000 rows) + 131072 bit (*3) initial stateDualColumn + 524288 bit - stop when primal feasible + 1048576 bit - don't perturb even if long time + 2097152 bit - no primal in fastDual2 if feasible + 4194304 bit - tolerances have been changed by code + 8388608 bit - tolerances are dynamic (at first) + */ + inline void setMoreSpecialOptions(int value) { + moreSpecialOptions_ = value; + } + //@} + /**@name status methods */ + //@{ + inline void setFakeBound(int sequence, FakeBound fakeBound) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~24); + st_byte = static_cast<unsigned char>(st_byte | (fakeBound << 3)); + } + inline FakeBound getFakeBound(int sequence) const { + return static_cast<FakeBound> ((status_[sequence] >> 3) & 3); + } + inline void setRowStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence+numberColumns_]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + inline Status getRowStatus(int sequence) const { + return static_cast<Status> (status_[sequence+numberColumns_] & 7); + } + inline void setColumnStatus(int sequence, Status newstatus) { + unsigned char & st_byte = status_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & ~7); + st_byte = static_cast<unsigned char>(st_byte | newstatus); + } + inline Status getColumnStatus(int sequence) const { + return static_cast<Status> (status_[sequence] & 7); + } + inline void setPivoted( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] | 32); + } + inline void clearPivoted( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~32); + } + inline bool pivoted(int sequence) const { + return (((status_[sequence] >> 5) & 1) != 0); + } + /// To flag a variable (not inline to allow for column generation) + void setFlagged( int sequence); + inline void clearFlagged( int sequence) { + status_[sequence] = static_cast<unsigned char>(status_[sequence] & ~64); + } + inline bool flagged(int sequence) const { + return ((status_[sequence] & 64) != 0); + } + /// To say row active in primal pivot row choice + inline void setActive( int iRow) { + status_[iRow] = static_cast<unsigned char>(status_[iRow] | 128); + } + inline void clearActive( int iRow) { + status_[iRow] = static_cast<unsigned char>(status_[iRow] & ~128); + } + inline bool active(int iRow) const { + return ((status_[iRow] & 128) != 0); + } + /// To say perturbed + inline void setPerturbed( int iSequence) { + status_[iSequence] = static_cast<unsigned char>(status_[iSequence] | 128); + } + inline void clearPerturbed( int iSequence) { + status_[iSequence] = static_cast<unsigned char>(status_[iSequence] & ~128); + } + inline bool perturbed(int iSequence) const { + return ((status_[iSequence] & 128) != 0); + } + /** Set up status array (can be used by OsiClp). + Also can be used to set up all slack basis */ + void createStatus() ; + /** Sets up all slack basis and resets solution to + as it was after initial load or readMps */ + void allSlackBasis(bool resetSolution = false); + + /// So we know when to be cautious + inline int lastBadIteration() const { + return lastBadIteration_; + } + /// Set so we know when to be cautious + inline void setLastBadIteration(int value) { + lastBadIteration_=value; + } + /// Progress flag - at present 0 bit says artificials out + inline int progressFlag() const { + return (progressFlag_ & 3); + } + /// For dealing with all issues of cycling etc + inline ClpSimplexProgress * progress() + { return &progress_;} + /// Force re-factorization early value + inline int forceFactorization() const { + return forceFactorization_ ; + } + /// Force re-factorization early + inline void forceFactorization(int value) { + forceFactorization_ = value; + } + /// Raw objective value (so always minimize in primal) + inline double rawObjectiveValue() const { + return objectiveValue_; + } + /// Compute objective value from solution and put in objectiveValue_ + void computeObjectiveValue(bool useWorkingSolution = false); + /// Compute minimization objective value from internal solution without perturbation + double computeInternalObjectiveValue(); + /** Infeasibility/unbounded ray (NULL returned if none/wrong) + Up to user to use delete [] on these arrays. */ + double * infeasibilityRay(bool fullRay=false) const; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + inline int numberExtraRows() const { + return numberExtraRows_; + } + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + inline int maximumBasic() const { + return maximumBasic_; + } + /// Iteration when we entered dual or primal + inline int baseIteration() const { + return baseIteration_; + } + /// Create C++ lines to get to current state + void generateCpp( FILE * fp, bool defaultFactor = false); + /// Gets clean and emptyish factorization + ClpFactorization * getEmptyFactorization(); + /// May delete or may make clean and emptyish factorization + void setEmptyFactorization(); + /// Move status and solution across + void moveInfo(const ClpSimplex & rhs, bool justStatus = false); + //@} + + ///@name Basis handling + // These are only to be used using startFinishOptions (ClpSimplexDual, ClpSimplexPrimal) + // *** At present only without scaling + // *** Slacks havve -1.0 element (so == row activity) - take care + ///Get a row of the tableau (slack part in slack if not NULL) + void getBInvARow(int row, double* z, double * slack = NULL); + + ///Get a row of the basis inverse + void getBInvRow(int row, double* z); + + ///Get a column of the tableau + void getBInvACol(int col, double* vec); + + ///Get a column of the basis inverse + void getBInvCol(int col, double* vec); + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + void getBasics(int* index); + + //@} + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + void setObjectiveCoefficient( int elementIndex, double elementValue ); + /** Set an objective function coefficient */ + inline void setObjCoeff( int elementIndex, double elementValue ) { + setObjectiveCoefficient( elementIndex, elementValue); + } + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + void setColumnLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + void setColumnUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + void setColumnBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + void setColumnSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + inline void setColLower( int elementIndex, double elementValue ) { + setColumnLower(elementIndex, elementValue); + } + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + inline void setColUpper( int elementIndex, double elementValue ) { + setColumnUpper(elementIndex, elementValue); + } + + /** Set a single column lower and upper bound */ + inline void setColBounds( int elementIndex, + double newlower, double newupper ) { + setColumnBounds(elementIndex, newlower, newupper); + } + + /** Set the bounds on a number of columns simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + inline void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList) { + setColumnSetBounds(indexFirst, indexLast, boundList); + } + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the bounds on a number of rows simultaneously<br> + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + /// Resizes rim part of model + void resize (int newNumberRows, int newNumberColumns); + + //@} + +////////////////// data ////////////////// +protected: + + /**@name data. Many arrays have a row part and a column part. + There is a single array with both - columns then rows and + then normally two arrays pointing to rows and columns. The + single array is the owner of memory + */ + //@{ + /** Best possible improvement using djs (primal) or + obj change by flipping bounds to make dual feasible (dual) */ + double bestPossibleImprovement_; + /// Zero tolerance + double zeroTolerance_; + /// Sequence of worst (-1 if feasible) + int columnPrimalSequence_; + /// Sequence of worst (-1 if feasible) + int rowPrimalSequence_; + /// "Best" objective value + double bestObjectiveValue_; + /// More special options - see set for details + int moreSpecialOptions_; + /// Iteration when we entered dual or primal + int baseIteration_; + /// Primal tolerance needed to make dual feasible (<largeTolerance) + double primalToleranceToGetOptimal_; + /// Large bound value (for complementarity etc) + double largeValue_; + /// Largest error on Ax-b + double largestPrimalError_; + /// Largest error on basic duals + double largestDualError_; + /// For computing whether to re-factorize + double alphaAccuracy_; + /// Dual bound + double dualBound_; + /// Alpha (pivot element) + double alpha_; + /// Theta (pivot change) + double theta_; + /// Lower Bound on In variable + double lowerIn_; + /// Value of In variable + double valueIn_; + /// Upper Bound on In variable + double upperIn_; + /// Reduced cost of In variable + double dualIn_; + /// Lower Bound on Out variable + double lowerOut_; + /// Value of Out variable + double valueOut_; + /// Upper Bound on Out variable + double upperOut_; + /// Infeasibility (dual) or ? (primal) of Out variable + double dualOut_; + /// Current dual tolerance for algorithm + double dualTolerance_; + /// Current primal tolerance for algorithm + double primalTolerance_; + /// Sum of dual infeasibilities + double sumDualInfeasibilities_; + /// Sum of primal infeasibilities + double sumPrimalInfeasibilities_; + /// Weight assigned to being infeasible in primal + double infeasibilityCost_; + /// Sum of Dual infeasibilities using tolerance based on error in duals + double sumOfRelaxedDualInfeasibilities_; + /// Sum of Primal infeasibilities using tolerance based on error in primals + double sumOfRelaxedPrimalInfeasibilities_; + /// Acceptable pivot value just after factorization + double acceptablePivot_; + /// Minimum primal tolerance + double minimumPrimalTolerance_; + /// Last few infeasibilities +#define CLP_INFEAS_SAVE 5 + double averageInfeasibility_[CLP_INFEAS_SAVE]; + /// Working copy of lower bounds (Owner of arrays below) + double * lower_; + /// Row lower bounds - working copy + double * rowLowerWork_; + /// Column lower bounds - working copy + double * columnLowerWork_; + /// Working copy of upper bounds (Owner of arrays below) + double * upper_; + /// Row upper bounds - working copy + double * rowUpperWork_; + /// Column upper bounds - working copy + double * columnUpperWork_; + /// Working copy of objective (Owner of arrays below) + double * cost_; + /// Row objective - working copy + double * rowObjectiveWork_; + /// Column objective - working copy + double * objectiveWork_; + /// Useful row length arrays + CoinIndexedVector * rowArray_[6]; + /// Useful column length arrays + CoinIndexedVector * columnArray_[6]; + /// Sequence of In variable + int sequenceIn_; + /// Direction of In, 1 going up, -1 going down, 0 not a clude + int directionIn_; + /// Sequence of Out variable + int sequenceOut_; + /// Direction of Out, 1 to upper bound, -1 to lower bound, 0 - superbasic + int directionOut_; + /// Pivot Row + int pivotRow_; + /// Last good iteration (immediately after a re-factorization) + int lastGoodIteration_; + /// Working copy of reduced costs (Owner of arrays below) + double * dj_; + /// Reduced costs of slacks not same as duals (or - duals) + double * rowReducedCost_; + /// Possible scaled reduced costs + double * reducedCostWork_; + /// Working copy of primal solution (Owner of arrays below) + double * solution_; + /// Row activities - working copy + double * rowActivityWork_; + /// Column activities - working copy + double * columnActivityWork_; + /// Number of dual infeasibilities + int numberDualInfeasibilities_; + /// Number of dual infeasibilities (without free) + int numberDualInfeasibilitiesWithoutFree_; + /// Number of primal infeasibilities + int numberPrimalInfeasibilities_; + /// How many iterative refinements to do + int numberRefinements_; + /// dual row pivot choice + ClpDualRowPivot * dualRowPivot_; + /// primal column pivot choice + ClpPrimalColumnPivot * primalColumnPivot_; + /// Basic variables pivoting on which rows + int * pivotVariable_; + /// factorization + ClpFactorization * factorization_; + /// Saved version of solution + double * savedSolution_; + /// Number of times code has tentatively thought optimal + int numberTimesOptimal_; + /// Disaster handler + ClpDisasterHandler * disasterArea_; + /// If change has been made (first attempt at stopping looping) + int changeMade_; + /// Algorithm >0 == Primal, <0 == Dual + int algorithm_; + /** Now for some reliability aids + This forces re-factorization early */ + int forceFactorization_; + /** Perturbation: + -50 to +50 - perturb by this power of ten (-6 sounds good) + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + */ + int perturbation_; + /// Saved status regions + unsigned char * saveStatus_; + /** Very wasteful way of dealing with infeasibilities in primal. + However it will allow non-linearities and use of dual + analysis. If it doesn't work it can easily be replaced. + */ + ClpNonLinearCost * nonLinearCost_; + /// So we know when to be cautious + int lastBadIteration_; + /// So we know when to open up again + int lastFlaggedIteration_; + /// Can be used for count of fake bounds (dual) or fake costs (primal) + int numberFake_; + /// Can be used for count of changed costs (dual) or changed bounds (primal) + int numberChanged_; + /// Progress flag - at present 0 bit says artificials out, 1 free in + int progressFlag_; + /// First free/super-basic variable (-1 if none) + int firstFree_; + /** Number of extra rows. These are ones which will be dynamically created + each iteration. This is for GUB but may have other uses. + */ + int numberExtraRows_; + /** Maximum number of basic variables - can be more than number of rows if GUB + */ + int maximumBasic_; + /// If may skip final factorize then allow up to this pivots (default 20) + int dontFactorizePivots_; + /** For advanced use. When doing iterative solves things can get + nasty so on values pass if incoming solution has largest + infeasibility < incomingInfeasibility throw out variables + from basis until largest infeasibility < allowedInfeasibility. + if allowedInfeasibility>= incomingInfeasibility this is + always possible altough you may end up with an all slack basis. + + Defaults are 1.0,10.0 + */ + double incomingInfeasibility_; + double allowedInfeasibility_; + /// Automatic scaling of objective and rhs and bounds + int automaticScale_; + /// Maximum perturbation array size (take out when code rewritten) + int maximumPerturbationSize_; + /// Perturbation array (maximumPerturbationSize_) + double * perturbationArray_; + /// A copy of model with certain state - normally without cuts + ClpSimplex * baseModel_; + /// For dealing with all issues of cycling etc + ClpSimplexProgress progress_; +#ifdef ABC_INHERIT + AbcSimplex * abcSimplex_; +#define CLP_ABC_WANTED 1 +#define CLP_ABC_WANTED_PARALLEL 2 +#define CLP_ABC_FULL_DONE 8 + // bits 256,512,1024 for crash +#endif +#define CLP_ABC_BEEN_FEASIBLE 65536 + int abcState_; + /// Number of degenerate pivots since last perturbed + int numberDegeneratePivots_; +public: + /// Spare int array for passing information [0]!=0 switches on + mutable int spareIntArray_[4]; + /// Spare double array for passing information [0]!=0 switches on + mutable double spareDoubleArray_[4]; +protected: + /// Allow OsiClp certain perks + friend class OsiClpSolverInterface; + /// And OsiCLP + friend class OsiCLPSolverInterface; + //@} +}; +//############################################################################# +/** A function that tests the methods in the ClpSimplex class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. + + It also does some testing of ClpFactorization class + */ +void +ClpSimplexUnitTest(const std::string & mpsDir); + +// For Devex stuff +#define DEVEX_TRY_NORM 1.0e-4 +#define DEVEX_ADD_ONE 1.0 +#if defined(ABC_INHERIT) || defined(CBC_THREAD) || defined(THREADS_IN_ANALYZE) +// Use pthreads +#include <pthread.h> +typedef struct { + double result; + //const CoinIndexedVector * constVector; // can get rid of + //CoinIndexedVector * vectors[2]; // can get rid of + void * extraInfo; + void * extraInfo2; + int status; + int stuff[4]; +} CoinThreadInfo; +class CoinPthreadStuff { +public: + /**@name Constructors and destructor and copy */ + //@{ + /** Main constructor + */ + CoinPthreadStuff (int numberThreads=0, + void * parallelManager(void * stuff)=NULL); + /// Assignment operator. This copies the data + CoinPthreadStuff & operator=(const CoinPthreadStuff & rhs); + /// Destructor + ~CoinPthreadStuff ( ); + /// set stop start + inline void setStopStart(int value) + { stopStart_=value;} +#ifndef NUMBER_THREADS +#define NUMBER_THREADS 8 +#endif + // For waking up thread + inline pthread_mutex_t * mutexPointer(int which,int thread=0) + { return mutex_+which+3*thread;} +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + inline pthread_barrier_t * barrierPointer() + { return &barrier_;} +#endif + inline int whichLocked(int thread=0) const + { return locked_[thread];} + inline CoinThreadInfo * threadInfoPointer(int thread=0) + { return threadInfo_+thread;} + void startParallelTask(int type,int iThread,void * info=NULL); + int waitParallelTask(int type, int & iThread,bool allowIdle); + void waitAllTasks(); + /// so thread can find out which one it is + int whichThread() const; + void sayIdle(int iThread); + //void startThreads(int numberThreads); + //void stopThreads(); + // For waking up thread + pthread_mutex_t mutex_[3*(NUMBER_THREADS+1)]; +#ifdef PTHREAD_BARRIER_SERIAL_THREAD + pthread_barrier_t barrier_; +#endif + CoinThreadInfo threadInfo_[NUMBER_THREADS+1]; + pthread_t abcThread_[NUMBER_THREADS+1]; + int locked_[NUMBER_THREADS+1]; + int stopStart_; + int numberThreads_; +}; +void * clp_parallelManager(void * stuff); +#endif +#endif diff --git a/thirdparty/linux/include/coin1/ClpSimplexDual.hpp b/thirdparty/linux/include/coin1/ClpSimplexDual.hpp new file mode 100644 index 0000000..77cc577 --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSimplexDual.hpp @@ -0,0 +1,300 @@ +/* $Id: ClpSimplexDual.hpp 1761 2011-07-06 16:06:24Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexDual_H +#define ClpSimplexDual_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the dual simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexDual : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Dual algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of updatedDualBound_ being + given to getting dual feasible. In this version I have used the + idea that this weight can be thought of as a fake bound. If the + distance between the lower and upper bounds on a variable is less + than the feasibility weight then we are always better off flipping + to other bound to make dual feasible. If the distance is greater + then we make up a fake bound updatedDualBound_ away from one bound. + If we end up optimal or primal infeasible, we check to see if + bounds okay. If so we have finished, if not we increase updatedDualBound_ + and continue (after checking if unbounded). I am undecided about + free variables - there is coding but I am not sure about it. At + present I put them in basis anyway. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find outgoing variable for + Dantzig row choice. For steepest edge we keep an updated list + of infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and some + of what I think is the dual analog of Gill et al. + I am still not sure of the exact details. + + The flow of dual is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by flipping variables so + dual feasible. If looks finished check fake dual bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot row (outgoing variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot row in tableau + + Choose incoming column. If we don't find one then we look + primal infeasible so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find incoming column, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve flipping variables to stay + dual feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot out option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int dual(int ifValuesPass, int startFinishOptions = 0); + /** For strong branching. On input lower and upper are new bounds + while on output they are change in objective function values + (>1.0e50 infeasible). + Return code is 0 if nothing interesting, -1 if infeasible both + ways and +1 if infeasible one way (check values to see which one(s)) + Solutions are filled in as well - even down, odd up - also + status and number of iterations + */ + int strongBranching(int numberVariables, const int * variables, + double * newLower, double * newUpper, + double ** outputSolution, + int * outputStatus, int * outputIterations, + bool stopOnFirstInfeasible = true, + bool alwaysFinish = false, + int startFinishOptions = 0); + /// This does first part of StrongBranching + ClpFactorization * setupForStrongBranching(char * arrays, int numberRows, + int numberColumns, bool solveLp = false); + /// This cleans up after strong branching + void cleanupAfterStrongBranching(ClpFactorization * factorization); + //@} + + /**@name Functions used in dual */ + //@{ + /** This has the flow between re-factorizations + Broken out for clarity and will be used by strong branching + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + + If givenPi not NULL then in values pass + */ + int whileIterating(double * & givenPi, int ifValuesPass); + /** The duals are updated by the given arrays. + Returns number of infeasibilities. + After rowArray and columnArray will just have those which + have been flipped. + Variables may be flipped between bounds to stay dual feasible. + The output vector has movement of primal + solution (row length array) */ + int updateDualsInDual(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * outputArray, + double theta, + double & objectiveChange, + bool fullRecompute); + /** The duals are updated by the given arrays. + This is in values pass - so no changes to primal is made + */ + void updateDualsInValuesPass(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double theta); + /** While updateDualsInDual sees what effect is of flip + this does actual flipping. + */ + void flipBounds(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray); + /** + Row array has row part of pivot row + Column array has column part. + This chooses pivot column. + Spare arrays are used to save pivots which will go infeasible + We will check for basic so spare array will never overflow. + If necessary will modify costs + For speed, we may need to go to a bucket approach when many + variables are being flipped. + Returns best possible pivot value + */ + double dualColumn(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + CoinIndexedVector * spareArray2, + double accpetablePivot, + CoinBigIndex * dubiousWeights); + /// Does first bit of dualColumn + int dualColumn0(const CoinIndexedVector * rowArray, + const CoinIndexedVector * columnArray, + CoinIndexedVector * spareArray, + double acceptablePivot, + double & upperReturn, double &bestReturn, double & badFree); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in dual values pass + if sequenceIn==sequenceOut can change dual on chosen row and leave variable in basis + */ + void checkPossibleValuesMove(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + Row array has row part of pivot row + Column array has column part. + This sees what is best thing to do in branch and bound cleanup + If sequenceIn_ < 0 then can't do anything + */ + void checkPossibleCleanup(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double acceptablePivot); + /** + This sees if we can move duals in dual values pass. + This is done before any pivoting + */ + void doEasyOnesInValuesPass(double * givenReducedCosts); + /** + Chooses dual pivot row + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first rows we look at + + If alreadyChosen >=0 then in values pass and that row has been + selected + */ + void dualRow(int alreadyChosen); + /** Checks if any fake bounds active - if so returns number and modifies + updatedDualBound_ and everything. + Free variables will be left as free + Returns number of bounds changed if >=0 + Returns -1 if not initialize and no effect + Fills in changeVector which can be used to see if unbounded + and cost of change vector + If 2 sets to original (just changed) + */ + int changeBounds(int initialize, CoinIndexedVector * outputArray, + double & changeCost); + /** As changeBounds but just changes new bounds for a single variable. + Returns true if change */ + bool changeBound( int iSequence); + /// Restores bound to original bound + void originalBound(int iSequence); + /** Checks if tentative optimal actually means unbounded in dual + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInDual(int & lastCleaned, int type, + double * givenDjs, ClpDataSave & saveData, + int ifValuesPass); + /** Perturbs problem (method depends on perturbation()) + returns nonzero if should go to dual */ + int perturb(); + /** Fast iterations. Misses out a lot of initialization. + Normally stops on maximum iterations, first re-factorization + or tentative optimum. If looks interesting then continues as + normal. Returns 0 if finished properly, 1 otherwise. + */ + int fastDual(bool alwaysFinish = false); + /** Checks number of variables at fake bounds. This is used by fastDual + so can exit gracefully before end */ + int numberAtFakeBound(); + + /** Pivot in a variable and choose an outgoing one. Assumes dual + feasible - will not go through a reduced cost. Returns step length in theta + Return codes as before but -1 means no acceptable pivot + */ + int pivotResultPart1(); + /** Get next free , -1 if none */ + int nextSuperBasic(); + /** Startup part of dual (may be extended to other algorithms) + returns 0 if good, 1 if bad */ + int startupSolve(int ifValuesPass, double * saveDuals, int startFinishOptions); + void finishSolve(int startFinishOptions); + void gutsOfDual(int ifValuesPass, double * & saveDuals, int initialStatus, + ClpDataSave & saveData); + //int dual2(int ifValuesPass,int startFinishOptions=0); + void resetFakeBounds(int type); + + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/ClpSimplexNonlinear.hpp b/thirdparty/linux/include/coin1/ClpSimplexNonlinear.hpp new file mode 100644 index 0000000..6c1088b --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSimplexNonlinear.hpp @@ -0,0 +1,117 @@ +/* $Id: ClpSimplexNonlinear.hpp 2025 2014-03-19 12:49:55Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexNonlinear_H +#define ClpSimplexNonlinear_H + +class ClpNonlinearInfo; +class ClpQuadraticObjective; +class ClpConstraint; + +#include "ClpSimplexPrimal.hpp" + +/** This solves non-linear LPs using the primal simplex method + + It inherits from ClpSimplexPrimal. It has no data of its own and + is never created - only cast from a ClpSimplexPrimal object at algorithm time. + If needed create new class and pass around + +*/ + +class ClpSimplexNonlinear : public ClpSimplexPrimal { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithms for reduced gradient + At present we have two algorithms: + + */ + /// A reduced gradient method. + int primal(); + /** Primal algorithm for quadratic + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + */ + int primalSLP(int numberPasses, double deltaTolerance, + int otherOptions=0); + /// May use a cut approach for solving any LP + int primalDualCuts(char * rowsIn, int startUp, int algorithm); + /** Primal algorithm for nonlinear constraints + Using a semi-trust region approach as for pooling problem + This is in because I have it lying around + + */ + int primalSLP(int numberConstraints, ClpConstraint ** constraints, + int numberPasses, double deltaTolerance); + + /** Creates direction vector. note longArray is long enough + for rows and columns. If numberNonBasic 0 then is updated + otherwise mode is ignored and those are used. + Norms are only for those > 1.0e3*dualTolerance + If mode is nonzero then just largest dj */ + void directionVector (CoinIndexedVector * longArray, + CoinIndexedVector * spare1, CoinIndexedVector * spare2, + int mode, + double & normFlagged, double & normUnflagged, + int & numberNonBasic); + /// Main part. + int whileIterating (int & pivotMode); + /** + longArray has direction + pivotMode - + 0 - use all dual infeasible variables + 1 - largest dj + while >= 10 trying startup phase + Returns 0 - can do normal iteration (basis change) + 1 - no basis change + 2 - if wants singleton + 3 - if time to re-factorize + If sequenceIn_ >=0 then that will be incoming variable + */ + int pivotColumn(CoinIndexedVector * longArray, + CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + CoinIndexedVector * spare, + int & pivotMode, + double & solutionError, + double * array1); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + double & bestObjectiveWhenFlagged); + /** Do last half of an iteration. + Return codes + Reasons to come out normal mode + -1 normal + -2 factorize now - good iteration + -3 slight inaccuracy - refactorize - iteration done + -4 inaccuracy - refactorize - no iteration + -5 something flagged - go round again + +2 looks unbounded + +3 max iterations (iteration done) + + */ + int pivotNonlinearResult(); + //@} + +}; +#endif + diff --git a/thirdparty/linux/include/coin1/ClpSimplexOther.hpp b/thirdparty/linux/include/coin1/ClpSimplexOther.hpp new file mode 100644 index 0000000..c5014ec --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSimplexOther.hpp @@ -0,0 +1,277 @@ +/* $Id: ClpSimplexOther.hpp 2070 2014-11-18 11:12:54Z forrest $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexOther_H +#define ClpSimplexOther_H + +#include "ClpSimplex.hpp" + +/** This is for Simplex stuff which is neither dual nor primal + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexOther : public ClpSimplex { + +public: + + /**@name Methods */ + //@{ + /** Dual ranging. + This computes increase/decrease in cost for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + For non-basic variables the information is trivial to compute and the change in cost is just minus the + reduced cost and the sequence number will be that of the non-basic variables. + For basic variables a ratio test is between the reduced costs for non-basic variables + and the row of the tableau corresponding to the basic variable. + The increase/decrease value is always >= 0.0 + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + If valueIncrease/Decrease not NULL (both must be NULL or both non NULL) then these are filled with + the value of variable if such a change in cost were made (the existing bounds are ignored) + + When here - guaranteed optimal + */ + void dualRanging(int numberCheck, const int * which, + double * costIncrease, int * sequenceIncrease, + double * costDecrease, int * sequenceDecrease, + double * valueIncrease = NULL, double * valueDecrease = NULL); + /** Primal ranging. + This computes increase/decrease in value for each given variable and corresponding + sequence numbers which would change basis. Sequence numbers are 0..numberColumns + and numberColumns.. for artificials/slacks. + This should only be used for non-basic variabls as otherwise information is pretty useless + For basic variables the sequence number will be that of the basic variables. + + Up to user to provide correct length arrays where each array is of length numberCheck. + which contains list of variables for which information is desired. All other + arrays will be filled in by function. If fifth entry in which is variable 7 then fifth entry in output arrays + will be information for variable 7. + + When here - guaranteed optimal + */ + void primalRanging(int numberCheck, const int * which, + double * valueIncrease, int * sequenceIncrease, + double * valueDecrease, int * sequenceDecrease); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + and similarly for objective. + It starts at startingTheta and returns ending theta in endingTheta. + If reportIncrement 0.0 it will report on any movement + If reportIncrement >0.0 it will report at startingTheta+k*reportIncrement. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, double reportIncrement, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs, + const double * changeObjective); + /** Version of parametrics which reads from file + See CbcClpParam.cpp for details of format + Returns -2 if unable to open file */ + int parametrics(const char * dataFile); + /** Parametrics + This is an initial slow version. + The code uses current bounds + theta * change (if change array not NULL) + It starts at startingTheta and returns ending theta in endingTheta. + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, if error on ranges -1, otherwise 0. + Event handler may do more + On exit endingTheta is maximum reached (can be used for next startingTheta) + */ + int parametrics(double startingTheta, double & endingTheta, + const double * changeLowerBound, const double * changeUpperBound, + const double * changeLowerRhs, const double * changeUpperRhs); + int parametricsObj(double startingTheta, double & endingTheta, + const double * changeObjective); + /// Finds best possible pivot + double bestPivot(bool justColumns=false); + typedef struct { + double startingTheta; + double endingTheta; + double maxTheta; + double acceptableMaxTheta; // if this far then within tolerances + double * lowerChange; // full array of lower bound changes + int * lowerList; // list of lower bound changes + double * upperChange; // full array of upper bound changes + int * upperList; // list of upper bound changes + char * markDone; // mark which ones looked at + int * backwardBasic; // from sequence to pivot row + int * lowerActive; + double * lowerGap; + double * lowerCoefficient; + int * upperActive; + double * upperGap; + double * upperCoefficient; + int unscaledChangesOffset; + bool firstIteration; // so can update rhs for accuracy + } parametricsData; + +private: + /** Parametrics - inner loop + This first attempt is when reportIncrement non zero and may + not report endingTheta correctly + If it can not reach input endingTheta return code will be 1 for infeasible, + 2 for unbounded, otherwise 0. + Normal report is just theta and objective but + if event handler exists it may do more + */ + int parametricsLoop(parametricsData & paramData, double reportIncrement, + const double * changeLower, const double * changeUpper, + const double * changeObjective, ClpDataSave & data, + bool canTryQuick); + int parametricsLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + int parametricsObjLoop(parametricsData & paramData, + ClpDataSave & data,bool canSkipFactorization=false); + /** Refactorizes if necessary + Checks if finished. Updates status. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + */ + void statusOfProblemInParametrics(int type, ClpDataSave & saveData); + void statusOfProblemInParametricsObj(int type, ClpDataSave & saveData); + /** This has the flow between re-factorizations + + Reasons to come out: + -1 iterations etc + -2 inaccuracy + -3 slight inaccuracy (and done iterations) + +0 looks optimal (might be unbounded - but we will investigate) + +1 looks infeasible + +3 max iterations + */ + int whileIterating(parametricsData & paramData, double reportIncrement, + const double * changeObjective); + /** Computes next theta and says if objective or bounds (0= bounds, 1 objective, -1 none). + theta is in theta_. + type 1 bounds, 2 objective, 3 both. + */ + int nextTheta(int type, double maxTheta, parametricsData & paramData, + const double * changeObjective); + int whileIteratingObj(parametricsData & paramData); + int nextThetaObj(double maxTheta, parametricsData & paramData); + /// Restores bound to original bound + void originalBound(int iSequence, double theta, const double * changeLower, + const double * changeUpper); + /// Compute new rowLower_ etc (return negative if infeasible - otherwise largest change) + double computeRhsEtc(parametricsData & paramData); + /// Redo lower_ from rowLower_ etc + void redoInternalArrays(); + /** + Row array has row part of pivot row + Column array has column part. + This is used in dual ranging + */ + void checkDualRatios(CoinIndexedVector * rowArray, + CoinIndexedVector * columnArray, + double & costIncrease, int & sequenceIncrease, double & alphaIncrease, + double & costDecrease, int & sequenceDecrease, double & alphaDecrease); + /** + Row array has pivot column + This is used in primal ranging + */ + void checkPrimalRatios(CoinIndexedVector * rowArray, + int direction); + /// Returns new value of whichOther when whichIn enters basis + double primalRanging1(int whichIn, int whichOther); + +public: + /** Write the basis in MPS format to the specified file. + If writeValues true writes values of structurals + (and adds VALUES to end of NAME card) + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex (later) + </ul> + + Returns non-zero on I/O error + */ + int writeBasis(const char *filename, + bool writeValues = false, + int formatType = 0) const; + /// Read a basis from the given filename + int readBasis(const char *filename); + /** Creates dual of a problem if looks plausible + (defaults will always create model) + fractionRowRanges is fraction of rows allowed to have ranges + fractionColumnRanges is fraction of columns allowed to have ranges + */ + ClpSimplex * dualOfModel(double fractionRowRanges = 1.0, double fractionColumnRanges = 1.0) const; + /** Restores solution from dualized problem + non-zero return code indicates minor problems + */ + int restoreFromDual(const ClpSimplex * dualProblem, + bool checkAccuracy=false); + /** Sets solution in dualized problem + non-zero return code indicates minor problems + */ + int setInDual(ClpSimplex * dualProblem); + /** Does very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + ClpSimplex * crunch(double * rhs, int * whichRows, int * whichColumns, + int & nBound, bool moreBounds = false, bool tightenBounds = false); + /** After very cursory presolve. + rhs is numberRows, whichRows is 3*numberRows and whichColumns is 2*numberColumns. + */ + void afterCrunch(const ClpSimplex & small, + const int * whichRows, const int * whichColumns, + int nBound); + /** Returns gub version of model or NULL + whichRows has to be numberRows + whichColumns has to be numberRows+numberColumns */ + ClpSimplex * gubVersion(int * whichRows, int * whichColumns, + int neededGub, + int factorizationFrequency=50); + /// Sets basis from original + void setGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns); + /// Restores basis to original + void getGubBasis(ClpSimplex &original,const int * whichRows, + const int * whichColumns) const; + /// Quick try at cleaning up duals if postsolve gets wrong + void cleanupAfterPostsolve(); + /** Tightens integer bounds - returns number tightened or -1 if infeasible + */ + int tightenIntegerBounds(double * rhsSpace); + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput, + double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement, int reConstruct = -1) const; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/ClpSimplexPrimal.hpp b/thirdparty/linux/include/coin1/ClpSimplexPrimal.hpp new file mode 100644 index 0000000..d78e54e --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSimplexPrimal.hpp @@ -0,0 +1,244 @@ +/* $Id: ClpSimplexPrimal.hpp 1665 2011-01-04 17:55:54Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSimplexPrimal_H +#define ClpSimplexPrimal_H + +#include "ClpSimplex.hpp" + +/** This solves LPs using the primal simplex method + + It inherits from ClpSimplex. It has no data of its own and + is never created - only cast from a ClpSimplex object at algorithm time. + +*/ + +class ClpSimplexPrimal : public ClpSimplex { + +public: + + /**@name Description of algorithm */ + //@{ + /** Primal algorithm + + Method + + It tries to be a single phase approach with a weight of 1.0 being + given to getting optimal and a weight of infeasibilityCost_ being + given to getting primal feasible. In this version I have tried to + be clever in a stupid way. The idea of fake bounds in dual + seems to work so the primal analogue would be that of getting + bounds on reduced costs (by a presolve approach) and using + these for being above or below feasible region. I decided to waste + memory and keep these explicitly. This allows for non-linear + costs! I have not tested non-linear costs but will be glad + to do something if a reasonable example is provided. + + The code is designed to take advantage of sparsity so arrays are + seldom zeroed out from scratch or gone over in their entirety. + The only exception is a full scan to find incoming variable for + Dantzig row choice. For steepest edge we keep an updated list + of dual infeasibilities (actually squares). + On easy problems we don't need full scan - just + pick first reasonable. This method has not been coded. + + One problem is how to tackle degeneracy and accuracy. At present + I am using the modification of costs which I put in OSL and which was + extended by Gill et al. I am still not sure whether we will also + need explicit perturbation. + + The flow of primal is three while loops as follows: + + while (not finished) { + + while (not clean solution) { + + Factorize and/or clean up solution by changing bounds so + primal feasible. If looks finished check fake primal bounds. + Repeat until status is iterating (-1) or finished (0,1,2) + + } + + while (status==-1) { + + Iterate until no pivot in or out or time to re-factorize. + + Flow is: + + choose pivot column (incoming variable). if none then + we are primal feasible so looks as if done but we need to + break and check bounds etc. + + Get pivot column in tableau + + Choose outgoing row. If we don't find one then we look + primal unbounded so break and check bounds etc. (Also the + pivot tolerance is larger after any iterations so that may be + reason) + + If we do find outgoing row, we may have to adjust costs to + keep going forwards (anti-degeneracy). Check pivot will be stable + and if unstable throw away iteration and break to re-factorize. + If minor error re-factorize after iteration. + + Update everything (this may involve changing bounds on + variables to stay primal feasible. + + } + + } + + TODO's (or maybe not) + + At present we never check we are going forwards. I overdid that in + OSL so will try and make a last resort. + + Needs partial scan pivot in option. + + May need other anti-degeneracy measures, especially if we try and use + loose tolerances as a way to solve in fewer iterations. + + I like idea of dynamic scaling. This gives opportunity to decouple + different implications of scaling for accuracy, iteration count and + feasibility tolerance. + + for use of exotic parameter startFinishoptions see Clpsimplex.hpp + */ + + int primal(int ifValuesPass = 0, int startFinishOptions = 0); + //@} + + /**@name For advanced users */ + //@{ + /// Do not change infeasibility cost and always say optimal + void alwaysOptimal(bool onOff); + bool alwaysOptimal() const; + /** Normally outgoing variables can go out to slightly negative + values (but within tolerance) - this is to help stability and + and degeneracy. This can be switched off + */ + void exactOutgoing(bool onOff); + bool exactOutgoing() const; + //@} + + /**@name Functions used in primal */ + //@{ + /** This has the flow between re-factorizations + + Returns a code to say where decision to exit was made + Problem status set to: + + -2 re-factorize + -4 Looks optimal/infeasible + -5 Looks unbounded + +3 max iterations + + valuesOption has original value of valuesPass + */ + int whileIterating(int valuesOption); + + /** Do last half of an iteration. This is split out so people can + force incoming variable. If solveType_ is 2 then this may + re-factorize while normally it would exit to re-factorize. + Return codes + Reasons to come out (normal mode/user mode): + -1 normal + -2 factorize now - good iteration/ NA + -3 slight inaccuracy - refactorize - iteration done/ same but factor done + -4 inaccuracy - refactorize - no iteration/ NA + -5 something flagged - go round again/ pivot not possible + +2 looks unbounded + +3 max iterations (iteration done) + + With solveType_ ==2 this should + Pivot in a variable and choose an outgoing one. Assumes primal + feasible - will not go through a bound. Returns step length in theta + Returns ray in ray_ + */ + int pivotResult(int ifValuesPass = 0); + + + /** The primals are updated by the given array. + Returns number of infeasibilities. + After rowArray will have cost changes for use next iteration + */ + int updatePrimalsInPrimal(CoinIndexedVector * rowArray, + double theta, + double & objectiveChange, + int valuesPass); + /** + Row array has pivot column + This chooses pivot row. + Rhs array is used for distance to next bound (for speed) + For speed, we may need to go to a bucket approach when many + variables go through bounds + If valuesPass non-zero then compute dj for direction + */ + void primalRow(CoinIndexedVector * rowArray, + CoinIndexedVector * rhsArray, + CoinIndexedVector * spareArray, + int valuesPass); + /** + Chooses primal pivot column + updateArray has cost updates (also use pivotRow_ from last iteration) + Would be faster with separate region to scan + and will have this (with square of infeasibility) when steepest + For easy problems we can just choose one of the first columns we look at + */ + void primalColumn(CoinIndexedVector * updateArray, + CoinIndexedVector * spareRow1, + CoinIndexedVector * spareRow2, + CoinIndexedVector * spareColumn1, + CoinIndexedVector * spareColumn2); + + /** Checks if tentative optimal actually means unbounded in primal + Returns -3 if not, 2 if is unbounded */ + int checkUnbounded(CoinIndexedVector * ray, CoinIndexedVector * spare, + double changeCost); + /** Refactorizes if necessary + Checks if finished. Updates status. + lastCleaned refers to iteration at which some objective/feasibility + cleaning too place. + + type - 0 initial so set up save arrays etc + - 1 normal -if good update save + - 2 restoring from saved + saveModel is normally NULL but may not be if doing Sprint + */ + void statusOfProblemInPrimal(int & lastCleaned, int type, + ClpSimplexProgress * progress, + bool doFactorization, + int ifValuesPass, + ClpSimplex * saveModel = NULL); + /// Perturbs problem (method depends on perturbation()) + void perturb(int type); + /// Take off effect of perturbation and say whether to try dual + bool unPerturb(); + /// Unflag all variables and return number unflagged + int unflag(); + /** Get next superbasic -1 if none, + Normal type is 1 + If type is 3 then initializes sorted list + if 2 uses list. + */ + int nextSuperBasic(int superBasicType, CoinIndexedVector * columnArray); + + /// Create primal ray + void primalRay(CoinIndexedVector * rowArray); + /// Clears all bits and clears rowArray[1] etc + void clearAll(); + + /// Sort of lexicographic resolve + int lexSolve(); + + //@} +}; +#endif + diff --git a/thirdparty/linux/include/coin1/ClpSolve.hpp b/thirdparty/linux/include/coin1/ClpSolve.hpp new file mode 100644 index 0000000..280e33d --- /dev/null +++ b/thirdparty/linux/include/coin1/ClpSolve.hpp @@ -0,0 +1,446 @@ +/* $Id: ClpSolve.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). +/* + Authors + + John Forrest + + */ +#ifndef ClpSolve_H +#define ClpSolve_H + +/** + This is a very simple class to guide algorithms. It is used to tidy up + passing parameters to initialSolve and maybe for output from that + +*/ + +class ClpSolve { + +public: + + /** enums for solve function */ + enum SolveType { + useDual = 0, + usePrimal, + usePrimalorSprint, + useBarrier, + useBarrierNoCross, + automatic, + tryDantzigWolfe, + tryBenders, + notImplemented + }; + enum PresolveType { + presolveOn = 0, + presolveOff, + presolveNumber, + presolveNumberCost + }; + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSolve ( ); + /// Constructor when you really know what you are doing + ClpSolve ( SolveType method, PresolveType presolveType, + int numberPasses, int options[6], + int extraInfo[6], int independentOptions[3]); + /// Generates code for above constructor + void generateCpp(FILE * fp); + /// Copy constructor. + ClpSolve(const ClpSolve &); + /// Assignment operator. This copies the data + ClpSolve & operator=(const ClpSolve & rhs); + /// Destructor + ~ClpSolve ( ); + //@} + + /**@name Functions most useful to user */ + //@{ + /** Special options - bits + 0 4 - use crash (default allslack in dual, idiot in primal) + 8 - all slack basis in primal + 2 16 - switch off interrupt handling + 3 32 - do not try and make plus minus one matrix + 64 - do not use sprint even if problem looks good + */ + /** which translation is: + which: + 0 - startup in Dual (nothing if basis exists).: + 0 - no basis + 1 - crash + 2 - use initiative about idiot! but no crash + 1 - startup in Primal (nothing if basis exists): + 0 - use initiative + 1 - use crash + 2 - use idiot and look at further info + 3 - use sprint and look at further info + 4 - use all slack + 5 - use initiative but no idiot + 6 - use initiative but no sprint + 7 - use initiative but no crash + 8 - do allslack or idiot + 9 - do allslack or sprint + 10 - slp before + 11 - no nothing and primal(0) + 2 - interrupt handling - 0 yes, 1 no (for threadsafe) + 3 - whether to make +- 1matrix - 0 yes, 1 no + 4 - for barrier + 0 - dense cholesky + 1 - Wssmp allowing some long columns + 2 - Wssmp not allowing long columns + 3 - Wssmp using KKT + 4 - Using Florida ordering + 8 - bit set to do scaling + 16 - set to be aggressive with gamma/delta? + 32 - Use KKT + 5 - for presolve + 1 - switch off dual stuff + 6 - extra switches + + */ + void setSpecialOption(int which, int value, int extraInfo = -1); + int getSpecialOption(int which) const; + + /// Solve types + void setSolveType(SolveType method, int extraInfo = -1); + SolveType getSolveType(); + + // Presolve types + void setPresolveType(PresolveType amount, int extraInfo = -1); + PresolveType getPresolveType(); + int getPresolvePasses() const; + /// Extra info for idiot (or sprint) + int getExtraInfo(int which) const; + /** Say to return at once if infeasible, + default is to solve */ + void setInfeasibleReturn(bool trueFalse); + inline bool infeasibleReturn() const { + return independentOptions_[0] != 0; + } + /// Whether we want to do dual part of presolve + inline bool doDual() const { + return (independentOptions_[1] & 1) == 0; + } + inline void setDoDual(bool doDual_) { + if (doDual_) independentOptions_[1] &= ~1; + else independentOptions_[1] |= 1; + } + /// Whether we want to do singleton part of presolve + inline bool doSingleton() const { + return (independentOptions_[1] & 2) == 0; + } + inline void setDoSingleton(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~2; + else independentOptions_[1] |= 2; + } + /// Whether we want to do doubleton part of presolve + inline bool doDoubleton() const { + return (independentOptions_[1] & 4) == 0; + } + inline void setDoDoubleton(bool doDoubleton_) { + if (doDoubleton_) independentOptions_[1] &= ~4; + else independentOptions_[1] |= 4; + } + /// Whether we want to do tripleton part of presolve + inline bool doTripleton() const { + return (independentOptions_[1] & 8) == 0; + } + inline void setDoTripleton(bool doTripleton_) { + if (doTripleton_) independentOptions_[1] &= ~8; + else independentOptions_[1] |= 8; + } + /// Whether we want to do tighten part of presolve + inline bool doTighten() const { + return (independentOptions_[1] & 16) == 0; + } + inline void setDoTighten(bool doTighten_) { + if (doTighten_) independentOptions_[1] &= ~16; + else independentOptions_[1] |= 16; + } + /// Whether we want to do forcing part of presolve + inline bool doForcing() const { + return (independentOptions_[1] & 32) == 0; + } + inline void setDoForcing(bool doForcing_) { + if (doForcing_) independentOptions_[1] &= ~32; + else independentOptions_[1] |= 32; + } + /// Whether we want to do impliedfree part of presolve + inline bool doImpliedFree() const { + return (independentOptions_[1] & 64) == 0; + } + inline void setDoImpliedFree(bool doImpliedfree) { + if (doImpliedfree) independentOptions_[1] &= ~64; + else independentOptions_[1] |= 64; + } + /// Whether we want to do dupcol part of presolve + inline bool doDupcol() const { + return (independentOptions_[1] & 128) == 0; + } + inline void setDoDupcol(bool doDupcol_) { + if (doDupcol_) independentOptions_[1] &= ~128; + else independentOptions_[1] |= 128; + } + /// Whether we want to do duprow part of presolve + inline bool doDuprow() const { + return (independentOptions_[1] & 256) == 0; + } + inline void setDoDuprow(bool doDuprow_) { + if (doDuprow_) independentOptions_[1] &= ~256; + else independentOptions_[1] |= 256; + } + /// Whether we want to do singleton column part of presolve + inline bool doSingletonColumn() const { + return (independentOptions_[1] & 512) == 0; + } + inline void setDoSingletonColumn(bool doSingleton_) { + if (doSingleton_) independentOptions_[1] &= ~512; + else independentOptions_[1] |= 512; + } + /// Whether we want to kill small substitutions + inline bool doKillSmall() const { + return (independentOptions_[1] & 8192) == 0; + } + inline void setDoKillSmall(bool doKill) { + if (doKill) independentOptions_[1] &= ~8192; + else independentOptions_[1] |= 8192; + } + /// Set whole group + inline int presolveActions() const { + return independentOptions_[1] & 0xffff; + } + inline void setPresolveActions(int action) { + independentOptions_[1] = (independentOptions_[1] & 0xffff0000) | (action & 0xffff); + } + /// Largest column for substitution (normally 3) + inline int substitution() const { + return independentOptions_[2]; + } + inline void setSubstitution(int value) { + independentOptions_[2] = value; + } + inline void setIndependentOption(int type,int value) { + independentOptions_[type] = value; + } + inline int independentOption(int type) const { + return independentOptions_[type]; + } + //@} + +////////////////// data ////////////////// +private: + + /**@name data. + */ + //@{ + /// Solve type + SolveType method_; + /// Presolve type + PresolveType presolveType_; + /// Amount of presolve + int numberPasses_; + /// Options - last is switch for OsiClp + int options_[7]; + /// Extra information + int extraInfo_[7]; + /** Extra algorithm dependent options + 0 - if set return from clpsolve if infeasible + 1 - To be copied over to presolve options + 2 - max substitution level + If Dantzig Wolfe/benders 0 is number blocks, 2 is #passes (notional) + */ + int independentOptions_[3]; + //@} +}; + +/// For saving extra information to see if looping. +class ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + ClpSimplexProgress ( ); + + /// Constructor from model + ClpSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + ClpSimplexProgress(const ClpSimplexProgress &); + + /// Assignment operator. This copies the data + ClpSimplexProgress & operator=(const ClpSimplexProgress & rhs); + /// Destructor + ~ClpSimplexProgress ( ); + /// Resets as much as possible + void reset(); + /// Fill from model + void fillFromModel ( ClpSimplex * model ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + /// Start check at beginning of whileIterating + void startCheck(); + /// Returns cycle length in whileIterating + int cycle(int in, int out, int wayIn, int wayOut); + + /// Returns previous objective (if -1) - current if (0) + double lastObjective(int back = 1) const; + /// Set real primal infeasibility and move back + void setInfeasibility(double value); + /// Returns real primal infeasibility (if -1) - current if (0) + double lastInfeasibility(int back = 1) const; + /// Returns number of primal infeasibilities (if -1) - current if (0) + int numberInfeasibilities(int back = 1) const; + /// Modify objective e.g. if dual infeasible in dual + void modifyObjective(double value); + /// Returns previous iteration number (if -1) - current if (0) + int lastIterationNumber(int back = 1) const; + /// clears all iteration numbers (to switch off panic) + void clearIterationNumbers(); + /// Odd state + inline void newOddState() { + oddState_ = - oddState_ - 1; + } + inline void endOddState() { + oddState_ = abs(oddState_); + } + inline void clearOddState() { + oddState_ = 0; + } + inline int oddState() const { + return oddState_; + } + /// number of bad times + inline int badTimes() const { + return numberBadTimes_; + } + inline void clearBadTimes() { + numberBadTimes_ = 0; + } + /// number of really bad times + inline int reallyBadTimes() const { + return numberReallyBadTimes_; + } + inline void incrementReallyBadTimes() { + numberReallyBadTimes_++; + } + /// number of times flagged + inline int timesFlagged() const { + return numberTimesFlagged_; + } + inline void clearTimesFlagged() { + numberTimesFlagged_ = 0; + } + inline void incrementTimesFlagged() { + numberTimesFlagged_++; + } + + //@} + /**@name Data */ +#define CLP_PROGRESS 5 + //#define CLP_PROGRESS_WEIGHT 10 + //@{ + /// Objective values + double objective_[CLP_PROGRESS]; + /// Sum of infeasibilities for algorithm + double infeasibility_[CLP_PROGRESS]; + /// Sum of real primal infeasibilities for primal + double realInfeasibility_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Objective values for weights + double objectiveWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of infeasibilities for algorithm for weights + double infeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Sum of real primal infeasibilities for primal for weights + double realInfeasibilityWeight_[CLP_PROGRESS_WEIGHT]; + /// Drop for weights + double drop_; + /// Best? for weights + double best_; +#endif + /// Initial weight for weights + double initialWeight_; +#define CLP_CYCLE 12 + /// For cycle checking + //double obj_[CLP_CYCLE]; + int in_[CLP_CYCLE]; + int out_[CLP_CYCLE]; + char way_[CLP_CYCLE]; + /// Pointer back to model so we can get information + ClpSimplex * model_; + /// Number of infeasibilities + int numberInfeasibilities_[CLP_PROGRESS]; + /// Iteration number at which occurred + int iterationNumber_[CLP_PROGRESS]; +#ifdef CLP_PROGRESS_WEIGHT + /// Number of infeasibilities for weights + int numberInfeasibilitiesWeight_[CLP_PROGRESS_WEIGHT]; + /// Iteration number at which occurred for weights + int iterationNumberWeight_[CLP_PROGRESS_WEIGHT]; +#endif + /// Number of times checked (so won't stop too early) + int numberTimes_; + /// Number of times it looked like loop + int numberBadTimes_; + /// Number really bad times + int numberReallyBadTimes_; + /// Number of times no iterations as flagged + int numberTimesFlagged_; + /// If things are in an odd state + int oddState_; + //@} +}; + +#include "ClpConfig.h" +#if CLP_HAS_ABC +#include "AbcCommon.hpp" +/// For saving extra information to see if looping. +class AbcSimplexProgress : public ClpSimplexProgress { + +public: + + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + AbcSimplexProgress ( ); + + /// Constructor from model + AbcSimplexProgress ( ClpSimplex * model ); + + /// Copy constructor. + AbcSimplexProgress(const AbcSimplexProgress &); + + /// Assignment operator. This copies the data + AbcSimplexProgress & operator=(const AbcSimplexProgress & rhs); + /// Destructor + ~AbcSimplexProgress ( ); + + //@} + + /**@name Check progress */ + //@{ + /** Returns -1 if okay, -n+1 (n number of times bad) if bad but action taken, + >=0 if give up and use as problem status + */ + int looping ( ); + + //@} + /**@name Data */ + //@} +}; +#endif +#endif diff --git a/thirdparty/linux/include/coin1/Clp_C_Interface.h b/thirdparty/linux/include/coin1/Clp_C_Interface.h new file mode 100644 index 0000000..b91b2d2 --- /dev/null +++ b/thirdparty/linux/include/coin1/Clp_C_Interface.h @@ -0,0 +1,525 @@ +/* $Id: Clp_C_Interface.h 2019 2014-01-31 05:18:01Z stefan $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef ClpSimplexC_H +#define ClpSimplexC_H + +/* include all defines and ugly stuff */ +#include "Coin_C_defines.h" + +#if defined (CLP_EXTERN_C) +typedef struct { + ClpSolve options; +} Clp_Solve; +#else +typedef void Clp_Solve; +#endif + +/** This is a first "C" interface to Clp. + It has similarities to the OSL V3 interface + and only has most common functions +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + /**@name Version info + * + * A Clp library has a version number of the form <major>.<minor>.<release>, + * where each of major, minor, and release are nonnegative integers. + * For a checkout of the Clp stable branch, release is 9999. + * For a checkout of the Clp development branch, major, minor, and release are 9999. + */ + /*@{*/ + /** Clp library version number as string. */ + COINLIBAPI const char* COINLINKAGE Clp_Version(void); + /** Major number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMajor(void); + /** Minor number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionMinor(void); + /** Release number of Clp library version. */ + COINLIBAPI int COINLINKAGE Clp_VersionRelease(void); + /*@}*/ + + /**@name Constructors and destructor + These do not have an exact analogue in C++. + The user does not need to know structure of Clp_Simplex or Clp_Solve. + + For (almost) all Clp_* functions outside this group there is an exact C++ + analogue created by taking the first parameter out, removing the Clp_ + from name and applying the method to an object of type ClpSimplex. + + Similarly, for all ClpSolve_* functions there is an exact C++ + analogue created by taking the first parameter out, removing the ClpSolve_ + from name and applying the method to an object of type ClpSolve. + */ + /*@{*/ + + /** Default constructor */ + COINLIBAPI Clp_Simplex * COINLINKAGE Clp_newModel(void); + /** Destructor */ + COINLIBAPI void COINLINKAGE Clp_deleteModel(Clp_Simplex * model); + /** Default constructor */ + COINLIBAPI Clp_Solve * COINLINKAGE ClpSolve_new(); + /** Destructor */ + COINLIBAPI void COINLINKAGE ClpSolve_delete(Clp_Solve * solve); + /*@}*/ + + /**@name Load model - loads some stuff and initializes others */ + /*@{*/ + /** Loads a problem (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + /** Just like the other loadProblem() method except that the matrix is + given in a standard column major ordered format (without gaps). */ + COINLIBAPI void COINLINKAGE Clp_loadProblem (Clp_Simplex * model, const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /* read quadratic part of the objective (the matrix part) */ + COINLIBAPI void COINLINKAGE + Clp_loadQuadraticObjective(Clp_Simplex * model, + const int numberColumns, + const CoinBigIndex * start, + const int * column, + const double * element); + /** Read an mps file from the given filename */ + COINLIBAPI int COINLINKAGE Clp_readMps(Clp_Simplex * model, const char *filename, + int keepNames, + int ignoreErrors); + /** Copy in integer informations */ + COINLIBAPI void COINLINKAGE Clp_copyInIntegerInformation(Clp_Simplex * model, const char * information); + /** Drop integer informations */ + COINLIBAPI void COINLINKAGE Clp_deleteIntegerInformation(Clp_Simplex * model); + /** Resizes rim part of model */ + COINLIBAPI void COINLINKAGE Clp_resize (Clp_Simplex * model, int newNumberRows, int newNumberColumns); + /** Deletes rows */ + COINLIBAPI void COINLINKAGE Clp_deleteRows(Clp_Simplex * model, int number, const int * which); + /** Add rows */ + COINLIBAPI void COINLINKAGE Clp_addRows(Clp_Simplex * model, int number, const double * rowLower, + const double * rowUpper, + const int * rowStarts, const int * columns, + const double * elements); + + /** Deletes columns */ + COINLIBAPI void COINLINKAGE Clp_deleteColumns(Clp_Simplex * model, int number, const int * which); + /** Add columns */ + COINLIBAPI void COINLINKAGE Clp_addColumns(Clp_Simplex * model, int number, const double * columnLower, + const double * columnUpper, + const double * objective, + const int * columnStarts, const int * rows, + const double * elements); + /** Change row lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowLower(Clp_Simplex * model, const double * rowLower); + /** Change row upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgRowUpper(Clp_Simplex * model, const double * rowUpper); + /** Change column lower bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnLower(Clp_Simplex * model, const double * columnLower); + /** Change column upper bounds */ + COINLIBAPI void COINLINKAGE Clp_chgColumnUpper(Clp_Simplex * model, const double * columnUpper); + /** Change objective coefficients */ + COINLIBAPI void COINLINKAGE Clp_chgObjCoefficients(Clp_Simplex * model, const double * objIn); + /** Drops names - makes lengthnames 0 and names empty */ + COINLIBAPI void COINLINKAGE Clp_dropNames(Clp_Simplex * model); + /** Copies in names */ + COINLIBAPI void COINLINKAGE Clp_copyNames(Clp_Simplex * model, const char * const * rowNames, + const char * const * columnNames); + + /*@}*/ + /**@name gets and sets - you will find some synonyms at the end of this file */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_numberRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_numberColumns(Clp_Simplex * model); + /** Primal tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_primalTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPrimalTolerance(Clp_Simplex * model, double value) ; + /** Dual tolerance to use */ + COINLIBAPI double COINLINKAGE Clp_dualTolerance(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualTolerance(Clp_Simplex * model, double value) ; + /** Dual objective limit */ + COINLIBAPI double COINLINKAGE Clp_dualObjectiveLimit(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualObjectiveLimit(Clp_Simplex * model, double value); + /** Objective offset */ + COINLIBAPI double COINLINKAGE Clp_objectiveOffset(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setObjectiveOffset(Clp_Simplex * model, double value); + /** Fills in array with problem name */ + COINLIBAPI void COINLINKAGE Clp_problemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /* Sets problem name. Must have \0 at end. */ + COINLIBAPI int COINLINKAGE + Clp_setProblemName(Clp_Simplex * model, int maxNumberCharacters, char * array); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_numberIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setNumberIterations(Clp_Simplex * model, int numberIterations); + /** Maximum number of iterations */ + COINLIBAPI int maximumIterations(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumIterations(Clp_Simplex * model, int value); + /** Maximum time in seconds (from when set called) */ + COINLIBAPI double COINLINKAGE Clp_maximumSeconds(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setMaximumSeconds(Clp_Simplex * model, double value); + /** Returns true if hit maximum iterations (or time) */ + COINLIBAPI int COINLINKAGE Clp_hitMaximumIterations(Clp_Simplex * model); + /** Status of problem: + 0 - optimal + 1 - primal infeasible + 2 - dual infeasible + 3 - stopped on iterations etc + 4 - stopped due to errors + */ + COINLIBAPI int COINLINKAGE Clp_status(Clp_Simplex * model); + /** Set problem status */ + COINLIBAPI void COINLINKAGE Clp_setProblemStatus(Clp_Simplex * model, int problemStatus); + /** Secondary status of problem - may get extended + 0 - none + 1 - primal infeasible because dual limit reached + 2 - scaled problem optimal - unscaled has primal infeasibilities + 3 - scaled problem optimal - unscaled has dual infeasibilities + 4 - scaled problem optimal - unscaled has both dual and primal infeasibilities + */ + COINLIBAPI int COINLINKAGE Clp_secondaryStatus(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSecondaryStatus(Clp_Simplex * model, int status); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_optimizationDirection(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setOptimizationDirection(Clp_Simplex * model, double value); + /** Primal row solution */ + COINLIBAPI double * COINLINKAGE Clp_primalRowSolution(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI double * COINLINKAGE Clp_primalColumnSolution(Clp_Simplex * model); + /** Dual row solution */ + COINLIBAPI double * COINLINKAGE Clp_dualRowSolution(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI double * COINLINKAGE Clp_dualColumnSolution(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI double* COINLINKAGE Clp_rowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI double* COINLINKAGE Clp_rowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI double * COINLINKAGE Clp_objective(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI double * COINLINKAGE Clp_columnLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI double * COINLINKAGE Clp_columnUpper(Clp_Simplex * model); + /** Number of elements in matrix */ + COINLIBAPI int COINLINKAGE Clp_getNumElements(Clp_Simplex * model); + /* Column starts in matrix */ + COINLIBAPI const CoinBigIndex * COINLINKAGE Clp_getVectorStarts(Clp_Simplex * model); + /* Row indices in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getIndices(Clp_Simplex * model); + /* Column vector lengths in matrix */ + COINLIBAPI const int * COINLINKAGE Clp_getVectorLengths(Clp_Simplex * model); + /* Element values in matrix */ + COINLIBAPI const double * COINLINKAGE Clp_getElements(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_objectiveValue(Clp_Simplex * model); + /** Integer information */ + COINLIBAPI char * COINLINKAGE Clp_integerInformation(Clp_Simplex * model); + /** Gives Infeasibility ray. + * + * Use Clp_freeRay to free the returned array. + * + * @return infeasibility ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_infeasibilityRay(Clp_Simplex * model); + /** Gives ray in which the problem is unbounded. + * + * Use Clp_freeRay to free the returned array. + * + * @return unbounded ray, or NULL returned if none/wrong. + */ + COINLIBAPI double * COINLINKAGE Clp_unboundedRay(Clp_Simplex * model); + /** Frees a infeasibility or unbounded ray. */ + COINLIBAPI void COINLINKAGE Clp_freeRay(Clp_Simplex * model, double * ray); + /** See if status array exists (partly for OsiClp) */ + COINLIBAPI int COINLINKAGE Clp_statusExists(Clp_Simplex * model); + /** Return address of status array (char[numberRows+numberColumns]) */ + COINLIBAPI unsigned char * COINLINKAGE Clp_statusArray(Clp_Simplex * model); + /** Copy in status vector */ + COINLIBAPI void COINLINKAGE Clp_copyinStatus(Clp_Simplex * model, const unsigned char * statusArray); + /* status values are as in ClpSimplex.hpp i.e. 0 - free, 1 basic, 2 at upper, + 3 at lower, 4 superbasic, (5 fixed) */ + /* Get variable basis info */ + COINLIBAPI int COINLINKAGE Clp_getColumnStatus(Clp_Simplex * model, int sequence); + /* Get row basis info */ + COINLIBAPI int COINLINKAGE Clp_getRowStatus(Clp_Simplex * model, int sequence); + /* Set variable basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setColumnStatus(Clp_Simplex * model, + int sequence, int value); + /* Set row basis info (and value if at bound) */ + COINLIBAPI void COINLINKAGE Clp_setRowStatus(Clp_Simplex * model, + int sequence, int value); + + /** User pointer for whatever reason */ + COINLIBAPI void COINLINKAGE Clp_setUserPointer (Clp_Simplex * model, void * pointer); + COINLIBAPI void * COINLINKAGE Clp_getUserPointer (Clp_Simplex * model); + /*@}*/ + /**@name Message handling. Call backs are handled by ONE function */ + /*@{*/ + /** Pass in Callback function. + Message numbers up to 1000000 are Clp, Coin ones have 1000000 added */ + COINLIBAPI void COINLINKAGE Clp_registerCallBack(Clp_Simplex * model, + clp_callback userCallBack); + /** Unset Callback function */ + COINLIBAPI void COINLINKAGE Clp_clearCallBack(Clp_Simplex * model); + /** Amount of print out: + 0 - none + 1 - just final + 2 - just factorizations + 3 - as 2 plus a bit more + 4 - verbose + above that 8,16,32 etc just for selective debug + */ + COINLIBAPI void COINLINKAGE Clp_setLogLevel(Clp_Simplex * model, int value); + COINLIBAPI int COINLINKAGE Clp_logLevel(Clp_Simplex * model); + /** length of names (0 means no names0 */ + COINLIBAPI int COINLINKAGE Clp_lengthNames(Clp_Simplex * model); + /** Fill in array (at least lengthNames+1 long) with a row name */ + COINLIBAPI void COINLINKAGE Clp_rowName(Clp_Simplex * model, int iRow, char * name); + /** Fill in array (at least lengthNames+1 long) with a column name */ + COINLIBAPI void COINLINKAGE Clp_columnName(Clp_Simplex * model, int iColumn, char * name); + + /*@}*/ + + + /**@name Functions most useful to user */ + /*@{*/ + /** General solve algorithm which can do presolve. + See ClpSolve.hpp for options + */ + COINLIBAPI int COINLINKAGE Clp_initialSolve(Clp_Simplex * model); + /** Pass solve options. (Exception to direct analogue rule) */ + COINLIBAPI int COINLINKAGE Clp_initialSolveWithOptions(Clp_Simplex * model, Clp_Solve *); + /** Dual initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialDualSolve(Clp_Simplex * model); + /** Primal initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialPrimalSolve(Clp_Simplex * model); + /** Barrier initial solve */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierSolve(Clp_Simplex * model); + /** Barrier initial solve, no crossover */ + COINLIBAPI int COINLINKAGE Clp_initialBarrierNoCrossSolve(Clp_Simplex * model); + /** Dual algorithm - see ClpSimplexDual.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_dual(Clp_Simplex * model, int ifValuesPass); + /** Primal algorithm - see ClpSimplexPrimal.hpp for method */ + COINLIBAPI int COINLINKAGE Clp_primal(Clp_Simplex * model, int ifValuesPass); +#ifndef SLIM_CLP + /** Solve the problem with the idiot code */ + COINLIBAPI void COINLINKAGE Clp_idiot(Clp_Simplex * model, int tryhard); +#endif + /** Sets or unsets scaling, 0 -off, 1 equilibrium, 2 geometric, 3, auto, 4 dynamic(later) */ + COINLIBAPI void COINLINKAGE Clp_scaling(Clp_Simplex * model, int mode); + /** Gets scalingFlag */ + COINLIBAPI int COINLINKAGE Clp_scalingFlag(Clp_Simplex * model); + /** Crash - at present just aimed at dual, returns + -2 if dual preferred and crash basis created + -1 if dual preferred and all slack basis preferred + 0 if basis going in was not all slack + 1 if primal preferred and all slack basis preferred + 2 if primal preferred and crash basis created. + + if gap between bounds <="gap" variables can be flipped + + If "pivot" is + 0 No pivoting (so will just be choice of algorithm) + 1 Simple pivoting e.g. gub + 2 Mini iterations + */ + COINLIBAPI int COINLINKAGE Clp_crash(Clp_Simplex * model, double gap, int pivot); + /*@}*/ + + + /**@name most useful gets and sets */ + /*@{*/ + /** If problem is primal feasible */ + COINLIBAPI int COINLINKAGE Clp_primalFeasible(Clp_Simplex * model); + /** If problem is dual feasible */ + COINLIBAPI int COINLINKAGE Clp_dualFeasible(Clp_Simplex * model); + /** Dual bound */ + COINLIBAPI double COINLINKAGE Clp_dualBound(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setDualBound(Clp_Simplex * model, double value); + /** Infeasibility cost */ + COINLIBAPI double COINLINKAGE Clp_infeasibilityCost(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setInfeasibilityCost(Clp_Simplex * model, double value); + /** Perturbation: + 50 - switch on perturbation + 100 - auto perturb if takes too long (1.0e-6 largest nonzero) + 101 - we are perturbed + 102 - don't try perturbing again + default is 100 + others are for playing + */ + COINLIBAPI int COINLINKAGE Clp_perturbation(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setPerturbation(Clp_Simplex * model, int value); + /** Current (or last) algorithm */ + COINLIBAPI int COINLINKAGE Clp_algorithm(Clp_Simplex * model); + /** Set algorithm */ + COINLIBAPI void COINLINKAGE Clp_setAlgorithm(Clp_Simplex * model, int value); + /** Sum of dual infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumDualInfeasibilities(Clp_Simplex * model); + /** Number of dual infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberDualInfeasibilities(Clp_Simplex * model); + /** Sum of primal infeasibilities */ + COINLIBAPI double COINLINKAGE Clp_sumPrimalInfeasibilities(Clp_Simplex * model); + /** Number of primal infeasibilities */ + COINLIBAPI int COINLINKAGE Clp_numberPrimalInfeasibilities(Clp_Simplex * model); + /** Save model to file, returns 0 if success. This is designed for + use outside algorithms so does not save iterating arrays etc. + It does not save any messaging information. + Does not save scaling values. + It does not know about all types of virtual functions. + */ + COINLIBAPI int COINLINKAGE Clp_saveModel(Clp_Simplex * model, const char * fileName); + /** Restore model from file, returns 0 if success, + deletes current model */ + COINLIBAPI int COINLINKAGE Clp_restoreModel(Clp_Simplex * model, const char * fileName); + + /** Just check solution (for external use) - sets sum of + infeasibilities etc */ + COINLIBAPI void COINLINKAGE Clp_checkSolution(Clp_Simplex * model); + /*@}*/ + + /******************** End of most useful part **************/ + /**@name gets and sets - some synonyms */ + /*@{*/ + /** Number of rows */ + COINLIBAPI int COINLINKAGE Clp_getNumRows(Clp_Simplex * model); + /** Number of columns */ + COINLIBAPI int COINLINKAGE Clp_getNumCols(Clp_Simplex * model); + /** Number of iterations */ + COINLIBAPI int COINLINKAGE Clp_getIterationCount(Clp_Simplex * model); + /** Are there a numerical difficulties? */ + COINLIBAPI int COINLINKAGE Clp_isAbandoned(Clp_Simplex * model); + /** Is optimality proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenOptimal(Clp_Simplex * model); + /** Is primal infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenPrimalInfeasible(Clp_Simplex * model); + /** Is dual infeasiblity proven? */ + COINLIBAPI int COINLINKAGE Clp_isProvenDualInfeasible(Clp_Simplex * model); + /** Is the given primal objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isPrimalObjectiveLimitReached(Clp_Simplex * model) ; + /** Is the given dual objective limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isDualObjectiveLimitReached(Clp_Simplex * model) ; + /** Iteration limit reached? */ + COINLIBAPI int COINLINKAGE Clp_isIterationLimitReached(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI double COINLINKAGE Clp_getObjSense(Clp_Simplex * model); + /** Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore */ + COINLIBAPI void COINLINKAGE Clp_setObjSense(Clp_Simplex * model, double objsen); + /** Primal row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowActivity(Clp_Simplex * model); + /** Primal column solution */ + COINLIBAPI const double * COINLINKAGE Clp_getColSolution(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setColSolution(Clp_Simplex * model, const double * input); + /** Dual row solution */ + COINLIBAPI const double * COINLINKAGE Clp_getRowPrice(Clp_Simplex * model); + /** Reduced costs */ + COINLIBAPI const double * COINLINKAGE Clp_getReducedCost(Clp_Simplex * model); + /** Row lower */ + COINLIBAPI const double* COINLINKAGE Clp_getRowLower(Clp_Simplex * model); + /** Row upper */ + COINLIBAPI const double* COINLINKAGE Clp_getRowUpper(Clp_Simplex * model); + /** Objective */ + COINLIBAPI const double * COINLINKAGE Clp_getObjCoefficients(Clp_Simplex * model); + /** Column Lower */ + COINLIBAPI const double * COINLINKAGE Clp_getColLower(Clp_Simplex * model); + /** Column Upper */ + COINLIBAPI const double * COINLINKAGE Clp_getColUpper(Clp_Simplex * model); + /** Objective value */ + COINLIBAPI double COINLINKAGE Clp_getObjValue(Clp_Simplex * model); + /** Print model for debugging purposes */ + COINLIBAPI void COINLINKAGE Clp_printModel(Clp_Simplex * model, const char * prefix); + /* Small element value - elements less than this set to zero, + default is 1.0e-20 */ + COINLIBAPI double COINLINKAGE Clp_getSmallElementValue(Clp_Simplex * model); + COINLIBAPI void COINLINKAGE Clp_setSmallElementValue(Clp_Simplex * model, double value); + /*@}*/ + + + /**@name Get and set ClpSolve options + */ + /*@{*/ + COINLIBAPI void COINLINKAGE ClpSolve_setSpecialOption(Clp_Solve *, int which, int value, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSpecialOption(Clp_Solve *, int which); + + /** method: (see ClpSolve::SolveType) + 0 - dual simplex + 1 - primal simplex + 2 - primal or sprint + 3 - barrier + 4 - barrier no crossover + 5 - automatic + 6 - not implemented + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setSolveType(Clp_Solve *, int method, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getSolveType(Clp_Solve *); + + /** amount: (see ClpSolve::PresolveType) + 0 - presolve on + 1 - presolve off + 2 - presolve number + 3 - presolve number cost + -- pass extraInfo == -1 for default behavior */ + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveType(Clp_Solve *, int amount, int extraInfo); + COINLIBAPI int COINLINKAGE ClpSolve_getPresolveType(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_getPresolvePasses(Clp_Solve *); + COINLIBAPI int COINLINKAGE ClpSolve_getExtraInfo(Clp_Solve *, int which); + COINLIBAPI void COINLINKAGE ClpSolve_setInfeasibleReturn(Clp_Solve *, int trueFalse); + COINLIBAPI int COINLINKAGE ClpSolve_infeasibleReturn(Clp_Solve *); + + COINLIBAPI int COINLINKAGE ClpSolve_doDual(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDual(Clp_Solve *, int doDual); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingleton(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doDoubleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDoubleton(Clp_Solve *, int doDoubleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTripleton(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTripleton(Clp_Solve *, int doTripleton); + + COINLIBAPI int COINLINKAGE ClpSolve_doTighten(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoTighten(Clp_Solve *, int doTighten); + + COINLIBAPI int COINLINKAGE ClpSolve_doForcing(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoForcing(Clp_Solve *, int doForcing); + + COINLIBAPI int COINLINKAGE ClpSolve_doImpliedFree(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoImpliedFree(Clp_Solve *, int doImpliedFree); + + COINLIBAPI int COINLINKAGE ClpSolve_doDupcol(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDupcol(Clp_Solve *, int doDupcol); + + COINLIBAPI int COINLINKAGE ClpSolve_doDuprow(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoDuprow(Clp_Solve *, int doDuprow); + + COINLIBAPI int COINLINKAGE ClpSolve_doSingletonColumn(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setDoSingletonColumn(Clp_Solve *, int doSingleton); + + COINLIBAPI int COINLINKAGE ClpSolve_presolveActions(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setPresolveActions(Clp_Solve *, int action); + + COINLIBAPI int COINLINKAGE ClpSolve_substitution(Clp_Solve *); + COINLIBAPI void COINLINKAGE ClpSolve_setSubstitution(Clp_Solve *, int value); + + /*@}*/ +#ifdef __cplusplus +} +#endif +#endif diff --git a/thirdparty/linux/include/coin1/CoinAlloc.hpp b/thirdparty/linux/include/coin1/CoinAlloc.hpp new file mode 100644 index 0000000..8f6b08c --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinAlloc.hpp @@ -0,0 +1,176 @@ +/* $Id: CoinAlloc.hpp 1438 2011-06-09 18:14:12Z stefan $ */ +// Copyright (C) 2007, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinAlloc_hpp +#define CoinAlloc_hpp + +#include "CoinUtilsConfig.h" +#include <cstdlib> + +#if !defined(COINUTILS_MEMPOOL_MAXPOOLED) +# define COINUTILS_MEMPOOL_MAXPOOLED -1 +#endif + +#if (COINUTILS_MEMPOOL_MAXPOOLED >= 0) + +#ifndef COINUTILS_MEMPOOL_ALIGNMENT +#define COINUTILS_MEMPOOL_ALIGNMENT 16 +#endif + +/* Note: + This memory pool implementation assumes that sizeof(size_t) and + sizeof(void*) are both <= COINUTILS_MEMPOOL_ALIGNMENT. + Choosing an alignment of 4 will cause segfault on 64-bit platforms and may + lead to bad performance on 32-bit platforms. So 8 is a mnimum recommended + alignment. Probably 16 does not waste too much space either and may be even + better for performance. One must play with it. +*/ + +//############################################################################# + +#if (COINUTILS_MEMPOOL_ALIGNMENT == 16) +static const std::size_t CoinAllocPtrShift = 4; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)15); +#elif (COINUTILS_MEMPOOL_ALIGNMENT == 8) +static const std::size_t CoinAllocPtrShift = 3; +static const std::size_t CoinAllocRoundMask = ~((std::size_t)7); +#else +#error "COINUTILS_MEMPOOL_ALIGNMENT must be defined as 8 or 16 (or this code needs to be changed :-)" +#endif + +//############################################################################# + +#ifndef COIN_MEMPOOL_SAVE_BLOCKHEADS +# define COIN_MEMPOOL_SAVE_BLOCKHEADS 0 +#endif + +//############################################################################# + +class CoinMempool +{ +private: +#if (COIN_MEMPOOL_SAVE_BLOCKHEADS == 1) + char** block_heads; + std::size_t block_num; + std::size_t max_block_num; +#endif +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_t mutex_; +#endif + int last_block_size_; + char* first_free_; + const std::size_t entry_size_; + +private: + CoinMempool(const CoinMempool&); + CoinMempool& operator=(const CoinMempool&); + +private: + char* allocate_new_block(); + inline void lock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_lock(&mutex_); +#endif + } + inline void unlock_mutex() { +#if defined(COINUTILS_PTHREADS) && (COINUTILS_PTHREAD == 1) + pthread_mutex_unlock(&mutex_); +#endif + } + +public: + CoinMempool(std::size_t size = 0); + ~CoinMempool(); + + char* alloc(); + inline void dealloc(char *p) + { + char** pp = (char**)p; + lock_mutex(); + *pp = first_free_; + first_free_ = p; + unlock_mutex(); + } +}; + +//############################################################################# + +/** A memory pool allocator. + + If a request arrives for allocating \c n bytes then it is first + rounded up to the nearest multiple of \c sizeof(void*) (this is \c + n_roundup), then one more \c sizeof(void*) is added to this + number. If the result is no more than maxpooled_ then + the appropriate pool is used to get a chunk of memory, if not, + then malloc is used. In either case, the size of the allocated + chunk is written into the first \c sizeof(void*) bytes and a + pointer pointing afterwards is returned. +*/ + +class CoinAlloc +{ +private: + CoinMempool* pool_; + int maxpooled_; +public: + CoinAlloc(); + ~CoinAlloc() {} + + inline void* alloc(const std::size_t n) + { + if (maxpooled_ <= 0) { + return std::malloc(n); + } + char *p = NULL; + const std::size_t to_alloc = + ((n+COINUTILS_MEMPOOL_ALIGNMENT-1) & CoinAllocRoundMask) + + COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = NULL; + if (maxpooled_ > 0 && to_alloc >= (size_t)maxpooled_) { + p = static_cast<char*>(std::malloc(to_alloc)); + if (p == NULL) throw std::bad_alloc(); + } else { + pool = pool_ + (to_alloc >> CoinAllocPtrShift); + p = pool->alloc(); + } + *((CoinMempool**)p) = pool; + return static_cast<void*>(p+COINUTILS_MEMPOOL_ALIGNMENT); + } + + inline void dealloc(void* p) + { + if (maxpooled_ <= 0) { + std::free(p); + return; + } + if (p) { + char* base = static_cast<char*>(p)-COINUTILS_MEMPOOL_ALIGNMENT; + CoinMempool* pool = *((CoinMempool**)base); + if (!pool) { + std::free(base); + } else { + pool->dealloc(base); + } + } + } +}; + +extern CoinAlloc CoinAllocator; + +//############################################################################# + +#if defined(COINUTILS_MEMPOOL_OVERRIDE_NEW) && (COINUTILS_MEMPOOL_OVERRIDE_NEW == 1) +void* operator new(std::size_t size) throw (std::bad_alloc); +void* operator new[](std::size_t) throw (std::bad_alloc); +void operator delete(void*) throw(); +void operator delete[](void*) throw(); +void* operator new(std::size_t, const std::nothrow_t&) throw(); +void* operator new[](std::size_t, const std::nothrow_t&) throw(); +void operator delete(void*, const std::nothrow_t&) throw(); +void operator delete[](void*, const std::nothrow_t&) throw(); +#endif + +#endif /*(COINUTILS_MEMPOOL_MAXPOOLED >= 0)*/ +#endif diff --git a/thirdparty/linux/include/coin1/CoinBuild.hpp b/thirdparty/linux/include/coin1/CoinBuild.hpp new file mode 100644 index 0000000..770c269 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinBuild.hpp @@ -0,0 +1,149 @@ +/* $Id: CoinBuild.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinBuild_H +#define CoinBuild_H + + +#include "CoinPragma.hpp" +#include "CoinTypes.hpp" +#include "CoinFinite.hpp" + + +/** + In many cases it is natural to build a model by adding one row at a time. In Coin this + is inefficient so this class gives some help. An instance of CoinBuild can be built up + more efficiently and then added to the Clp/OsiModel in one go. + + It may be more efficient to have fewer arrays and re-allocate them but this should + give a large gain over addRow. + + I have now extended it to columns. + +*/ + +class CoinBuild { + +public: + /**@name Useful methods */ + //@{ + /// add a row + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX); + /// add a column + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0); + /// add a column + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue);} + /// Return number of rows or maximum found so far + inline int numberRows() const + { return (type_==0) ? numberItems_ : numberOther_;} + /// Return number of columns or maximum found so far + inline int numberColumns() const + { return (type_==1) ? numberItems_ : numberOther_;} + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /** Returns number of elements in a row and information in row + */ + int row(int whichRow, double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current row and information in row + Used as rows may be stored in a chain + */ + int currentRow(double & rowLower, double & rowUpper, + const int * & indices, const double * & elements) const; + /// Set current row + void setCurrentRow(int whichRow); + /// Returns current row number + int currentRow() const; + /** Returns number of elements in a column and information in column + */ + int column(int whichColumn, + double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current column and information in column + Used as columns may be stored in a chain + */ + int currentColumn( double & columnLower, double & columnUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current column + void setCurrentColumn(int whichColumn); + /// Returns current column number + int currentColumn() const; + /// Returns type + inline int type() const + { return type_;} + //@} + + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinBuild(); + /** Constructor with type 0==for addRow, 1== for addColumn. */ + CoinBuild(int type); + /** Destructor */ + ~CoinBuild(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinBuild(const CoinBuild&); + /// = + CoinBuild& operator=(const CoinBuild&); + //@} +private: + /// Set current + void setMutableCurrent(int which) const; + /// add a item + void addItem(int numberInItem, const int * indices, + const double * elements, + double itemLower, + double itemUpper, double objectiveValue); + /** Returns number of elements in a item and information in item + */ + int item(int whichItem, + double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /** Returns number of elements in current item and information in item + Used as items may be stored in a chain + */ + int currentItem( double & itemLower, double & itemUpper,double & objectiveValue, + const int * & indices, const double * & elements) const; + /// Set current item + void setCurrentItem(int whichItem); + /// Returns current item number + int currentItem() const; + +private: + /**@name Data members */ + //@{ + /// Current number of items + int numberItems_; + /// Current number of other dimension i.e. Columns if addRow (i.e. max) + int numberOther_; + /// Current number of elements + CoinBigIndex numberElements_; + /// Current item pointer + mutable double * currentItem_; + /// First item pointer + double * firstItem_; + /// Last item pointer + double * lastItem_; + /// Type of build - 0 for row, 1 for column, -1 unset + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinDenseFactorization.hpp b/thirdparty/linux/include/coin1/CoinDenseFactorization.hpp new file mode 100644 index 0000000..3ba7528 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinDenseFactorization.hpp @@ -0,0 +1,419 @@ +/* $Id: CoinDenseFactorization.hpp 1759 2014-11-18 11:07:23Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +/* + Authors + + John Forrest + + */ +#ifndef CoinDenseFactorization_H +#define CoinDenseFactorization_H + +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFactorization.hpp" +#if COIN_FACTORIZATION_DENSE_CODE == 2 +#undef COIN_FACTORIZATION_DENSE_CODE +#endif +class CoinPackedMatrix; +/// Abstract base class which also has some scalars so can be used from Dense or Simp +class CoinOtherFactorization { + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOtherFactorization ( ); + /// Copy constructor + CoinOtherFactorization ( const CoinOtherFactorization &other); + + /// Destructor + virtual ~CoinOtherFactorization ( ); + /// = copy + CoinOtherFactorization & operator = ( const CoinOtherFactorization & other ); + + /// Clone + virtual CoinOtherFactorization * clone() const = 0; + //@} + + /**@name general stuff such as status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /** Get solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline int solveMode() const + { return solveMode_ ;} + /** Set solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + inline void setSolveMode(int value) + { solveMode_ = value;} + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Get rid of all memory + virtual void clearArrays() {} + //@} + /**@name virtual general stuff such as permutation */ + //@{ + /// Returns array to put basis indices in + virtual int * indices() const = 0; + /// Returns permute in + virtual int * permute() const = 0; + /// Total number of elements in factorization + virtual int numberElements ( ) const = 0; + //@} + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ) = 0; + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ) = 0; + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ) = 0; + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable) = 0; + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns) = 0; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8)=0; + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) = 0; + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const = 0; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false) = 0; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const = 0; + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Columns in factorization + int numberColumns_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Status of factorization + int status_; + /// Maximum rows ever (i.e. use to copy arrays etc) + int maximumRows_; + /// Maximum length of iterating area + CoinBigIndex maximumSpace_; + /// Pivot row + int * pivotRow_; + /** Elements of factorization and updates + length is maxR*maxR+maxSpace + will always be long enough so can have nR*nR ints in maxSpace + */ + CoinFactorizationDouble * elements_; + /// Work area of numberRows_ + CoinFactorizationDouble * workArea_; + /** Solve mode e.g. 0 C++ code, 1 Lapack, 2 choose + If 4 set then values pass + if 8 set then has iterated + */ + int solveMode_; + //@} +}; +/** This deals with Factorization and Updates + This is a simple dense version so other people can write a better one + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + + +class CoinDenseFactorization : public CoinOtherFactorization { + friend void CoinDenseFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinDenseFactorization ( ); + /// Copy constructor + CoinDenseFactorization ( const CoinDenseFactorization &other); + + /// Destructor + virtual ~CoinDenseFactorization ( ); + /// = copy + CoinDenseFactorization & operator = ( const CoinDenseFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual inline int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool = false) + { return updateColumn(regionSparse,regionSparse2);} + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + virtual inline int * indices() const + { return reinterpret_cast<int *> (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinDenseFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinDenseVector.hpp b/thirdparty/linux/include/coin1/CoinDenseVector.hpp new file mode 100644 index 0000000..77ff9af --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinDenseVector.hpp @@ -0,0 +1,383 @@ +/* $Id: CoinDenseVector.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinDenseVector_H +#define CoinDenseVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <cassert> +#include <cstdlib> +#include <cmath> +#include "CoinHelperFunctions.hpp" + +//############################################################################# +/** A function that tests the methods in the CoinDenseVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ + template <typename T> void + CoinDenseVectorUnitTest(T dummy); + +//############################################################################# +/** Dense Vector + +Stores a dense (or expanded) vector of floating point values. +Type of vector elements is controlled by templating. +(Some working quantities such as accumulated sums +are explicitly declared of type double). This allows the +components of the vector integer, single or double precision. + +Here is a sample usage: +@verbatim + const int ne = 4; + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinDenseVector<double> r(ne,el); + + // access each element + assert( r.getElements()[0]==10. ); + assert( r.getElements()[1]==40. ); + assert( r.getElements()[2]== 1. ); + assert( r.getElements()[3]==50. ); + + // Test for equality + CoinDenseVector<double> r1; + r1=r; + + // Add dense vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinDenseVector<double> add = r + r1; + assert( add[0] == 10.+10. ); + assert( add[1] == 40.+40. ); + assert( add[2] == 1.+ 1. ); + assert( add[3] == 50.+50. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +template <typename T> class CoinDenseVector { +private: + /**@name Private member data */ + //@{ + /// Size of element vector + int nElements_; + ///Vector elements + T * elements_; + //@} + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + inline int size() const { return nElements_; } + /// Get element values + inline const T * getElements() const { return elements_; } + /// Get element values + inline T * getElements() { return elements_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (i.e. set all elemenets to zero) + void clear(); + /** Assignment operator */ + CoinDenseVector & operator=(const CoinDenseVector &); + /** Member of array operator */ + T & operator[](int index) const; + + /** Set vector size, and elements. + Size is the length of the elements vector. + The element vector is copied into this class instance's + member data. */ + void setVector(int size, const T * elems); + + + /** Elements set to have the same scalar value */ + void setConstant(int size, T elems); + + + /** Set an existing element in the dense vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, T element); + /** Resize the dense vector to be the first newSize elements. + If length is decreased, vector is truncated. If increased + new entries, set to new default element */ + void resize(int newSize, T fill=T()); + + /** Append a dense vector to this dense vector */ + void append(const CoinDenseVector &); + //@} + + /**@name norms, sum and scale */ + //@{ + /// 1-norm of vector + inline T oneNorm() const { + T norm = 0; + for (int i=0; i<nElements_; i++) + norm += CoinAbs(elements_[i]); + return norm; + } + /// 2-norm of vector + inline double twoNorm() const { + double norm = 0.; + for (int i=0; i<nElements_; i++) + norm += elements_[i] * elements_[i]; + // std namespace removed because it was causing a compile + // problem with Microsoft Visual C++ + return /*std::*/sqrt(norm); + } + /// infinity-norm of vector + inline T infNorm() const { + T norm = 0; + for (int i=0; i<nElements_; i++) + norm = CoinMax(norm, CoinAbs(elements_[i])); + return norm; + } + /// sum of vector elements + inline T sum() const { + T sume = 0; + for (int i=0; i<nElements_; i++) + sume += elements_[i]; + return sume; + } + /// scale vector elements + inline void scale(T factor) { + for (int i=0; i<nElements_; i++) + elements_[i] *= factor; + return; + } + //@} + + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(T value); + /// subtract <code>value</code> from every entry + void operator-=(T value); + /// multiply every entry by <code>value</code> + void operator*=(T value); + /// divide every entry by <code>value</code> + void operator/=(T value); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinDenseVector(); + /** Alternate Constructors - set elements to vector of Ts */ + CoinDenseVector(int size, const T * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinDenseVector(int size, T element=T()); + /** Copy constructors */ + CoinDenseVector(const CoinDenseVector &); + + /** Destructor */ + ~CoinDenseVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, const T * elems); + /// Set all elements to a given value + void gutsOfSetConstant(int size, T value); + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on dense vectors. + + <strong>NOTE</strong>: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + <em>very</em> inefficient... + */ +//@{ +/// Return the sum of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + elements2[i]; + return op3; +} + +/// Return the difference of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] - elements2[i]; + return op3; +} + + +/// Return the element-wise product of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * elements2[i]; + return op3; +} + +/// Return the element-wise ratio of two dense vectors +template <typename T> inline +CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1, + const CoinDenseVector<T>& op2){ + assert(op1.size() == op2.size()); + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + const T *elements2 = op2.getElements(); + T *elements3 = op3.getElements(); + for(int i=0; i<size; i++) + elements3[i] = elements1[i] / elements2[i]; + return op3; +} +//@} + +/**@name Arithmetic operators on dense vector and a constant. + These functions create a dense vector as a result. That dense vector will + have the same indices as <code>op1</code> and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator+(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + dvalue; + return op3; +} + +/// Return the difference of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator-(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] - dvalue; + return op3; +} + +/// Return the element-wise product of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator*(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * dvalue; + return op3; +} + +/// Return the element-wise ratio of a dense vector and a constant +template <typename T> inline +CoinDenseVector<T> operator/(const CoinDenseVector<T>& op1, T value){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] / dvalue; + return op3; +} + +/// Return the sum of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator+(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] + dvalue; + return op3; +} + +/// Return the difference of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator-(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = dvalue - elements1[i]; + return op3; +} + +/// Return the element-wise product of a constant and a dense vector +template <typename T> inline +CoinDenseVector<T> operator*(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = elements1[i] * dvalue; + return op3; +} + +/// Return the element-wise ratio of a a constant and dense vector +template <typename T> inline +CoinDenseVector<T> operator/(T value, const CoinDenseVector<T>& op1){ + int size = op1.size(); + CoinDenseVector<T> op3(size); + const T *elements1 = op1.getElements(); + T *elements3 = op3.getElements(); + double dvalue = value; + for(int i=0; i<size; i++) + elements3[i] = dvalue / elements1[i]; + return op3; +} +//@} + +#endif diff --git a/thirdparty/linux/include/coin1/CoinDistance.hpp b/thirdparty/linux/include/coin1/CoinDistance.hpp new file mode 100644 index 0000000..acaa908 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinDistance.hpp @@ -0,0 +1,48 @@ +/* $Id: CoinDistance.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinDistance_H +#define CoinDistance_H + +#include <iterator> + +//------------------------------------------------------------------- +// +// Attempt to provide an std::distance function +// that will work on multiple platforms +// +//------------------------------------------------------------------- + +/** CoinDistance + +This is the Coin implementation of the std::function that is +designed to work on multiple platforms. +*/ +template <class ForwardIterator, class Distance> +void coinDistance(ForwardIterator first, ForwardIterator last, + Distance& n) +{ +#if defined(__SUNPRO_CC) + n = 0; + std::distance(first,last,n); +#else + n = std::distance(first,last); +#endif +} + +template <class ForwardIterator> +size_t coinDistance(ForwardIterator first, ForwardIterator last) +{ + size_t retVal; +#if defined(__SUNPRO_CC) + retVal = 0; + std::distance(first,last,retVal); +#else + retVal = std::distance(first,last); +#endif + return retVal; +} + +#endif diff --git a/thirdparty/linux/include/coin1/CoinError.hpp b/thirdparty/linux/include/coin1/CoinError.hpp new file mode 100644 index 0000000..704cfea --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinError.hpp @@ -0,0 +1,257 @@ +/* $Id: CoinError.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinError_H +#define CoinError_H + +#include <string> +#include <iostream> +#include <cassert> +#include <cstring> + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +/** A function to block the popup windows that windows creates when the code + crashes */ +void WindowsErrorPopupBlocker(); + +//------------------------------------------------------------------- +// +// Error class used to throw exceptions +// +// Errors contain: +// +//------------------------------------------------------------------- + +/** Error Class thrown by an exception + +This class is used when exceptions are thrown. +It contains: + <ul> + <li>message text + <li>name of method throwing exception + <li>name of class throwing exception or hint + <li>name of file if assert + <li>line number + </ul> + For asserts class=> optional hint +*/ +class CoinError { + friend void CoinErrorUnitTest(); + +private: + CoinError() + : + message_(), + method_(), + class_(), + file_(), + lineNumber_() + { + // nothing to do here + } + +public: + + //------------------------------------------------------------------- + // Get methods + //------------------------------------------------------------------- + /**@name Get error attributes */ + //@{ + /// get message text + inline const std::string & message() const + { return message_; } + /// get name of method instantiating error + inline const std::string & methodName() const + { return method_; } + /// get name of class instantiating error (or hint for assert) + inline const std::string & className() const + { return class_; } + /// get name of file for assert + inline const std::string & fileName() const + { return file_; } + /// get line number of assert (-1 if not assert) + inline int lineNumber() const + { return lineNumber_; } + /// Just print (for asserts) + inline void print(bool doPrint = true) const + { + if (! doPrint) + return; + if (lineNumber_<0) { + std::cout<<message_<<" in "<<class_<<"::"<<method_<<std::endl; + } else { + std::cout<<file_<<":"<<lineNumber_<<" method "<<method_ + <<" : assertion \'"<<message_<<"\' failed."<<std::endl; + if(class_!="") + std::cout<<"Possible reason: "<<class_<<std::endl; + } + } + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Alternate Constructor + CoinError ( + std::string message__, + std::string methodName__, + std::string className__, + std::string fileName_ = std::string(), + int line = -1) + : + message_(message__), + method_(methodName__), + class_(className__), + file_(fileName_), + lineNumber_(line) + { + print(printErrors_); + } + + /// Copy constructor + CoinError (const CoinError & source) + : + message_(source.message_), + method_(source.method_), + class_(source.class_), + file_(source.file_), + lineNumber_(source.lineNumber_) + { + // nothing to do here + } + + /// Assignment operator + CoinError & operator=(const CoinError& rhs) + { + if (this != &rhs) { + message_=rhs.message_; + method_=rhs.method_; + class_=rhs.class_; + file_=rhs.file_; + lineNumber_ = rhs.lineNumber_; + } + return *this; + } + + /// Destructor + virtual ~CoinError () + { + // nothing to do here + } + //@} + +private: + + /**@name Private member data */ + //@{ + /// message test + std::string message_; + /// method name + std::string method_; + /// class name or hint + std::string class_; + /// file name + std::string file_; + /// Line number + int lineNumber_; + //@} + +public: + /// Whether to print every error + static bool printErrors_; +}; + +#ifndef __STRING +#define __STRING(x) #x +#endif + +#ifndef __GNUC_PREREQ +# define __GNUC_PREREQ(maj, min) (0) +#endif + +#ifndef COIN_ASSERT +# define CoinAssertDebug(expression) assert(expression) +# define CoinAssertDebugHint(expression,hint) assert(expression) +# define CoinAssert(expression) assert(expression) +# define CoinAssertHint(expression,hint) assert(expression) +#else +# ifdef NDEBUG +# define CoinAssertDebug(expression) {} +# define CoinAssertDebugHint(expression,hint) {} +# else +# if defined(__GNUC__) && __GNUC_PREREQ(2, 6) +# define CoinAssertDebug(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + "", __FILE__, __LINE__); \ + } \ + } +# define CoinAssertDebugHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + hint, __FILE__,__LINE__); \ + } \ + } +# else +# define CoinAssertDebug(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + "", __FILE__,__LINE__); \ + } \ + } +# define CoinAssertDebugHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + hint, __FILE__,__LINE__); \ + } \ + } +# endif +# endif +# if defined(__GNUC__) && __GNUC_PREREQ(2, 6) +# define CoinAssert(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + "", __FILE__, __LINE__); \ + } \ + } +# define CoinAssertHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), __PRETTY_FUNCTION__, \ + hint, __FILE__,__LINE__); \ + } \ + } +# else +# define CoinAssert(expression) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + "", __FILE__,__LINE__); \ + } \ + } +# define CoinAssertHint(expression,hint) { \ + if (!(expression)) { \ + throw CoinError(__STRING(expression), "", \ + hint, __FILE__,__LINE__); \ + } \ + } +# endif +#endif + + +//############################################################################# +/** A function that tests the methods in the CoinError class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinErrorUnitTest(); + +#ifdef __LINE__ +#define CoinErrorFL(x, y, z) CoinError((x), (y), (z), __FILE__, __LINE__) +#endif + +#endif diff --git a/thirdparty/linux/include/coin1/CoinFactorization.hpp b/thirdparty/linux/include/coin1/CoinFactorization.hpp new file mode 100644 index 0000000..0a532bf --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinFactorization.hpp @@ -0,0 +1,2044 @@ +/* $Id: CoinFactorization.hpp 1767 2015-01-05 12:36:13Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + Authors + + John Forrest + + */ +#ifndef CoinFactorization_H +#define CoinFactorization_H +//#define COIN_ONE_ETA_COPY 100 + +#include <iostream> +#include <string> +#include <cassert> +#include <cstdio> +#include <cmath> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" + +class CoinPackedMatrix; +/** This deals with Factorization and Updates + + This class started with a parallel simplex code I was writing in the + mid 90's. The need for parallelism led to many complications and + I have simplified as much as I could to get back to this. + + I was aiming at problems where I might get speed-up so I was looking at dense + problems or ones with structure. This led to permuting input and output + vectors and to increasing the number of rows each rank-one update. This is + still in as a minor overhead. + + I have also put in handling for hyper-sparsity. I have taken out + all outer loop unrolling, dense matrix handling and most of the + book-keeping for slacks. Also I always use FTRAN approach to updating + even if factorization fairly dense. All these could improve performance. + + I blame some of the coding peculiarities on the history of the code + but mostly it is just because I can't do elegant code (or useful + comments). + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + + +class CoinFactorization { + friend void CoinFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinFactorization ( ); + /// Copy constructor + CoinFactorization ( const CoinFactorization &other); + + /// Destructor + ~CoinFactorization ( ); + /// Delete all stuff (leaves as after CoinFactorization()) + void almostDestructor(); + /// Debug show object (shows one representation) + void show_self ( ) const; + /// Debug - save on file - 0 if no error + int saveFactorization (const char * file ) const; + /** Debug - restore from file - 0 if no error on file. + If factor true then factorizes as if called from ClpFactorization + */ + int restoreFactorization (const char * file , bool factor=false) ; + /// Debug - sort so can compare + void sort ( ) const; + /// = copy + CoinFactorization & operator = ( const CoinFactorization & other ); + //@} + + /**@name Do factorization */ + //@{ + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + /** When given as triplets. + Actually does factorization. maximumL is guessed maximum size of L part of + final factorization, maximumU of U part. These are multiplied by + areaFactor which can be computed by user or internally. + Arrays are copied in. I could add flag to delete arrays to save a + bit of memory. + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorize ( int numberRows, + int numberColumns, + CoinBigIndex numberElements, + CoinBigIndex maximumL, + CoinBigIndex maximumU, + const int indicesRow[], + const int indicesColumn[], const double elements[] , + int permutation[], + double areaFactor = 0.0); + /** Two part version for maximum flexibility + This part creates arrays for user to fill. + estimateNumberElements is safe estimate of number + returns 0 -okay, -99 memory */ + int factorizePart1 ( int numberRows, + int numberColumns, + CoinBigIndex estimateNumberElements, + int * indicesRow[], + int * indicesColumn[], + CoinFactorizationDouble * elements[], + double areaFactor = 0.0); + /** This is part two of factorization + Arrays belong to factorization and were returned by part 1 + If status okay, permutation has pivot rows - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -99 memory */ + int factorizePart2 (int permutation[],int exactNumberElements); + /// Condition number - product of pivots after factorization + double conditionNumber() const; + + //@} + + /**@name general stuff such as permutation or status */ + //@{ + /// Returns status + inline int status ( ) const { + return status_; + } + /// Sets status + inline void setStatus ( int value) + { status_=value; } + /// Returns number of pivots since factorization + inline int pivots ( ) const { + return numberPivots_; + } + /// Sets number of pivots since factorization + inline void setPivots ( int value ) + { numberPivots_=value; } + /// Returns address of permute region + inline int *permute ( ) const { + return permute_.array(); + } + /// Returns address of pivotColumn region (also used for permuting) + inline int *pivotColumn ( ) const { + return pivotColumn_.array(); + } + /// Returns address of pivot region + inline CoinFactorizationDouble *pivotRegion ( ) const { + return pivotRegion_.array(); + } + /// Returns address of permuteBack region + inline int *permuteBack ( ) const { + return permuteBack_.array(); + } + /// Returns address of lastRow region + inline int *lastRow ( ) const { + return lastRow_.array(); + } + /** Returns address of pivotColumnBack region (also used for permuting) + Now uses firstCount to save memory allocation */ + inline int *pivotColumnBack ( ) const { + //return firstCount_.array(); + return pivotColumnBack_.array(); + } + /// Start of each row in L + inline CoinBigIndex * startRowL() const + { return startRowL_.array();} + + /// Start of each column in L + inline CoinBigIndex * startColumnL() const + { return startColumnL_.array();} + + /// Index of column in row for L + inline int * indexColumnL() const + { return indexColumnL_.array();} + + /// Row indices of L + inline int * indexRowL() const + { return indexRowL_.array();} + + /// Elements in L (row copy) + inline CoinFactorizationDouble * elementByRowL() const + { return elementByRowL_.array();} + + /// Number of Rows after iterating + inline int numberRowsExtra ( ) const { + return numberRowsExtra_; + } + /// Set number of Rows after factorization + inline void setNumberRows(int value) + { numberRows_ = value; } + /// Number of Rows after factorization + inline int numberRows ( ) const { + return numberRows_; + } + /// Number in L + inline CoinBigIndex numberL() const + { return numberL_;} + + /// Base of L + inline CoinBigIndex baseL() const + { return baseL_;} + /// Maximum of Rows after iterating + inline int maximumRowsExtra ( ) const { + return maximumRowsExtra_; + } + /// Total number of columns in factorization + inline int numberColumns ( ) const { + return numberColumns_; + } + /// Total number of elements in factorization + inline int numberElements ( ) const { + return totalElements_; + } + /// Length of FT vector + inline int numberForrestTomlin ( ) const { + return numberInColumn_.array()[numberColumnsExtra_]; + } + /// Number of good columns in factorization + inline int numberGoodColumns ( ) const { + return numberGoodU_; + } + /// Whether larger areas needed + inline double areaFactor ( ) const { + return areaFactor_; + } + inline void areaFactor ( double value ) { + areaFactor_=value; + } + /// Returns areaFactor but adjusted for dense + double adjustedAreaFactor() const; + /// Allows change of pivot accuracy check 1.0 == none >1.0 relaxed + inline void relaxAccuracyCheck(double value) + { relaxCheck_ = value;} + inline double getAccuracyCheck() const + { return relaxCheck_;} + /// Level of detail of messages + inline int messageLevel ( ) const { + return messageLevel_ ; + } + void messageLevel ( int value ); + /// Maximum number of pivots between factorizations + inline int maximumPivots ( ) const { + return maximumPivots_ ; + } + void maximumPivots ( int value ); + + /// Gets dense threshold + inline int denseThreshold() const + { return denseThreshold_;} + /// Sets dense threshold + inline void setDenseThreshold(int value) + { denseThreshold_ = value;} + /// Pivot tolerance + inline double pivotTolerance ( ) const { + return pivotTolerance_ ; + } + void pivotTolerance ( double value ); + /// Zero tolerance + inline double zeroTolerance ( ) const { + return zeroTolerance_ ; + } + void zeroTolerance ( double value ); +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + inline double slackValue ( ) const { + return slackValue_ ; + } + void slackValue ( double value ); +#endif + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// true if Forrest Tomlin update, false if PFI + inline bool forrestTomlin() const + { return doForrestTomlin_;} + inline void setForrestTomlin(bool value) + { doForrestTomlin_=value;} + /// True if FT update and space + inline bool spaceForForrestTomlin() const + { + CoinBigIndex start = startColumnU_.array()[maximumColumnsExtra_]; + CoinBigIndex space = lengthAreaU_ - ( start + numberRowsExtra_ ); + return (space>=0)&&doForrestTomlin_; + } + //@} + + /**@name some simple stuff */ + //@{ + + /// Returns number of dense rows + inline int numberDense() const + { return numberDense_;} + + /// Returns number in U area + inline CoinBigIndex numberElementsU ( ) const { + return lengthU_; + } + /// Setss number in U area + inline void setNumberElementsU(CoinBigIndex value) + { lengthU_ = value; } + /// Returns length of U area + inline CoinBigIndex lengthAreaU ( ) const { + return lengthAreaU_; + } + /// Returns number in L area + inline CoinBigIndex numberElementsL ( ) const { + return lengthL_; + } + /// Returns length of L area + inline CoinBigIndex lengthAreaL ( ) const { + return lengthAreaL_; + } + /// Returns number in R area + inline CoinBigIndex numberElementsR ( ) const { + return lengthR_; + } + /// Number of compressions done + inline CoinBigIndex numberCompressions() const + { return numberCompressions_;} + /// Number of entries in each row + inline int * numberInRow() const + { return numberInRow_.array();} + /// Number of entries in each column + inline int * numberInColumn() const + { return numberInColumn_.array();} + /// Elements of U + inline CoinFactorizationDouble * elementU() const + { return elementU_.array();} + /// Row indices of U + inline int * indexRowU() const + { return indexRowU_.array();} + /// Start of each column in U + inline CoinBigIndex * startColumnU() const + { return startColumnU_.array();} + /// Maximum number of Columns after iterating + inline int maximumColumnsExtra() + { return maximumColumnsExtra_;} + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + inline int biasLU() const + { return biasLU_;} + inline void setBiasLU(int value) + { biasLU_=value;} + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + inline int persistenceFlag() const + { return persistenceFlag_;} + void setPersistenceFlag(int value); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + /** Combines BtranU and delete elements + If deleted is NULL then delete elements + otherwise store where elements are + */ + void replaceColumnU ( CoinIndexedVector * regionSparse, + CoinBigIndex * deleted, + int internalPivotRow); +#ifdef ABC_USE_COIN_FACTORIZATION + /** returns empty fake vector carved out of existing + later - maybe use associated arrays */ + CoinIndexedVector * fakeVector(CoinIndexedVector * vector, + int already=0) const; + void deleteFakeVector(CoinIndexedVector * vector, + CoinIndexedVector * fakeVector) const; + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update already in U */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + int pivotRow); + /** Checks if can replace one Column to basis, + returns update alpha + Fills in region for use later + partial update in vector */ + double checkReplacePart1 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow); + /** Checks if can replace one Column in basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room, 5 max pivots */ + int checkReplacePart2 ( int pivotRow, + double btranAlpha, + double ftranAlpha, + double ftAlpha, + double acceptablePivot = 1.0e-8); + /** Replaces one Column to basis, + partial update already in U */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + int pivotRow, + double alpha ); + /** Replaces one Column to basis, + partial update in vector */ + void replaceColumnPart3 ( CoinIndexedVector * regionSparse, + CoinIndexedVector * partialUpdate, + int pivotRow, + double alpha ); + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + long regions + */ + int updateColumnFT ( CoinIndexedVector & regionSparse); + int updateColumnFTPart1 ( CoinIndexedVector & regionSparse) ; + void updateColumnFTPart2 ( CoinIndexedVector & regionSparse) ; + /** Updates one column (FTRAN) - long region + Tries to do FT update + puts partial update in vector */ + void updateColumnFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & partialUpdate, + int which); + /** Updates one column (FTRAN) long region */ + int updateColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) from regionFT + Tries to do FT update + number returned is negative if no room. + Also updates regionOther - long region*/ + int updateTwoColumnsFT ( CoinIndexedVector & regionSparseFT, + CoinIndexedVector & regionSparseOther); + /** Updates one column (BTRAN) - long region*/ + int updateColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column (FTRAN) - long region */ + void updateColumnCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one column (BTRAN) - long region */ + void updateColumnTransposeCpu ( CoinIndexedVector & regionSparse,int whichCpu) const; + /** Updates one full column (FTRAN) - long region */ + void updateFullColumn ( CoinIndexedVector & regionSparse) const; + /** Updates one full column (BTRAN) - long region */ + void updateFullColumnTranspose ( CoinIndexedVector & regionSparse) const; + /** Updates one column for dual steepest edge weights (FTRAN) - long region */ + void updateWeights ( CoinIndexedVector & regionSparse) const; + /// Returns true if wants tableauColumn in replaceColumn + inline bool wantsTableauColumn() const + {return false;} + /// Pivot tolerance + inline double minimumPivotTolerance ( ) const { + return pivotTolerance_ ; + } + inline void minimumPivotTolerance ( double value ) + { pivotTolerance(value);} + /// Says parallel + inline void setParallelMode(int value) + { parallelMode_=value;} + /// Sets solve mode + inline void setSolveMode(int value) + { parallelMode_ &= 3;parallelMode_ |= (value<<2);} + /// Sets solve mode + inline int solveMode() const + { return parallelMode_ >> 2;} + /// Update partial Ftran by R update + void updatePartialUpdate(CoinIndexedVector & partialUpdate); + /// Makes a non-singular basis by replacing variables + void makeNonSingular(int * COIN_RESTRICT sequence); +#endif + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /** Updates one column (FTRAN) from region2 + Tries to do FT update + number returned is negative if no room. + Also updates region3 + region1 starts as zero and is zero at end */ + int updateTwoColumnsFT ( CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermuteRegion3=false) ; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /** makes a row copy of L for speed and to allow very sparse problems */ + void goSparse(); + /** get sparse threshold */ + inline int sparseThreshold ( ) const + { return sparseThreshold_;} + /** set sparse threshold */ + void sparseThreshold ( int value ); + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization (return code number elements) + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + //@} + + /**@name various updates - none of which have been written! */ + //@{ + + /** Adds given elements to Basis and updates factorization, + can increase size of basis. Returns rank */ + int add ( CoinBigIndex numberElements, + int indicesRow[], + int indicesColumn[], double elements[] ); + + /** Adds one Column to basis, + can increase size of basis. Returns rank */ + int addColumn ( CoinBigIndex numberElements, + int indicesRow[], double elements[] ); + + /** Adds one Row to basis, + can increase size of basis. Returns rank */ + int addRow ( CoinBigIndex numberElements, + int indicesColumn[], double elements[] ); + + /// Deletes one Column from basis, returns rank + int deleteColumn ( int Row ); + /// Deletes one Row from basis, returns rank + int deleteRow ( int Row ); + + /** Replaces one Row in basis, + At present assumes just a singleton on row is in basis + returns 0=OK, 1=Probably OK, 2=singular, 3 no space */ + int replaceRow ( int whichRow, int numberElements, + const int indicesColumn[], const double elements[] ); + /// Takes out all entries for given rows + void emptyRows(int numberToEmpty, const int which[]); + //@} + /**@name used by ClpFactorization */ + /// See if worth going sparse + void checkSparse(); + /// For statistics +#if 0 //def CLP_FACTORIZATION_INSTRUMENT + inline bool collectStatistics() const + { return collectStatistics_;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { collectStatistics_ = onOff;} +#else + inline bool collectStatistics() const + { return true;} + /// For statistics + inline void setCollectStatistics(bool onOff) const + { } +#endif + /// The real work of constructors etc 0 just scalars, 1 bit normal + void gutsOfDestructor(int type=1); + /// 1 bit - tolerances etc, 2 more, 4 dummy arrays + void gutsOfInitialize(int type); + void gutsOfCopy(const CoinFactorization &other); + + /// Reset all sparsity etc statistics + void resetStatistics(); + + + //@} + + /**@name used by factorization */ + /// Gets space for a factorization, called by constructors + void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /** PreProcesses raw triplet data. + state is 0 - triplets, 1 - some counts etc , 2 - .. */ + void preProcess ( int state, + int possibleDuplicates = -1 ); + /// Does most of factorization + int factor ( ); +protected: + /** Does sparse phase of factorization + return code is <0 error, 0= finished */ + int factorSparse ( ); + /** Does sparse phase of factorization (for smaller problems) + return code is <0 error, 0= finished */ + int factorSparseSmall ( ); + /** Does sparse phase of factorization (for larger problems) + return code is <0 error, 0= finished */ + int factorSparseLarge ( ); + /** Does dense phase of factorization + return code is <0 error, 0= finished */ + int factorDense ( ); + + /// Pivots when just one other row so faster? + bool pivotOneOtherRow ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Row Singleton in factorization + bool pivotRowSingleton ( int pivotRow, + int pivotColumn ); + /// Does one pivot on Column Singleton in factorization + bool pivotColumnSingleton ( int pivotRow, + int pivotColumn ); + + /** Gets space for one Column with given length, + may have to do compression (returns True if successful), + also moves existing vector, + extraNeeded is over and above present */ + bool getColumnSpace ( int iColumn, + int extraNeeded ); + + /** Reorders U so contiguous and in order (if there is space) + Returns true if it could */ + bool reorderU(); + /** getColumnSpaceIterateR. Gets space for one extra R element in Column + may have to do compression (returns true) + also moves existing vector */ + bool getColumnSpaceIterateR ( int iColumn, double value, + int iRow); + /** getColumnSpaceIterate. Gets space for one extra U element in Column + may have to do compression (returns true) + also moves existing vector. + Returns -1 if no memory or where element was put + Used by replaceRow (turns off R version) */ + CoinBigIndex getColumnSpaceIterate ( int iColumn, double value, + int iRow); + /** Gets space for one Row with given length, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpace ( int iRow, int extraNeeded ); + + /** Gets space for one Row with given length while iterating, + may have to do compression (returns True if successful), + also moves existing vector */ + bool getRowSpaceIterate ( int iRow, + int extraNeeded ); + /// Checks that row and column copies look OK + void checkConsistency ( ); + /// Adds a link in chain of equal counts + inline void addLink ( int index, int count ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = firstCount[count]; + lastCount[index] = -2 - count; + if ( next < 0 ) { + //first with that count + firstCount[count] = index; + nextCount[index] = -1; + } else { + firstCount[count] = index; + nextCount[index] = next; + lastCount[next] = index; + }} + /// Deletes a link in chain of equal counts + inline void deleteLink ( int index ) { + int *nextCount = nextCount_.array(); + int *firstCount = firstCount_.array(); + int *lastCount = lastCount_.array(); + int next = nextCount[index]; + int last = lastCount[index]; + if ( last >= 0 ) { + nextCount[last] = next; + } else { + int count = -last - 2; + + firstCount[count] = next; + } + if ( next >= 0 ) { + lastCount[next] = last; + } + nextCount[index] = -2; + lastCount[index] = -2; + return; + } + /// Separate out links with same row/column count + void separateLinks(int count,bool rowsFirst); + /// Cleans up at end of factorization + void cleanup ( ); + + /// Updates part of column (FTRANL) + void updateColumnL ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when densish + void updateColumnLDensish ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparse + void updateColumnLSparse ( CoinIndexedVector * region, int * indexIn ) const; + /// Updates part of column (FTRANL) when sparsish + void updateColumnLSparsish ( CoinIndexedVector * region, int * indexIn ) const; + + /// Updates part of column (FTRANR) without FT update + void updateColumnR ( CoinIndexedVector * region ) const; + /** Updates part of column (FTRANR) with FT update. + Also stores update after L and R */ + void updateColumnRFT ( CoinIndexedVector * region, int * indexIn ); + + /// Updates part of column (FTRANU) + void updateColumnU ( CoinIndexedVector * region, int * indexIn) const; + + /// Updates part of column (FTRANU) when sparse + void updateColumnUSparse ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) when sparsish + void updateColumnUSparsish ( CoinIndexedVector * regionSparse, + int * indexIn) const; + /// Updates part of column (FTRANU) + int updateColumnUDensish ( double * COIN_RESTRICT region, + int * COIN_RESTRICT regionIndex) const; + /// Updates part of 2 columns (FTRANU) real work + void updateTwoColumnsUDensish ( + int & numberNonZero1, + double * COIN_RESTRICT region1, + int * COIN_RESTRICT index1, + int & numberNonZero2, + double * COIN_RESTRICT region2, + int * COIN_RESTRICT index2) const; + /// Updates part of column PFI (FTRAN) (after rest) + void updateColumnPFI ( CoinIndexedVector * regionSparse) const; + /// Permutes back at end of updateColumn + void permuteBack ( CoinIndexedVector * regionSparse, + CoinIndexedVector * outVector) const; + + /// Updates part of column transpose PFI (BTRAN) (before rest) + void updateColumnTransposePFI ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU), + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeU ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparsish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparsish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when densish, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUDensish ( CoinIndexedVector * region, + int smallestIndex) const; + /** Updates part of column transpose (BTRANU) when sparse, + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUSparse ( CoinIndexedVector * region) const; + /** Updates part of column transpose (BTRANU) by column + assumes index is sorted i.e. region is correct */ + void updateColumnTransposeUByColumn ( CoinIndexedVector * region, + int smallestIndex) const; + + /// Updates part of column transpose (BTRANR) + void updateColumnTransposeR ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when dense + void updateColumnTransposeRDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANR) when sparse + void updateColumnTransposeRSparse ( CoinIndexedVector * region ) const; + + /// Updates part of column transpose (BTRANL) + void updateColumnTransposeL ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by column + void updateColumnTransposeLDensish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when densish by row + void updateColumnTransposeLByRow ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparsish by row + void updateColumnTransposeLSparsish ( CoinIndexedVector * region ) const; + /// Updates part of column transpose (BTRANL) when sparse (by Row) + void updateColumnTransposeLSparse ( CoinIndexedVector * region ) const; +public: + /** Replaces one Column to basis for PFI + returns 0=OK, 1=Probably OK, 2=singular, 3=no room. + In this case region is not empty - it is incoming variable (updated) + */ + int replaceColumnPFI ( CoinIndexedVector * regionSparse, + int pivotRow, double alpha); +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; + /********************************* START LARGE TEMPLATE ********/ +#ifdef INT_IS_8 +#define COINFACTORIZATION_BITS_PER_INT 64 +#define COINFACTORIZATION_SHIFT_PER_INT 6 +#define COINFACTORIZATION_MASK_PER_INT 0x3f +#else +#define COINFACTORIZATION_BITS_PER_INT 32 +#define COINFACTORIZATION_SHIFT_PER_INT 5 +#define COINFACTORIZATION_MASK_PER_INT 0x1f +#endif + template <class T> inline bool + pivot ( int pivotRow, + int pivotColumn, + CoinBigIndex pivotRowPosition, + CoinBigIndex pivotColumnPosition, + CoinFactorizationDouble work[], + unsigned int workArea2[], + int increment2, + T markRow[] , + int largeInteger) +{ + int *indexColumnU = indexColumnU_.array(); + CoinBigIndex *startColumnU = startColumnU_.array(); + int *numberInColumn = numberInColumn_.array(); + CoinFactorizationDouble *elementU = elementU_.array(); + int *indexRowU = indexRowU_.array(); + CoinBigIndex *startRowU = startRowU_.array(); + int *numberInRow = numberInRow_.array(); + CoinFactorizationDouble *elementL = elementL_.array(); + int *indexRowL = indexRowL_.array(); + int *saveColumn = saveColumn_.array(); + int *nextRow = nextRow_.array(); + int *lastRow = lastRow_.array() ; + + //store pivot columns (so can easily compress) + int numberInPivotRow = numberInRow[pivotRow] - 1; + CoinBigIndex startColumn = startColumnU[pivotColumn]; + int numberInPivotColumn = numberInColumn[pivotColumn] - 1; + CoinBigIndex endColumn = startColumn + numberInPivotColumn + 1; + int put = 0; + CoinBigIndex startRow = startRowU[pivotRow]; + CoinBigIndex endRow = startRow + numberInPivotRow + 1; + + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRow; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumnU[pivotColumnPosition]; + if ( iColumn != pivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRow ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumnU[i]; + } + } + assert (pivotColumnPosition<endRow); + assert (indexColumnU[pivotColumnPosition]==pivotColumn); + pivotColumnPosition++; + for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + saveColumn[put++] = indexColumnU[pivotColumnPosition]; + } + //take out this bit of indexColumnU + int next = nextRow[pivotRow]; + int last = lastRow[pivotRow]; + + nextRow[last] = next; + lastRow[next] = last; + nextRow[pivotRow] = numberGoodU_; //use for permute + lastRow[pivotRow] = -2; + numberInRow[pivotRow] = 0; + //store column in L, compress in U and take column out + CoinBigIndex l = lengthL_; + + if ( l + numberInPivotColumn > lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + return false; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberInPivotColumn; + lengthL_ += numberInPivotColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumn; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRowU[pivotRowPosition]; + if ( iRow != pivotRow ) { + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + markRow[iRow] = static_cast<T>(l - lSave); + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumn; i < pivotRowPosition; i++ ) { + int iRow = indexRowU[i]; + + markRow[iRow] = static_cast<T>(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[i]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition<endColumn); + assert (indexRowU[pivotRowPosition]==pivotRow); + CoinFactorizationDouble pivotElement = elementU[pivotRowPosition]; + CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement; + + pivotRegion_.array()[numberGoodU_] = pivotMultiplier; + pivotRowPosition++; + for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRowU[pivotRowPosition]; + + markRow[iRow] = static_cast<T>(l - lSave); + indexRowL[l] = iRow; + elementL[l] = elementU[pivotRowPosition]; + l++; + //take out of row list + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != pivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[pivotRow] = static_cast<T>(largeInteger); + //compress pivot column (move pivot to front including saved) + numberInColumn[pivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberInPivotColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberInPivotRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberInPivotRow * numberInPivotColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumn = startColumnU[iColumn]; + CoinBigIndex endColumn = startColumn + numberInColumn[iColumn]; + int iRow = indexRowU[startColumn]; + CoinFactorizationDouble value = elementU[startColumn]; + double largest; + CoinBigIndex put = startColumn; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumn + 1; i < endColumn; i++ ) { + iRow = indexRowU[i]; + value = elementU[i]; + int mark = markRow[iRow]; + + if ( mark == largeInteger+1 ) { + //keep + indexRowU[put] = iRow; + elementU[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != largeInteger ) { + //will be updated + work[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + elementU[put] = elementU[startColumn]; + indexRowU[put] = indexRowU[startColumn]; + if ( positionLargest == startColumn ) { + positionLargest = put; //follow if was largest + } + put++; + elementU[startColumn] = thisPivotValue; + indexRowU[startColumn] = pivotRow; + //clean up counts + startColumn++; + numberInColumn[iColumn] = put - startColumn; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumnU[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumnU[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberInPivotColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberInPivotColumn ) ) { + return false; + } + //redo starts + if (positionLargest >= 0) + positionLargest = positionLargest + startColumnU[iColumn] - startColumn; + startColumn = startColumnU[iColumn]; + put = startColumn + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberInPivotColumn; j++ ) { + value = work[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + work[j] = 0.0; + assert (put<lengthAreaU_); + elementU[put] = value; + indexRowU[put] = indexL[j]; + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + work[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRowU[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumnU[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumnU[where] = indexColumnU[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumn; + //move largest + if ( positionLargest >= 0 ) { + value = elementU[positionLargest]; + iRow = indexRowU[positionLargest]; + elementU[positionLargest] = elementU[startColumn]; + indexRowU[positionLargest] = indexRowU[startColumn]; + elementU[startColumn] = value; + indexRowU[startColumn] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberInPivotColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast<T>(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberInPivotColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRowU[next] - startRowU[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + return false; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRowU[iRow] + number; + int saveIndex; + + saveIndex = indexColumnU[startRowU[next]]; + + //add in + for ( jColumn = 0; jColumn < numberInPivotRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumnU[end] = saveColumn[jColumn]; + end += test; + } + indexColumnU[startRowU[next]] = saveIndex; + markRow[iRow] = static_cast<T>(largeInteger+1); + number = end - startRowU[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[pivotRow] = static_cast<T>(largeInteger+1); + //modify linked list for pivots + deleteLink ( pivotRow ); + deleteLink ( pivotColumn + numberRows_ ); + totalElements_ += added; + return true; +} + + /********************************* END LARGE TEMPLATE ********/ + //@} +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Pivot tolerance + double pivotTolerance_; + /// Zero tolerance + double zeroTolerance_; +#ifndef COIN_FAST_CODE + /// Whether slack value is +1 or -1 + double slackValue_; +#else +#ifndef slackValue_ +#define slackValue_ -1.0 +#endif +#endif + /// How much to multiply areas by + double areaFactor_; + /// Relax check on accuracy in replaceColumn + double relaxCheck_; + /// Number of Rows in factorization + int numberRows_; + /// Number of Rows after iterating + int numberRowsExtra_; + /// Maximum number of Rows after iterating + int maximumRowsExtra_; + /// Number of Columns in factorization + int numberColumns_; + /// Number of Columns after iterating + int numberColumnsExtra_; + /// Maximum number of Columns after iterating + int maximumColumnsExtra_; + /// Number factorized in U (not row singletons) + int numberGoodU_; + /// Number factorized in L + int numberGoodL_; + /// Maximum number of pivots before factorization + int maximumPivots_; + /// Number pivots since last factorization + int numberPivots_; + /// Number of elements in U (to go) + /// or while iterating total overall + CoinBigIndex totalElements_; + /// Number of elements after factorization + CoinBigIndex factorElements_; + /// Pivot order for each Column + CoinIntArrayWithLength pivotColumn_; + /// Permutation vector for pivot row order + CoinIntArrayWithLength permute_; + /// DePermutation vector for pivot row order + CoinIntArrayWithLength permuteBack_; + /// Inverse Pivot order for each Column + CoinIntArrayWithLength pivotColumnBack_; + /// Status of factorization + int status_; + + /** 0 - no increasing rows - no permutations, + 1 - no increasing rows but permutations + 2 - increasing rows + - taken out as always 2 */ + //int increasingRows_; + + /// Number of trials before rejection + int numberTrials_; + /// Start of each Row as pointer + CoinBigIndexArrayWithLength startRowU_; + + /// Number in each Row + CoinIntArrayWithLength numberInRow_; + + /// Number in each Column + CoinIntArrayWithLength numberInColumn_; + + /// Number in each Column including pivoted + CoinIntArrayWithLength numberInColumnPlus_; + + /** First Row/Column with count of k, + can tell which by offset - Rows then Columns */ + CoinIntArrayWithLength firstCount_; + + /// Next Row/Column with count + CoinIntArrayWithLength nextCount_; + + /// Previous Row/Column with count + CoinIntArrayWithLength lastCount_; + + /// Next Column in memory order + CoinIntArrayWithLength nextColumn_; + + /// Previous Column in memory order + CoinIntArrayWithLength lastColumn_; + + /// Next Row in memory order + CoinIntArrayWithLength nextRow_; + + /// Previous Row in memory order + CoinIntArrayWithLength lastRow_; + + /// Columns left to do in a single pivot + CoinIntArrayWithLength saveColumn_; + + /// Marks rows to be updated + CoinIntArrayWithLength markRow_; + + /// Detail in messages + int messageLevel_; + + /// Larger of row and column size + int biggerDimension_; + + /// Base address for U (may change) + CoinIntArrayWithLength indexColumnU_; + + /// Pivots for L + CoinIntArrayWithLength pivotRowL_; + + /// Inverses of pivot values + CoinFactorizationDoubleArrayWithLength pivotRegion_; + + /// Number of slacks at beginning of U + int numberSlacks_; + + /// Number in U + int numberU_; + + /// Maximum space used in U + CoinBigIndex maximumU_; + + /// Base of U is always 0 + //int baseU_; + + /// Length of U + CoinBigIndex lengthU_; + + /// Length of area reserved for U + CoinBigIndex lengthAreaU_; + +/// Elements of U + CoinFactorizationDoubleArrayWithLength elementU_; + +/// Row indices of U + CoinIntArrayWithLength indexRowU_; + +/// Start of each column in U + CoinBigIndexArrayWithLength startColumnU_; + +/// Converts rows to columns in U + CoinBigIndexArrayWithLength convertRowToColumnU_; + + /// Number in L + CoinBigIndex numberL_; + +/// Base of L + CoinBigIndex baseL_; + + /// Length of L + CoinBigIndex lengthL_; + + /// Length of area reserved for L + CoinBigIndex lengthAreaL_; + + /// Elements of L + CoinFactorizationDoubleArrayWithLength elementL_; + + /// Row indices of L + CoinIntArrayWithLength indexRowL_; + + /// Start of each column in L + CoinBigIndexArrayWithLength startColumnL_; + + /// true if Forrest Tomlin update, false if PFI + bool doForrestTomlin_; + + /// Number in R + int numberR_; + + /// Length of R stuff + CoinBigIndex lengthR_; + + /// length of area reserved for R + CoinBigIndex lengthAreaR_; + + /// Elements of R + CoinFactorizationDouble *elementR_; + + /// Row indices for R + int *indexRowR_; + + /// Start of columns for R + CoinBigIndexArrayWithLength startColumnR_; + + /// Dense area + double * denseArea_; + + /// Dense area - actually used (for alignment etc) + double * denseAreaAddress_; + + /// Dense permutation + int * densePermute_; + + /// Number of dense rows + int numberDense_; + + /// Dense threshold + int denseThreshold_; + + /// First work area + CoinFactorizationDoubleArrayWithLength workArea_; + + /// Second work area + CoinUnsignedIntArrayWithLength workArea2_; + + /// Number of compressions done + CoinBigIndex numberCompressions_; + +public: + /// Below are all to collect + mutable double ftranCountInput_; + mutable double ftranCountAfterL_; + mutable double ftranCountAfterR_; + mutable double ftranCountAfterU_; + mutable double btranCountInput_; + mutable double btranCountAfterU_; + mutable double btranCountAfterR_; + mutable double btranCountAfterL_; + + /// We can roll over factorizations + mutable int numberFtranCounts_; + mutable int numberBtranCounts_; + + /// While these are average ratios collected over last period + double ftranAverageAfterL_; + double ftranAverageAfterR_; + double ftranAverageAfterU_; + double btranAverageAfterU_; + double btranAverageAfterR_; + double btranAverageAfterL_; +protected: + + /// For statistics +#if 0 + mutable bool collectStatistics_; +#else +#define collectStatistics_ 1 +#endif + + /// Below this use sparse technology - if 0 then no L row copy + int sparseThreshold_; + + /// And one for "sparsish" + int sparseThreshold2_; + + /// Start of each row in L + CoinBigIndexArrayWithLength startRowL_; + + /// Index of column in row for L + CoinIntArrayWithLength indexColumnL_; + + /// Elements in L (row copy) + CoinFactorizationDoubleArrayWithLength elementByRowL_; + + /// Sparse regions + mutable CoinIntArrayWithLength sparse_; + /** L to U bias + 0 - U bias, 1 - some U bias, 2 some L bias, 3 L bias + */ + int biasLU_; + /** Array persistence flag + If 0 then as now (delete/new) + 1 then only do arrays if bigger needed + 2 as 1 but give a bit extra if bigger needed + */ + int persistenceFlag_; +#ifdef ABC_USE_COIN_FACTORIZATION + /// Says if parallel + int parallelMode_; +#endif + //@} +}; +// Dense coding +#ifdef COIN_HAS_LAPACK +#ifndef COIN_FACTORIZATION_DENSE_CODE +#define COIN_FACTORIZATION_DENSE_CODE 1 +#endif +#endif +#ifdef COIN_FACTORIZATION_DENSE_CODE +/* Type of Fortran integer translated into C */ +#ifndef ipfint +//typedef ipfint FORTRAN_INTEGER_TYPE ; +typedef int ipfint; +typedef const int cipfint; +#endif +#endif +#endif +// Extra for ugly include +#ifdef UGLY_COIN_FACTOR_CODING +#define FAC_UNSET (FAC_SET+1) +{ + goodPivot=false; + //store pivot columns (so can easily compress) + CoinBigIndex startColumnThis = startColumn[iPivotColumn]; + CoinBigIndex endColumn = startColumnThis + numberDoColumn + 1; + int put = 0; + CoinBigIndex startRowThis = startRow[iPivotRow]; + CoinBigIndex endRow = startRowThis + numberDoRow + 1; + if ( pivotColumnPosition < 0 ) { + for ( pivotColumnPosition = startRowThis; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + int iColumn = indexColumn[pivotColumnPosition]; + if ( iColumn != iPivotColumn ) { + saveColumn[put++] = iColumn; + } else { + break; + } + } + } else { + for (CoinBigIndex i = startRowThis ; i < pivotColumnPosition ; i++ ) { + saveColumn[put++] = indexColumn[i]; + } + } + assert (pivotColumnPosition<endRow); + assert (indexColumn[pivotColumnPosition]==iPivotColumn); + pivotColumnPosition++; + for ( ; pivotColumnPosition < endRow; pivotColumnPosition++ ) { + saveColumn[put++] = indexColumn[pivotColumnPosition]; + } + //take out this bit of indexColumn + int next = nextRow[iPivotRow]; + int last = lastRow[iPivotRow]; + + nextRow[last] = next; + lastRow[next] = last; + nextRow[iPivotRow] = numberGoodU_; //use for permute + lastRow[iPivotRow] = -2; + numberInRow[iPivotRow] = 0; + //store column in L, compress in U and take column out + CoinBigIndex l = lengthL_; + // **** HORRID coding coming up but a goto seems best! + { + if ( l + numberDoColumn > lengthAreaL_ ) { + //need more memory + if ((messageLevel_&4)!=0) + printf("more memory needed in middle of invert\n"); + goto BAD_PIVOT; + } + //l+=currentAreaL_->elementByColumn-elementL; + CoinBigIndex lSave = l; + + CoinBigIndex * startColumnL = startColumnL_.array(); + startColumnL[numberGoodL_] = l; //for luck and first time + numberGoodL_++; + startColumnL[numberGoodL_] = l + numberDoColumn; + lengthL_ += numberDoColumn; + if ( pivotRowPosition < 0 ) { + for ( pivotRowPosition = startColumnThis; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRow[pivotRowPosition]; + if ( iRow != iPivotRow ) { + indexRowL[l] = iRow; + elementL[l] = element[pivotRowPosition]; + markRow[iRow] = l - lSave; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + break; + } + } + } else { + CoinBigIndex i; + + for ( i = startColumnThis; i < pivotRowPosition; i++ ) { + int iRow = indexRow[i]; + + markRow[iRow] = l - lSave; + indexRowL[l] = iRow; + elementL[l] = element[i]; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + } + assert (pivotRowPosition<endColumn); + assert (indexRow[pivotRowPosition]==iPivotRow); + CoinFactorizationDouble pivotElement = element[pivotRowPosition]; + CoinFactorizationDouble pivotMultiplier = 1.0 / pivotElement; + + pivotRegion_.array()[numberGoodU_] = pivotMultiplier; + pivotRowPosition++; + for ( ; pivotRowPosition < endColumn; pivotRowPosition++ ) { + int iRow = indexRow[pivotRowPosition]; + + markRow[iRow] = l - lSave; + indexRowL[l] = iRow; + elementL[l] = element[pivotRowPosition]; + l++; + //take out of row list + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iPivotColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + assert (numberInRow[iRow]>=0); + } + markRow[iPivotRow] = FAC_SET; + //compress pivot column (move pivot to front including saved) + numberInColumn[iPivotColumn] = 0; + //use end of L for temporary space + int *indexL = &indexRowL[lSave]; + CoinFactorizationDouble *multipliersL = &elementL[lSave]; + + //adjust + int j; + + for ( j = 0; j < numberDoColumn; j++ ) { + multipliersL[j] *= pivotMultiplier; + } + //zero out fill + CoinBigIndex iErase; + for ( iErase = 0; iErase < increment2 * numberDoRow; + iErase++ ) { + workArea2[iErase] = 0; + } + CoinBigIndex added = numberDoRow * numberDoColumn; + unsigned int *temp2 = workArea2; + int * nextColumn = nextColumn_.array(); + + //pack down and move to work + int jColumn; + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + int iColumn = saveColumn[jColumn]; + CoinBigIndex startColumnThis = startColumn[iColumn]; + CoinBigIndex endColumn = startColumnThis + numberInColumn[iColumn]; + int iRow = indexRow[startColumnThis]; + CoinFactorizationDouble value = element[startColumnThis]; + double largest; + CoinBigIndex put = startColumnThis; + CoinBigIndex positionLargest = -1; + CoinFactorizationDouble thisPivotValue = 0.0; + + //compress column and find largest not updated + bool checkLargest; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + largest = fabs ( value ); + positionLargest = put; + put++; + checkLargest = false; + } else { + //need to find largest + largest = 0.0; + checkLargest = true; + if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + CoinBigIndex i; + for ( i = startColumnThis + 1; i < endColumn; i++ ) { + iRow = indexRow[i]; + value = element[i]; + int mark = markRow[iRow]; + + if ( mark == FAC_UNSET ) { + //keep + indexRow[put] = iRow; + element[put] = value; + if ( checkLargest ) { + double absValue = fabs ( value ); + + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + } + put++; + } else if ( mark != FAC_SET ) { + //will be updated + workArea[mark] = value; + int word = mark >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = mark & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + added--; + } else { + thisPivotValue = value; + } + } + //slot in pivot + element[put] = element[startColumnThis]; + indexRow[put] = indexRow[startColumnThis]; + if ( positionLargest == startColumnThis ) { + positionLargest = put; //follow if was largest + } + put++; + element[startColumnThis] = thisPivotValue; + indexRow[startColumnThis] = iPivotRow; + //clean up counts + startColumnThis++; + numberInColumn[iColumn] = put - startColumnThis; + int * numberInColumnPlus = numberInColumnPlus_.array(); + numberInColumnPlus[iColumn]++; + startColumn[iColumn]++; + //how much space have we got + int next = nextColumn[iColumn]; + CoinBigIndex space; + + space = startColumn[next] - put - numberInColumnPlus[next]; + //assume no zero elements + if ( numberDoColumn > space ) { + //getColumnSpace also moves fixed part + if ( !getColumnSpace ( iColumn, numberDoColumn ) ) { + goto BAD_PIVOT; + } + //redo starts + positionLargest = positionLargest + startColumn[iColumn] - startColumnThis; + startColumnThis = startColumn[iColumn]; + put = startColumnThis + numberInColumn[iColumn]; + } + double tolerance = zeroTolerance_; + + int *nextCount = nextCount_.array(); + for ( j = 0; j < numberDoColumn; j++ ) { + value = workArea[j] - thisPivotValue * multipliersL[j]; + double absValue = fabs ( value ); + + if ( absValue > tolerance ) { + workArea[j] = 0.0; + element[put] = value; + indexRow[put] = indexL[j]; + if ( absValue > largest ) { + largest = absValue; + positionLargest = put; + } + put++; + } else { + workArea[j] = 0.0; + added--; + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + if ( temp2[word] & ( 1 << bit ) ) { + //take out of row list + iRow = indexL[j]; + CoinBigIndex start = startRow[iRow]; + CoinBigIndex end = start + numberInRow[iRow]; + CoinBigIndex where = start; + + while ( indexColumn[where] != iColumn ) { + where++; + } /* endwhile */ +#if DEBUG_COIN + if ( where >= end ) { + abort ( ); + } +#endif + indexColumn[where] = indexColumn[end - 1]; + numberInRow[iRow]--; + } else { + //make sure won't be added + int word = j >> COINFACTORIZATION_SHIFT_PER_INT; + int bit = j & COINFACTORIZATION_MASK_PER_INT; + + temp2[word] = temp2[word] | ( 1 << bit ); //say already in counts + } + } + } + numberInColumn[iColumn] = put - startColumnThis; + //move largest + if ( positionLargest >= 0 ) { + value = element[positionLargest]; + iRow = indexRow[positionLargest]; + element[positionLargest] = element[startColumnThis]; + indexRow[positionLargest] = indexRow[startColumnThis]; + element[startColumnThis] = value; + indexRow[startColumnThis] = iRow; + } + //linked list for column + if ( nextCount[iColumn + numberRows_] != -2 ) { + //modify linked list + deleteLink ( iColumn + numberRows_ ); + addLink ( iColumn + numberRows_, numberInColumn[iColumn] ); + } + temp2 += increment2; + } + //get space for row list + unsigned int *putBase = workArea2; + int bigLoops = numberDoColumn >> COINFACTORIZATION_SHIFT_PER_INT; + int i = 0; + + // do linked lists and update counts + while ( bigLoops ) { + bigLoops--; + int bit; + for ( bit = 0; bit < COINFACTORIZATION_BITS_PER_INT; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + //put back next one in case zapped + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + putBase++; + } /* endwhile */ + int bit; + + for ( bit = 0; i < numberDoColumn; i++, bit++ ) { + unsigned int *putThis = putBase; + int iRow = indexL[i]; + + //get space + int number = 0; + int jColumn; + + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + number += test; + } + int next = nextRow[iRow]; + CoinBigIndex space; + + space = startRow[next] - startRow[iRow]; + number += numberInRow[iRow]; + if ( space < number ) { + if ( !getRowSpace ( iRow, number ) ) { + goto BAD_PIVOT; + } + } + // now do + putThis = putBase; + next = nextRow[iRow]; + number = numberInRow[iRow]; + CoinBigIndex end = startRow[iRow] + number; + int saveIndex; + + saveIndex = indexColumn[startRow[next]]; + + //add in + for ( jColumn = 0; jColumn < numberDoRow; jColumn++ ) { + unsigned int test = *putThis; + + putThis += increment2; + test = 1 - ( ( test >> bit ) & 1 ); + + indexColumn[end] = saveColumn[jColumn]; + end += test; + } + indexColumn[startRow[next]] = saveIndex; + markRow[iRow] = FAC_UNSET; + number = end - startRow[iRow]; + numberInRow[iRow] = number; + deleteLink ( iRow ); + addLink ( iRow, number ); + } + markRow[iPivotRow] = FAC_UNSET; + //modify linked list for pivots + deleteLink ( iPivotRow ); + deleteLink ( iPivotColumn + numberRows_ ); + totalElements_ += added; + goodPivot= true; + // **** UGLY UGLY UGLY + } + BAD_PIVOT: + + ; +} +#undef FAC_UNSET +#endif diff --git a/thirdparty/linux/include/coin1/CoinFileIO.hpp b/thirdparty/linux/include/coin1/CoinFileIO.hpp new file mode 100644 index 0000000..20be1a9 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinFileIO.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinFileIO.hpp 1439 2011-06-13 16:31:21Z stefan $ */ +// Copyright (C) 2005, COIN-OR. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFileIO_H +#define CoinFileIO_H + +#include <string> + +/// Base class for FileIO classes. +class CoinFileIOBase +{ +public: + /// Constructor. + /// @param fileName The name of the file used by this object. + CoinFileIOBase (const std::string &fileName); + + /// Destructor. + ~CoinFileIOBase (); + + /// Return the name of the file used by this object. + const char *getFileName () const; + + /// Return the method of reading being used + inline std::string getReadType () const + { return readType_.c_str();} +protected: + std::string readType_; +private: + CoinFileIOBase (); + CoinFileIOBase (const CoinFileIOBase &); + + std::string fileName_; +}; + +/// Abstract base class for file input classes. +class CoinFileInput: public CoinFileIOBase +{ +public: + /// indicates whether CoinFileInput supports gzip'ed files + static bool haveGzipSupport(); + /// indicates whether CoinFileInput supports bzip2'ed files + static bool haveBzip2Support(); + + /// Factory method, that creates a CoinFileInput (more precisely + /// a subclass of it) for the file specified. This method reads the + /// first few bytes of the file and determines if this is a compressed + /// or a plain file and returns the correct subclass to handle it. + /// If the file does not exist or uses a compression not compiled in + /// an exception is thrown. + /// @param fileName The file that should be read. + static CoinFileInput *create (const std::string &fileName); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileInput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileInput (); + + /// Read a block of data from the file, similar to fread. + /// @param buffer Address of a buffer to store the data into. + /// @param size Number of bytes to read (buffer should be large enough). + /// @return Number of bytes read. + virtual int read (void *buffer, int size) = 0; + + /// Reads up to (size-1) characters an stores them into the buffer, + /// similar to fgets. + /// Reading ends, when EOF or a newline occurs or (size-1) characters have + /// been read. The resulting string is terminated with '\0'. If reading + /// ends due to an encoutered newline, the '\n' is put into the buffer, + /// before the '\0' is appended. + /// @param buffer The buffer to put the string into. + /// @param size The size of the buffer in characters. + /// @return buffer on success, or 0 if no characters have been read. + virtual char *gets (char *buffer, int size) = 0; +}; + +/// Abstract base class for file output classes. +class CoinFileOutput: public CoinFileIOBase +{ +public: + + /// The compression method. + enum Compression { + COMPRESS_NONE = 0, ///< No compression. + COMPRESS_GZIP = 1, ///< gzip compression. + COMPRESS_BZIP2 = 2 ///< bzip2 compression. + }; + + /// Returns whether the specified compression method is supported + /// (i.e. was compiled into COIN). + static bool compressionSupported (Compression compression); + + /// Factory method, that creates a CoinFileOutput (more precisely + /// a subclass of it) for the file specified. If the compression method + /// is not supported an exception is thrown (so use compressionSupported + /// first, if this is a problem). The reason for not providing direct + /// access to the subclasses (and using such a method instead) is that + /// depending on the build configuration some of the classes are not + /// available (or functional). This way we can handle all required ifdefs + /// here instead of polluting other files. + /// @param fileName The file that should be read. + /// @param compression Compression method used. + static CoinFileOutput *create (const std::string &fileName, + Compression compression); + + /// Constructor (don't use this, use the create method instead). + /// @param fileName The name of the file used by this object. + CoinFileOutput (const std::string &fileName); + + /// Destructor. + virtual ~CoinFileOutput (); + + /// Write a block of data to the file, similar to fwrite. + /// @param buffer Address of a buffer containing the data to be written. + /// @param size Number of bytes to write. + /// @return Number of bytes written. + virtual int write (const void * buffer, int size) = 0; + + /// Write a string to the file (like fputs). + /// Just as with fputs no trailing newline is inserted! + /// The terminating '\0' is not written to the file. + /// The default implementation determines the length of the string + /// and calls write on it. + /// @param s The zero terminated string to be written. + /// @return true on success, false on error. + virtual bool puts (const char *s); + + /// Convenience method: just a 'puts(s.c_str())'. + inline bool puts (const std::string &s) + { + return puts (s.c_str ()); + } +}; + +/*! \relates CoinFileInput + \brief Test if the given string looks like an absolute file path + + The criteria are: + - unix: string begins with `/' + - windows: string begins with `\' or with `drv:' (drive specifier) +*/ +bool fileAbsPath (const std::string &path) ; + +/*! \relates CoinFileInput + \brief Test if the file is readable, using likely versions of the file + name, and return the name that worked. + + The file name is constructed from \p name using the following rules: + <ul> + <li> An absolute path is not modified. + <li> If the name begins with `~', an attempt is made to replace `~' + with the value of the environment variable HOME. + <li> If a default prefix (\p dfltPrefix) is provided, it is + prepended to the name. + </ul> + If the constructed file name cannot be opened, and CoinUtils was built + with support for compressed files, fileCoinReadable will try any + standard extensions for supported compressed files. + + The value returned in \p name is the file name that actually worked. +*/ +bool fileCoinReadable(std::string &name, + const std::string &dfltPrefix = std::string("")); +#endif diff --git a/thirdparty/linux/include/coin1/CoinFinite.hpp b/thirdparty/linux/include/coin1/CoinFinite.hpp new file mode 100644 index 0000000..71b5b65 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinFinite.hpp @@ -0,0 +1,34 @@ +/* $Id: CoinFinite.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* Defines COIN_DBL_MAX and relatives and provides CoinFinite and CoinIsnan. */ + +#ifndef CoinFinite_H +#define CoinFinite_H + +#include <limits> + +//============================================================================= +// Smallest positive double value and Plus infinity (double and int) + +#if 1 +const double COIN_DBL_MIN = (std::numeric_limits<double>::min)(); +const double COIN_DBL_MAX = (std::numeric_limits<double>::max)(); +const int COIN_INT_MAX = (std::numeric_limits<int>::max)(); +const double COIN_INT_MAX_AS_DOUBLE = (std::numeric_limits<int>::max)(); +#else +#define COIN_DBL_MIN (std::numeric_limits<double>::min()) +#define COIN_DBL_MAX (std::numeric_limits<double>::max()) +#define COIN_INT_MAX (std::numeric_limits<int>::max()) +#define COIN_INT_MAX_AS_DOUBLE (std::numeric_limits<int>::max()) +#endif + +/** checks if a double value is finite (not infinity and not NaN) */ +extern bool CoinFinite(double val); + +/** checks if a double value is not a number */ +extern bool CoinIsnan(double val); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinFloatEqual.hpp b/thirdparty/linux/include/coin1/CoinFloatEqual.hpp new file mode 100644 index 0000000..d5edfff --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinFloatEqual.hpp @@ -0,0 +1,177 @@ +/* $Id: CoinFloatEqual.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinFloatEqual_H +#define CoinFloatEqual_H + +#include <algorithm> +#include <cmath> + +#include "CoinFinite.hpp" + +/*! \file CoinFloatEqual.hpp + \brief Function objects for testing equality of real numbers. + + Two objects are provided; one tests for equality to an absolute tolerance, + one to a scaled tolerance. The tests will handle IEEE floating point, but + note that infinity == infinity. Mathematicians are rolling in their graves, + but this matches the behaviour for the common practice of using + <code>DBL_MAX</code> (<code>numeric_limits<double>::max()</code>, or similar + large finite number) as infinity. + + <p> + Example usage: + @verbatim + double d1 = 3.14159 ; + double d2 = d1 ; + double d3 = d1+.0001 ; + + CoinAbsFltEq eq1 ; + CoinAbsFltEq eq2(.001) ; + + assert( eq1(d1,d2) ) ; + assert( !eq1(d1,d3) ) ; + assert( eq2(d1,d3) ) ; + @endverbatim + CoinRelFltEq follows the same pattern. */ + +/*! \brief Equality to an absolute tolerance + + Operands are considered equal if their difference is within an epsilon ; + the test does not consider the relative magnitude of the operands. +*/ + +class CoinAbsFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + return (fabs(f1-f2) < epsilon_) ; } + + /*! \name Constructors and destructors */ + //@{ + + /*! \brief Default constructor + + Default tolerance is 1.0e-10. + */ + + CoinAbsFltEq () : epsilon_(1.e-10) {} + + //! Alternate constructor with epsilon as a parameter + + CoinAbsFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinAbsFltEq () {} + + //! Copy constructor + + CoinAbsFltEq (const CoinAbsFltEq& src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinAbsFltEq& operator= (const CoinAbsFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + + private: + + /*! \name Private member data */ + //@{ + + //! Equality tolerance. + + double epsilon_ ; + + //@} + +} ; + + + +/*! \brief Equality to a scaled tolerance + + Operands are considered equal if their difference is within a scaled + epsilon calculated as epsilon_*(1+CoinMax(|f1|,|f2|)). +*/ + +class CoinRelFltEq +{ + public: + + //! Compare function + + inline bool operator() (const double f1, const double f2) const + + { if (CoinIsnan(f1) || CoinIsnan(f2)) return false ; + if (f1 == f2) return true ; + if (!CoinFinite(f1) || !CoinFinite(f2)) return false ; + + double tol = (fabs(f1)>fabs(f2))?fabs(f1):fabs(f2) ; + + return (fabs(f1-f2) <= epsilon_*(1+tol)) ; } + + /*! \name Constructors and destructors */ + //@{ + +#ifndef COIN_FLOAT + /*! Default constructor + + Default tolerance is 1.0e-10. + */ + CoinRelFltEq () : epsilon_(1.e-10) {} +#else + /*! Default constructor + + Default tolerance is 1.0e-6. + */ + CoinRelFltEq () : epsilon_(1.e-6) {} ; // as float +#endif + + //! Alternate constructor with epsilon as a parameter + + CoinRelFltEq (const double epsilon) : epsilon_(epsilon) {} + + //! Destructor + + virtual ~CoinRelFltEq () {} + + //! Copy constructor + + CoinRelFltEq (const CoinRelFltEq & src) : epsilon_(src.epsilon_) {} + + //! Assignment + + CoinRelFltEq& operator= (const CoinRelFltEq& rhs) + + { if (this != &rhs) epsilon_ = rhs.epsilon_ ; + return (*this) ; } + + //@} + +private: + + /*! \name Private member data */ + //@{ + + //! Base equality tolerance + + double epsilon_ ; + + //@} + +} ; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinHelperFunctions.hpp b/thirdparty/linux/include/coin1/CoinHelperFunctions.hpp new file mode 100644 index 0000000..3409bbc --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinHelperFunctions.hpp @@ -0,0 +1,1111 @@ +/* $Id: CoinHelperFunctions.hpp 1679 2013-12-05 11:27:45Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinHelperFunctions_H +#define CoinHelperFunctions_H + +#include "CoinUtilsConfig.h" + +#if defined(_MSC_VER) +# include <direct.h> +# include <cctype> +# define getcwd _getcwd +# include <cctype> +#else +# include <unistd.h> +#endif +//#define USE_MEMCPY + +#include <cstdlib> +#include <cstdio> +#include <algorithm> +#include "CoinTypes.hpp" +#include "CoinError.hpp" + +// Compilers can produce better code if they know about __restrict +#ifndef COIN_RESTRICT +#ifdef COIN_USE_RESTRICT +#define COIN_RESTRICT __restrict +#else +#define COIN_RESTRICT +#endif +#endif + +//############################################################################# + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The arrays are given by pointers to their + first entries and by the size of the source array. Overlapping arrays are + handled correctly. */ + +template <class T> inline void +CoinCopyN(register const T* from, const int size, register T* to) +{ + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinCopyN", ""); +#endif + + register int n = (size + 7) / 8; + if (to > from) { + register const T* downfrom = from + size; + register T* downto = to + size; + // Use Duff's device to copy + switch (size % 8) { + case 0: do{ *--downto = *--downfrom; + case 7: *--downto = *--downfrom; + case 6: *--downto = *--downfrom; + case 5: *--downto = *--downfrom; + case 4: *--downto = *--downfrom; + case 3: *--downto = *--downfrom; + case 2: *--downto = *--downfrom; + case 1: *--downto = *--downfrom; + }while(--n>0); + } + } else { + // Use Duff's device to copy + --from; + --to; + switch (size % 8) { + case 0: do{ *++to = *++from; + case 7: *++to = *++from; + case 6: *++to = *++from; + case 5: *++to = *++from; + case 4: *++to = *++from; + case 3: *++to = *++from; + case 2: *++to = *++from; + case 1: *++to = *++from; + }while(--n>0); + } + } +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location using Duff's + device (for a speedup of ~2). The source array is given by its first and + "after last" entry; the target array is given by its first entry. + Overlapping arrays are handled correctly. + + All of the various CoinCopyN variants use an int for size. On 64-bit + architectures, the address diff last-first will be a 64-bit quantity. + Given that everything else uses an int, I'm going to choose to kick + the difference down to int. -- lh, 100823 -- +*/ +template <class T> inline void +CoinCopy(register const T* first, register const T* last, register T* to) +{ + CoinCopyN(first, static_cast<int>(last-first), to); +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinMemcpyN which can be used for atomic data */ +template <class T> inline void +CoinDisjointCopyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinDisjointCopyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinDisjointCopyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#else + CoinCopyN(from, size, to); +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The source array is given by its first and "after + last" entry; the target array is given by its first entry. */ +template <class T> inline void +CoinDisjointCopy(register const T* first, register const T* last, + register T* to) +{ + CoinDisjointCopyN(first, static_cast<int>(last - first), to); +} + +//----------------------------------------------------------------------------- + +/*! \brief Return an array of length \p size filled with input from \p array, + or null if \p array is null. +*/ + +template <class T> inline T* +CoinCopyOfArray( const T * array, const int size) +{ + if (array) { + T * arrayNew = new T[size]; + std::memcpy(arrayNew,array,size*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + + +/*! \brief Return an array of length \p size filled with first copySize from \p array, + or null if \p array is null. +*/ + +template <class T> inline T* +CoinCopyOfArrayPartial( const T * array, const int size,const int copySize) +{ + if (array||size) { + T * arrayNew = new T[size]; + assert (copySize<=size); + std::memcpy(arrayNew,array,copySize*sizeof(T)); + return arrayNew; + } else { + return NULL; + } +} + +/*! \brief Return an array of length \p size filled with input from \p array, + or filled with (scalar) \p value if \p array is null +*/ + +template <class T> inline T* +CoinCopyOfArray( const T * array, const int size, T value) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + int i; + for (i=0;i<size;i++) + arrayNew[i] = value; + } + return arrayNew; +} + + +/*! \brief Return an array of length \p size filled with input from \p array, + or filled with zero if \p array is null +*/ + +template <class T> inline T* +CoinCopyOfArrayOrZero( const T * array , const int size) +{ + T * arrayNew = new T[size]; + if (array) { + std::memcpy(arrayNew,array,size*sizeof(T)); + } else { + std::memset(arrayNew,0,size*sizeof(T)); + } + return arrayNew; +} + + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The arrays are given by pointers to their first + entries and by the size of the source array. + + Note JJF - the speed claim seems to be false on IA32 so I have added + alternative coding if USE_MEMCPY defined*/ +#ifndef COIN_USE_RESTRICT +template <class T> inline void +CoinMemcpyN(register const T* from, const int size, register T* to) +{ +#ifndef _MSC_VER +#ifdef USE_MEMCPY + // Use memcpy - seems a lot faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif +#endif + std::memcpy(to,from,size*sizeof(T)); +#else + if (size == 0 || from == to) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to copy negative number of entries", + "CoinMemcpyN", ""); +#endif + +#if 0 + /* There is no point to do this test. If to and from are from different + blocks then dist is undefined, so this can crash correct code. It's + better to trust the user that the arrays are really disjoint. */ + const long dist = to - from; + if (-size < dist && dist < size) + throw CoinError("overlapping arrays", "CoinMemcpyN", ""); +#endif + + for (register int n = size / 8; n > 0; --n, from += 8, to += 8) { + to[0] = from[0]; + to[1] = from[1]; + to[2] = from[2]; + to[3] = from[3]; + to[4] = from[4]; + to[5] = from[5]; + to[6] = from[6]; + to[7] = from[7]; + } + switch (size % 8) { + case 7: to[6] = from[6]; + case 6: to[5] = from[5]; + case 5: to[4] = from[4]; + case 4: to[3] = from[3]; + case 3: to[2] = from[2]; + case 2: to[1] = from[1]; + case 1: to[0] = from[0]; + case 0: break; + } +#endif +#else + CoinCopyN(from, size, to); +#endif +} +#else +template <class T> inline void +CoinMemcpyN(const T * COIN_RESTRICT from, int size, T* COIN_RESTRICT to) +{ +#ifdef USE_MEMCPY + std::memcpy(to,from,size*sizeof(T)); +#else + T * COIN_RESTRICT put = to; + const T * COIN_RESTRICT get = from; + for ( ; 0<size ; --size) + *put++ = *get++; +#endif +} +#endif + +//----------------------------------------------------------------------------- + +/** This helper function copies an array to another location. The two arrays + must not overlap (otherwise an exception is thrown). For speed 8 entries + are copied at a time. The source array is given by its first and "after + last" entry; the target array is given by its first entry. */ +template <class T> inline void +CoinMemcpy(register const T* first, register const T* last, + register T* to) +{ + CoinMemcpyN(first, static_cast<int>(last - first), to); +} + +//############################################################################# + +/** This helper function fills an array with a given value. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have added + CoinZero to allow for memset. */ +template <class T> inline void +CoinFillN(register T* to, const int size, register const T value) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinFillN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = value; + to[1] = value; + to[2] = value; + to[3] = value; + to[4] = value; + to[5] = value; + to[6] = value; + to[7] = value; + } + switch (size % 8) { + case 7: to[6] = value; + case 6: to[5] = value; + case 5: to[4] = value; + case 4: to[3] = value; + case 3: to[2] = value; + case 2: to[1] = value; + case 1: to[0] = value; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = value; + case 7: *++to = value; + case 6: *++to = value; + case 5: *++to = value; + case 4: *++to = value; + case 3: *++to = value; + case 2: *++to = value; + case 1: *++to = value; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with a given value. For speed 8 + entries are filled at a time. The array is given by its first and "after + last" entry. */ +template <class T> inline void +CoinFill(register T* first, register T* last, const T value) +{ + CoinFillN(first, last - first, value); +} + +//############################################################################# + +/** This helper function fills an array with zero. For speed 8 entries + are filled at a time. The array is given by a pointer to its first entry + and its size. + + Note JJF - the speed claim seems to be false on IA32 so I have allowed + for memset as an alternative */ +template <class T> inline void +CoinZeroN(register T* to, const int size) +{ +#ifdef USE_MEMCPY + // Use memset - seems faster on Intel with gcc +#ifndef NDEBUG + // Some debug so check + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif + memset(to,0,size*sizeof(T)); +#else + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("trying to fill negative number of entries", + "CoinZeroN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, to += 8) { + to[0] = 0; + to[1] = 0; + to[2] = 0; + to[3] = 0; + to[4] = 0; + to[5] = 0; + to[6] = 0; + to[7] = 0; + } + switch (size % 8) { + case 7: to[6] = 0; + case 6: to[5] = 0; + case 5: to[4] = 0; + case 4: to[3] = 0; + case 3: to[2] = 0; + case 2: to[1] = 0; + case 1: to[0] = 0; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --to; + switch (size % 8) { + case 0: do{ *++to = 0; + case 7: *++to = 0; + case 6: *++to = 0; + case 5: *++to = 0; + case 4: *++to = 0; + case 3: *++to = 0; + case 2: *++to = 0; + case 1: *++to = 0; + }while(--n>0); + } +#endif +#endif +} +/// This Debug helper function checks an array is all zero +inline void +CoinCheckDoubleZero(double * to, const int size) +{ + int n=0; + for (int j=0;j<size;j++) { + if (to[j]) + n++; + } + if (n) { + printf("array of length %d should be zero has %d nonzero\n",size,n); + } +} +/// This Debug helper function checks an array is all zero +inline void +CoinCheckIntZero(int * to, const int size) +{ + int n=0; + for (int j=0;j<size;j++) { + if (to[j]) + n++; + } + if (n) { + printf("array of length %d should be zero has %d nonzero\n",size,n); + } +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with a given value. For speed 8 + entries are filled at a time. The array is given by its first and "after + last" entry. */ +template <class T> inline void +CoinZero(register T* first, register T* last) +{ + CoinZeroN(first, last - first); +} + +//############################################################################# + +/** Returns strdup or NULL if original NULL */ +inline char * CoinStrdup(const char * name) +{ + char* dup = NULL; + if (name) { + const int len = static_cast<int>(strlen(name)); + dup = static_cast<char*>(malloc(len+1)); + CoinMemcpyN(name, len, dup); + dup[len] = 0; + } + return dup; +} + +//############################################################################# + +/** Return the larger (according to <code>operator<()</code> of the arguments. + This function was introduced because for some reason compiler tend to + handle the <code>max()</code> function differently. */ +template <class T> inline T +CoinMax(register const T x1, register const T x2) +{ + return (x1 > x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the smaller (according to <code>operator<()</code> of the arguments. + This function was introduced because for some reason compiler tend to + handle the min() function differently. */ +template <class T> inline T +CoinMin(register const T x1, register const T x2) +{ + return (x1 < x2) ? x1 : x2; +} + +//----------------------------------------------------------------------------- + +/** Return the absolute value of the argument. This function was introduced + because for some reason compiler tend to handle the abs() function + differently. */ +template <class T> inline T +CoinAbs(const T value) +{ + return value<0 ? -value : value; +} + +//############################################################################# + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by a pointer to its first entry + and by its size. */ +template <class T> inline bool +CoinIsSorted(register const T* first, const int size) +{ + if (size == 0) + return true; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIsSorted", ""); +#endif +#if 1 + // size1 is the number of comparisons to be made + const int size1 = size - 1; + for (register int n = size1 / 8; n > 0; --n, first += 8) { + if (first[8] < first[7]) return false; + if (first[7] < first[6]) return false; + if (first[6] < first[5]) return false; + if (first[5] < first[4]) return false; + if (first[4] < first[3]) return false; + if (first[3] < first[2]) return false; + if (first[2] < first[1]) return false; + if (first[1] < first[0]) return false; + } + + switch (size1 % 8) { + case 7: if (first[7] < first[6]) return false; + case 6: if (first[6] < first[5]) return false; + case 5: if (first[5] < first[4]) return false; + case 4: if (first[4] < first[3]) return false; + case 3: if (first[3] < first[2]) return false; + case 2: if (first[2] < first[1]) return false; + case 1: if (first[1] < first[0]) return false; + case 0: break; + } +#else + register const T* next = first; + register const T* last = first + size; + for (++next; next != last; first = next, ++next) + if (*next < *first) + return false; +#endif + return true; +} + +//----------------------------------------------------------------------------- + +/** This helper function tests whether the entries of an array are sorted + according to operator<. The array is given by its first and "after + last" entry. */ +template <class T> inline bool +CoinIsSorted(register const T* first, register const T* last) +{ + return CoinIsSorted(first, static_cast<int>(last - first)); +} + +//############################################################################# + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by a + pointer to its first entry and its size. */ +template <class T> inline void +CoinIotaN(register T* first, const int size, register T init) +{ + if (size == 0) + return; + +#ifndef NDEBUG + if (size < 0) + throw CoinError("negative number of entries", "CoinIotaN", ""); +#endif +#if 1 + for (register int n = size / 8; n > 0; --n, first += 8, init += 8) { + first[0] = init; + first[1] = init + 1; + first[2] = init + 2; + first[3] = init + 3; + first[4] = init + 4; + first[5] = init + 5; + first[6] = init + 6; + first[7] = init + 7; + } + switch (size % 8) { + case 7: first[6] = init + 6; + case 6: first[5] = init + 5; + case 5: first[4] = init + 4; + case 4: first[3] = init + 3; + case 3: first[2] = init + 2; + case 2: first[1] = init + 1; + case 1: first[0] = init; + case 0: break; + } +#else + // Use Duff's device to fill + register int n = (size + 7) / 8; + --first; + --init; + switch (size % 8) { + case 0: do{ *++first = ++init; + case 7: *++first = ++init; + case 6: *++first = ++init; + case 5: *++first = ++init; + case 4: *++first = ++init; + case 3: *++first = ++init; + case 2: *++first = ++init; + case 1: *++first = ++init; + }while(--n>0); + } +#endif +} + +//----------------------------------------------------------------------------- + +/** This helper function fills an array with the values init, init+1, init+2, + etc. For speed 8 entries are filled at a time. The array is given by its + first and "after last" entry. */ +template <class T> inline void +CoinIota(T* first, const T* last, T init) +{ + CoinIotaN(first, last-first, init); +} + +//############################################################################# + +/** This helper function deletes certain entries from an array. The array is + given by pointers to its first and "after last" entry (first two + arguments). The positions of the entries to be deleted are given in the + integer array specified by the last two arguments (again, first and "after + last" entry). */ +template <class T> inline T * +CoinDeleteEntriesFromArray(register T * arrayFirst, register T * arrayLast, + const int * firstDelPos, const int * lastDelPos) +{ + int delNum = static_cast<int>(lastDelPos - firstDelPos); + if (delNum == 0) + return arrayLast; + + if (delNum < 0) + throw CoinError("trying to delete negative number of entries", + "CoinDeleteEntriesFromArray", ""); + + int * delSortedPos = NULL; + if (! (CoinIsSorted(firstDelPos, lastDelPos) && + std::adjacent_find(firstDelPos, lastDelPos) == lastDelPos)) { + // the positions of the to be deleted is either not sorted or not unique + delSortedPos = new int[delNum]; + CoinDisjointCopy(firstDelPos, lastDelPos, delSortedPos); + std::sort(delSortedPos, delSortedPos + delNum); + delNum = static_cast<int>(std::unique(delSortedPos, + delSortedPos+delNum) - delSortedPos); + } + const int * delSorted = delSortedPos ? delSortedPos : firstDelPos; + + const int last = delNum - 1; + int size = delSorted[0]; + for (int i = 0; i < last; ++i) { + const int copyFirst = delSorted[i] + 1; + const int copyLast = delSorted[i+1]; + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + } + const int copyFirst = delSorted[last] + 1; + const int copyLast = static_cast<int>(arrayLast - arrayFirst); + CoinCopy(arrayFirst + copyFirst, arrayFirst + copyLast, + arrayFirst + size); + size += copyLast - copyFirst; + + if (delSortedPos) + delete[] delSortedPos; + + return arrayFirst + size; +} + +//############################################################################# + +#define COIN_OWN_RANDOM_32 + +#if defined COIN_OWN_RANDOM_32 +/* Thanks to Stefano Gliozzi for providing an operating system + independent random number generator. */ + +/*! \brief Return a random number between 0 and 1 + + A platform-independent linear congruential generator. For a given seed, the + generated sequence is always the same regardless of the (32-bit) + architecture. This allows to build & test in different environments, getting + in most cases the same optimization path. + + Set \p isSeed to true and supply an integer seed to set the seed + (vid. #CoinSeedRandom) + + \todo Anyone want to volunteer an upgrade for 64-bit architectures? +*/ +inline double CoinDrand48 (bool isSeed = false, unsigned int seed = 1) +{ + static unsigned int last = 123456; + if (isSeed) { + last = seed; + } else { + last = 1664525*last+1013904223; + return ((static_cast<double> (last))/4294967296.0); + } + return (0.0); +} + +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) +{ + CoinDrand48(true, iseed); +} + +#else // COIN_OWN_RANDOM_32 + +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__) + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return rand() / (double) RAND_MAX; } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand(iseed + 69822); } + +#else + +/// Return a random number between 0 and 1 +inline double CoinDrand48() { return drand48(); } +/// Set the seed for the random number generator +inline void CoinSeedRandom(int iseed) { srand48(iseed + 69822); } + +#endif + +#endif // COIN_OWN_RANDOM_32 + +//############################################################################# + +/** This function figures out whether file names should contain slashes or + backslashes as directory separator */ +inline char CoinFindDirSeparator() +{ + int size = 1000; + char* buf = 0; + while (true) { + buf = new char[size]; + if (getcwd(buf, size)) + break; + delete[] buf; + buf = 0; + size = 2*size; + } + // if first char is '/' then it's unix and the dirsep is '/'. otherwise we + // assume it's dos and the dirsep is '\' + char dirsep = buf[0] == '/' ? '/' : '\\'; + delete[] buf; + return dirsep; +} +//############################################################################# + +inline int CoinStrNCaseCmp(const char* s0, const char* s1, + const size_t len) +{ + for (size_t i = 0; i < len; ++i) { + if (s0[i] == 0) { + return s1[i] == 0 ? 0 : -1; + } + if (s1[i] == 0) { + return 1; + } + const int c0 = std::tolower(s0[i]); + const int c1 = std::tolower(s1[i]); + if (c0 < c1) + return -1; + if (c0 > c1) + return 1; + } + return 0; +} + +//############################################################################# + +/// Swap the arguments. +template <class T> inline void CoinSwap (T &x, T &y) +{ + T t = x; + x = y; + y = t; +} + +//############################################################################# + +/** This helper function copies an array to file + Returns 0 if OK, 1 if bad write. +*/ + +template <class T> inline int +CoinToFile( const T* array, CoinBigIndex size, FILE * fp) +{ + CoinBigIndex numberWritten; + if (array&&size) { + numberWritten = + static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + numberWritten = + static_cast<CoinBigIndex>(fwrite(array,sizeof(T),size_t(size),fp)); + if (numberWritten!=size) + return 1; + } else { + size = 0; + numberWritten = + static_cast<CoinBigIndex>(fwrite(&size,sizeof(int),1,fp)); + if (numberWritten!=1) + return 1; + } + return 0; +} + +//############################################################################# + +/** This helper function copies an array from file and creates with new. + Passed in array is ignored i.e. not deleted. + But if NULL and size does not match and newSize 0 then leaves as NULL and 0 + Returns 0 if OK, 1 if bad read, 2 if size did not match. +*/ + +template <class T> inline int +CoinFromFile( T* &array, CoinBigIndex size, FILE * fp, CoinBigIndex & newSize) +{ + CoinBigIndex numberRead; + numberRead = + static_cast<CoinBigIndex>(fread(&newSize,sizeof(int),1,fp)); + if (numberRead!=1) + return 1; + int returnCode=0; + if (size!=newSize&&(newSize||array)) + returnCode=2; + if (newSize) { + array = new T [newSize]; + numberRead = + static_cast<CoinBigIndex>(fread(array,sizeof(T),newSize,fp)); + if (numberRead!=newSize) + returnCode=1; + } else { + array = NULL; + } + return returnCode; +} + +//############################################################################# + +/// Cube Root +#if 0 +inline double CoinCbrt(double x) +{ +#if defined(_MSC_VER) + return pow(x,(1./3.)); +#else + return cbrt(x); +#endif +} +#endif + +//----------------------------------------------------------------------------- + +/// This helper returns "sizeof" as an int +#define CoinSizeofAsInt(type) (static_cast<int>(sizeof(type))) +/// This helper returns "strlen" as an int +inline int +CoinStrlenAsInt(const char * string) +{ + return static_cast<int>(strlen(string)); +} + +/** Class for thread specific random numbers +*/ +#if defined COIN_OWN_RANDOM_32 +class CoinThreadRandom { +public: + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CoinThreadRandom() + { seed_=12345678;} + /** Constructor wih seed. */ + CoinThreadRandom(int seed) + { + seed_ = seed; + } + /** Destructor */ + ~CoinThreadRandom() {} + // Copy + CoinThreadRandom(const CoinThreadRandom & rhs) + { seed_ = rhs.seed_;} + // Assignment + CoinThreadRandom& operator=(const CoinThreadRandom & rhs) + { + if (this != &rhs) { + seed_ = rhs.seed_; + } + return *this; + } + + //@} + + /**@name Sets/gets */ + + //@{ + /** Set seed. */ + inline void setSeed(int seed) + { + seed_ = seed; + } + /** Get seed. */ + inline unsigned int getSeed() const + { + return seed_; + } + /// return a random number + inline double randomDouble() const + { + double retVal; + seed_ = 1664525*(seed_)+1013904223; + retVal = ((static_cast<double> (seed_))/4294967296.0); + return retVal; + } + /// make more random (i.e. for startup) + inline void randomize(int n=0) + { + if (!n) + n=seed_ & 255; + for (int i=0;i<n;i++) + randomDouble(); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Current seed + mutable unsigned int seed_; + //@} +}; +#else +class CoinThreadRandom { +public: + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + CoinThreadRandom() + { seed_[0]=50000;seed_[1]=40000;seed_[2]=30000;} + /** Constructor wih seed. */ + CoinThreadRandom(const unsigned short seed[3]) + { memcpy(seed_,seed,3*sizeof(unsigned short));} + /** Constructor wih seed. */ + CoinThreadRandom(int seed) + { + union { int i[2]; unsigned short int s[4];} put; + put.i[0]=seed; + put.i[1]=seed; + memcpy(seed_,put.s,3*sizeof(unsigned short)); + } + /** Destructor */ + ~CoinThreadRandom() {} + // Copy + CoinThreadRandom(const CoinThreadRandom & rhs) + { memcpy(seed_,rhs.seed_,3*sizeof(unsigned short));} + // Assignment + CoinThreadRandom& operator=(const CoinThreadRandom & rhs) + { + if (this != &rhs) { + memcpy(seed_,rhs.seed_,3*sizeof(unsigned short)); + } + return *this; + } + + //@} + + /**@name Sets/gets */ + + //@{ + /** Set seed. */ + inline void setSeed(const unsigned short seed[3]) + { memcpy(seed_,seed,3*sizeof(unsigned short));} + /** Set seed. */ + inline void setSeed(int seed) + { + union { int i[2]; unsigned short int s[4];} put; + put.i[0]=seed; + put.i[1]=seed; + memcpy(seed_,put.s,3*sizeof(unsigned short)); + } + /// return a random number + inline double randomDouble() const + { + double retVal; +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN32__) + retVal=rand(); + retVal=retVal/(double) RAND_MAX; +#else + retVal = erand48(seed_); +#endif + return retVal; + } + /// make more random (i.e. for startup) + inline void randomize(int n=0) + { + if (!n) { + n=seed_[0]+seed_[1]+seed_[2]; + n &= 255; + } + for (int i=0;i<n;i++) + randomDouble(); + } + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Current seed + mutable unsigned short seed_[3]; + //@} +}; +#endif +#ifndef COIN_DETAIL +#define COIN_DETAIL_PRINT(s) {} +#else +#define COIN_DETAIL_PRINT(s) s +#endif +#endif diff --git a/thirdparty/linux/include/coin1/CoinIndexedVector.hpp b/thirdparty/linux/include/coin1/CoinIndexedVector.hpp new file mode 100644 index 0000000..9c386c5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinIndexedVector.hpp @@ -0,0 +1,1164 @@ +/* $Id: CoinIndexedVector.hpp 1767 2015-01-05 12:36:13Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinIndexedVector_H +#define CoinIndexedVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <map> +#include "CoinFinite.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#endif +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include <cassert> + +#ifndef COIN_FLOAT +#define COIN_INDEXED_TINY_ELEMENT 1.0e-50 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-100 +#else +#define COIN_INDEXED_TINY_ELEMENT 1.0e-35 +#define COIN_INDEXED_REALLY_TINY_ELEMENT 1.0e-39 +#endif + +/** Indexed Vector + +This stores values unpacked but apart from that is a bit like CoinPackedVector. +It is designed to be lightweight in normal use. + +It now has a "packed" mode when it is even more like CoinPackedVector + +Indices array has capacity_ extra chars which are zeroed and can +be used for any purpose - but must be re-zeroed + +Stores vector of indices and associated element values. +Supports sorting of indices. + +Does not support negative indices. + +Does NOT support testing for duplicates + +*** getElements is no longer supported + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its valuex1 + CoinIndexedVector r(ne,inx,el); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.getIndices ()[0]== 0 ); + assert( r.getIndices ()[1]== 1 ); + assert( r.getIndices ()[2]== 4 ); + assert( r.getIndices ()[3]== 2 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinIndexedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add indexed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinIndexedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinIndexedVector { + friend void CoinIndexedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getIndices() const { return indices_; } + /// Get element values + // ** No longer supported virtual const double * getElements() const ; + /// Get indices of elements + inline int * getIndices() { return indices_; } + /** Get the vector as a dense vector. This is normal storage method. + The user should not not delete [] this. + */ + inline double * denseVector() const { return elements_; } + /// For very temporary use when user needs to borrow a dense vector + inline void setDenseVector(double * array) + { elements_ = array;} + /// For very temporary use when user needs to borrow an index vector + inline void setIndexVector(int * array) + { indices_ = array;} + /** Access the i'th element of the full storage vector. + */ + double & operator[](int i) const; + + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Set the size + inline void setNumElements(int value) { nElements_ = value; + if (!nElements_) packedMode_=false;} + /// Reset the vector (as if were just created an empty vector). This leaves arrays! + void clear(); + /// Reset the vector (as if were just created an empty vector) + void empty(); + /** Assignment operator. */ + CoinIndexedVector & operator=(const CoinIndexedVector &); +#ifndef CLP_NO_VECTOR + /** Assignment operator from a CoinPackedVectorBase. <br> + <strong>NOTE</strong>: This assumes no duplicates */ + CoinIndexedVector & operator=(const CoinPackedVectorBase & rhs); +#endif + /** Copy the contents of one vector into another. If multiplier is 1 + It is the equivalent of = but if vectors are same size does + not re-allocate memory just clears and copies */ + void copy(const CoinIndexedVector & rhs, double multiplier=1.0); + + /** Borrow ownership of the arguments to this vector. + Size is the length of the unpacked elements vector. */ + void borrowVector(int size, int numberIndices, int* inds, double* elems); + + /** Return ownership of the arguments to this vector. + State after is empty . + */ + void returnVector(); + + /** Set vector numberIndices, indices, and elements. + NumberIndices is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. Assumed to have no duplicates */ + void setVector(int numberIndices, const int * inds, const double * elems); + + /** Set vector size, indices, and elements. + Size is the length of the unpacked elements vector. + The indices and elements vectors are copied into this class instance's + member data. We do not check for duplicate indices */ + void setVector(int size, int numberIndices, const int * inds, const double * elems); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems); + + /** Set an existing element in the indexed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Insert a nonzero element into the vector + inline void quickInsert(int index, double element) + { + assert (!elements_[index]); + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny */ + void add(int index, double element); + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This version does no checking */ + inline void quickAdd(int index, double element) + { + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = 1.0e-100; + } + } else if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Insert or if exists add an element into the vector + Any resulting zero elements will be made tiny. + This knows element is nonzero + This version does no checking */ + inline void quickAddNonZero(int index, double element) + { + assert (element); + if (elements_[index]) { + element += elements_[index]; + if ((element > 0 ? element : -element) >= COIN_INDEXED_TINY_ELEMENT) { + elements_[index] = element; + } else { + elements_[index] = COIN_DBL_MIN; + } + } else { + indices_[nElements_++] = index; + assert (nElements_<=capacity_); + elements_[index] = element; + } + } + /** Makes nonzero tiny. + This version does no checking */ + inline void zero(int index) + { + if (elements_[index]) + elements_[index] = COIN_DBL_MIN; + } + /** set all small values to zero and return number remaining + - < tolerance => 0.0 */ + int clean(double tolerance); + /// Same but packs down + int cleanAndPack(double tolerance); + /// Same but packs down and is safe (i.e. if order is odd) + int cleanAndPackSafe(double tolerance); + /// Mark as packed + inline void setPacked() + { packedMode_ = true;} +#ifndef NDEBUG + /// For debug check vector is clear i.e. no elements + void checkClear(); + /// For debug check vector is clean i.e. elements match indices + void checkClean(); +#else + inline void checkClear() {}; + inline void checkClean() {}; +#endif + /// Scan dense region and set up indices (returns number found) + int scan(); + /** Scan dense region from start to < end and set up indices + returns number found + */ + int scan(int start, int end); + /** Scan dense region and set up indices (returns number found). + Only ones >= tolerance */ + int scan(double tolerance); + /** Scan dense region from start to < end and set up indices + returns number found. Only >= tolerance + */ + int scan(int start, int end, double tolerance); + /// These are same but pack down + int scanAndPack(); + int scanAndPack(int start, int end); + int scanAndPack(double tolerance); + int scanAndPack(int start, int end, double tolerance); + /// Create packed array + void createPacked(int number, const int * indices, + const double * elements); + /// Create unpacked array + void createUnpacked(int number, const int * indices, + const double * elements); + /// Create unpacked singleton + void createOneUnpackedElement(int index, double element); + /// This is mainly for testing - goes from packed to indexed + void expand(); +#ifndef CLP_NO_VECTOR + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); +#endif + /// Append a CoinIndexedVector to the end (with extra space) + void append(const CoinIndexedVector & caboose); + /// Append a CoinIndexedVector to the end and modify indices + void append(CoinIndexedVector & other,int adjustIndex,bool zapElements=false); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /// Throw away all entries in rows >= newSize + void truncate(int newSize); + /// Print out + void print() const; + //@} + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(double value); + /// subtract <code>value</code> from every entry + void operator-=(double value); + /// multiply every entry by <code>value</code> + void operator*=(double value); + /// divide every entry by <code>value</code> (** 0 vanishes) + void operator/=(double value); + //@} + + /**@name Comparison operators on two indexed vectors */ + //@{ +#ifndef CLP_NO_VECTOR + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; +#endif + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinIndexedVector & rhs) const; + /// Not equal + bool operator!=(const CoinIndexedVector & rhs) const; + /// Equal with a tolerance (returns -1 or position of inequality). + int isApproximatelyEqual(const CoinIndexedVector & rhs, double tolerance=1.0e-8) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + //@} + + + /**@name Sorting */ + //@{ + /** Sort the indexed storage vector (increasing indices). */ + void sort() + { std::sort(indices_,indices_+nElements_); } + + void sortIncrIndex() + { std::sort(indices_,indices_+nElements_); } + + void sortDecrIndex(); + + void sortIncrElement(); + + void sortDecrElement(); + void sortPacked(); + + //@} + + //############################################################################# + + /**@name Arithmetic operators on packed vectors. + + <strong>NOTE</strong>: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.<br> + <strong>NOTE 2</strong>: Because these methods return an object (they can't + return a reference, though they could return a pointer...) they are + <em>very</em> inefficient... + */ +//@{ +/// Return the sum of two indexed vectors +CoinIndexedVector operator+( + const CoinIndexedVector& op2); + +/// Return the difference of two indexed vectors +CoinIndexedVector operator-( + const CoinIndexedVector& op2); + +/// Return the element-wise product of two indexed vectors +CoinIndexedVector operator*( + const CoinIndexedVector& op2); + +/// Return the element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +CoinIndexedVector operator/( + const CoinIndexedVector& op2); +/// The sum of two indexed vectors +void operator+=(const CoinIndexedVector& op2); + +/// The difference of two indexed vectors +void operator-=( const CoinIndexedVector& op2); + +/// The element-wise product of two indexed vectors +void operator*=(const CoinIndexedVector& op2); + +/// The element-wise ratio of two indexed vectors (0.0/0.0 => 0.0) (0 vanishes) +void operator/=(const CoinIndexedVector& op2); +//@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the indexed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + inline int capacity() const { return capacity_; } + inline void setCapacity(int value) + { capacity_ = value; } + /// Sets packed mode + inline void setPackedMode(bool yesNo) + { packedMode_=yesNo;} + /// Gets packed mode + inline bool packedMode() const + { return packedMode_;} + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinIndexedVector(); + /** Alternate Constructors - set elements to vector of doubles */ + CoinIndexedVector(int size, const int * inds, const double * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinIndexedVector(int size, const int * inds, double element); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinIndexedVector(int size, const double * elements); + /** Alternate Constructors - just size */ + CoinIndexedVector(int size); + /** Copy constructor. */ + CoinIndexedVector(const CoinIndexedVector &); + /** Copy constructor.2 */ + CoinIndexedVector(const CoinIndexedVector *); +#ifndef CLP_NO_VECTOR + /** Copy constructor <em>from a PackedVectorBase</em>. */ + CoinIndexedVector(const CoinPackedVectorBase & rhs); +#endif + /** Destructor */ + ~CoinIndexedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfSetVector(int size, + const int * inds, const double * elems); + void gutsOfSetVector(int size, int numberIndices, + const int * inds, const double * elems); + void gutsOfSetPackedVector(int size, int numberIndices, + const int * inds, const double * elems); + /// + void gutsOfSetConstant(int size, + const int * inds, double value); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and packed elements vectors + int nElements_; + /// Amount of memory allocated for indices_, and elements_. + int capacity_; + /// Offset to get where new allocated array + int offset_; + /// If true then is operating in packed mode + bool packedMode_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinIndexedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinIndexedVectorUnitTest(); +/** Pointer with length in bytes + + This has a pointer to an array and the number of bytes in array. + If number of bytes==-1 then + CoinConditionalNew deletes existing pointer and returns new pointer + of correct size (and number bytes still -1). + CoinConditionalDelete deletes existing pointer and NULLs it. + So behavior is as normal (apart from New deleting pointer which will have + no effect with good coding practices. + If number of bytes >=0 then + CoinConditionalNew just returns existing pointer if array big enough + otherwise deletes existing pointer, allocates array with spare 1%+64 bytes + and updates number of bytes + CoinConditionalDelete sets number of bytes = -size-2 and then array + returns NULL +*/ +class CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_; } + /// Get the size + inline int rawSize() const + { return size_; } + /// See if persistence already on + inline bool switchedOn() const + { return size_!=-1; } + /// Get the capacity (just read it) + inline int capacity() const + { return (size_>-2) ? size_ : (-size_)-2; } + /// Set the capacity to >=0 if <=-2 + inline void setCapacity() + { if (size_<=-2) size_ = (-size_)-2; } + /// Get Array + inline const char * array() const + { return (size_>-2) ? array_ : NULL; } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value; } + /// Set the size to -1 + inline void switchOff() + { size_ = -1; } + /// Set the size to -2 and alignment + inline void switchOn(int alignment=3) + { size_ = -2; alignment_=alignment;} + /// Does what is needed to set persistence + void setPersistence(int flag,int currentLength); + /// Zero out array + void clear(); + /// Swaps memory between two members + void swap(CoinArrayWithLength & other); + /// Extend a persistent array keeping data (size in bytes) + void extend(int newSize); + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + char * conditionalNew(long sizeWanted); + /// Conditionally deletes + void conditionalDelete(); + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArrayWithLength() + : array_(NULL),size_(-1),offset_(0),alignment_(0) + { } + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArrayWithLength(int size) + : size_(-1),offset_(0),alignment_(0) + { array_=new char [size];} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + mode>0 size_ set to size and zeroed + if size<=0 just does alignment + If abs(mode) >2 then align on that as power of 2 + */ + CoinArrayWithLength(int size, int mode); + /** Copy constructor. */ + CoinArrayWithLength(const CoinArrayWithLength & rhs); + /** Copy constructor.2 */ + CoinArrayWithLength(const CoinArrayWithLength * rhs); + /** Assignment operator. */ + CoinArrayWithLength& operator=(const CoinArrayWithLength & rhs); + /** Assignment with length (if -1 use internal length) */ + void copy(const CoinArrayWithLength & rhs, int numberBytes=-1); + /** Assignment with length - does not copy */ + void allocate(const CoinArrayWithLength & rhs, int numberBytes); + /** Destructor */ + ~CoinArrayWithLength (); + /// Get array with alignment + void getArray(int size); + /// Really get rid of array with alignment + void reallyFreeArray(); + /// Get enough space (if more needed then do at least needed) + void getCapacity(int numberBytes,int numberIfNeeded=-1); + //@} + +protected: + /**@name Private member data */ + //@{ + /// Array + char * array_; + /// Size of array in bytes + CoinBigIndex size_; + /// Offset of array + int offset_; + /// Alignment wanted (power of 2) + int alignment_; + //@} +}; +/// double * version + +class CoinDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(double); } + /// Get Array + inline double * array() const + { return reinterpret_cast<double *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline double * conditionalNew(int sizeWanted) + { return reinterpret_cast<double *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(double),mode) {} + /** Copy constructor. */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinDoubleArrayWithLength(const CoinDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinDoubleArrayWithLength& operator=(const CoinDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationDouble * version + +class CoinFactorizationDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinFactorizationDouble); } + /// Get Array + inline CoinFactorizationDouble * array() const + { return reinterpret_cast<CoinFactorizationDouble *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinFactorizationDouble); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinFactorizationDouble * conditionalNew(int sizeWanted) + { return reinterpret_cast<CoinFactorizationDouble *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinFactorizationDouble)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinFactorizationDouble)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinFactorizationDouble),mode) {} + /** Copy constructor. */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationDoubleArrayWithLength(const CoinFactorizationDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationDoubleArrayWithLength& operator=(const CoinFactorizationDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinFactorizationLongDouble * version + +class CoinFactorizationLongDoubleArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(long double); } + /// Get Array + inline long double * array() const + { return reinterpret_cast<long double *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(long double); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline long double * conditionalNew(int sizeWanted) + { return reinterpret_cast<long double *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(long double)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinFactorizationLongDoubleArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinFactorizationLongDoubleArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(long double)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinFactorizationLongDoubleArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(long double),mode) {} + /** Copy constructor. */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinFactorizationLongDoubleArrayWithLength(const CoinFactorizationLongDoubleArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinFactorizationLongDoubleArrayWithLength& operator=(const CoinFactorizationLongDoubleArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// int * version + +class CoinIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(int); } + /// Get Array + inline int * array() const + { return reinterpret_cast<int *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline int * conditionalNew(int sizeWanted) + { return reinterpret_cast<int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(int),mode) {} + /** Copy constructor. */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinIntArrayWithLength(const CoinIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinIntArrayWithLength& operator=(const CoinIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// CoinBigIndex * version + +class CoinBigIndexArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(CoinBigIndex); } + /// Get Array + inline CoinBigIndex * array() const + { return reinterpret_cast<CoinBigIndex *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(CoinBigIndex); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline CoinBigIndex * conditionalNew(int sizeWanted) + { return reinterpret_cast<CoinBigIndex *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(CoinBigIndex)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinBigIndexArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinBigIndexArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(CoinBigIndex)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinBigIndexArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(CoinBigIndex),mode) {} + /** Copy constructor. */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinBigIndexArrayWithLength(const CoinBigIndexArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinBigIndexArrayWithLength& operator=(const CoinBigIndexArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// unsigned int * version + +class CoinUnsignedIntArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(unsigned int); } + /// Get Array + inline unsigned int * array() const + { return reinterpret_cast<unsigned int *> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(unsigned int); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline unsigned int * conditionalNew(int sizeWanted) + { return reinterpret_cast<unsigned int *> (CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> (( sizeWanted)*CoinSizeofAsInt(unsigned int)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinUnsignedIntArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinUnsignedIntArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(unsigned int)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinUnsignedIntArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(unsigned int),mode) {} + /** Copy constructor. */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinUnsignedIntArrayWithLength(const CoinUnsignedIntArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinUnsignedIntArrayWithLength& operator=(const CoinUnsignedIntArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// void * version + +class CoinVoidStarArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/CoinSizeofAsInt(void *); } + /// Get Array + inline void ** array() const + { return reinterpret_cast<void **> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*CoinSizeofAsInt(void *); } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline void ** conditionalNew(int sizeWanted) + { return reinterpret_cast<void **> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> ((sizeWanted)*CoinSizeofAsInt(void *)) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinVoidStarArrayWithLength() + { array_=NULL; size_=-1;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinVoidStarArrayWithLength(int size) + { array_=new char [size*CoinSizeofAsInt(void *)]; size_=-1;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinVoidStarArrayWithLength(int size, int mode) + : CoinArrayWithLength(size*CoinSizeofAsInt(void *),mode) {} + /** Copy constructor. */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinVoidStarArrayWithLength(const CoinVoidStarArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinVoidStarArrayWithLength& operator=(const CoinVoidStarArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} +}; +/// arbitrary version + +class CoinArbitraryArrayWithLength : public CoinArrayWithLength { + +public: + /**@name Get methods. */ + //@{ + /// Get the size + inline int getSize() const + { return size_/lengthInBytes_; } + /// Get Array + inline void ** array() const + { return reinterpret_cast<void **> ((size_>-2) ? array_ : NULL); } + //@} + + /**@name Set methods */ + //@{ + /// Set the size + inline void setSize(int value) + { size_ = value*lengthInBytes_; } + //@} + + /**@name Condition methods */ + //@{ + /// Conditionally gets new array + inline char * conditionalNew(int length, int sizeWanted) + { lengthInBytes_=length;return reinterpret_cast<char *> ( CoinArrayWithLength::conditionalNew(sizeWanted>=0 ? static_cast<long> + ((sizeWanted)*lengthInBytes_) : -1)); } + //@} + + /**@name Constructors and destructors */ + //@{ + /** Default constructor - NULL*/ + inline CoinArbitraryArrayWithLength(int length=1) + { array_=NULL; size_=-1;lengthInBytes_=length;} + /** Alternate Constructor - length in bytes - size_ -1 */ + inline CoinArbitraryArrayWithLength(int length, int size) + { array_=new char [size*length]; size_=-1; lengthInBytes_=length;} + /** Alternate Constructor - length in bytes + mode - 0 size_ set to size + 1 size_ set to size and zeroed + */ + inline CoinArbitraryArrayWithLength(int length, int size, int mode) + : CoinArrayWithLength(size*length,mode) {lengthInBytes_=length;} + /** Copy constructor. */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength & rhs) + : CoinArrayWithLength(rhs) {} + /** Copy constructor.2 */ + inline CoinArbitraryArrayWithLength(const CoinArbitraryArrayWithLength * rhs) + : CoinArrayWithLength(rhs) {} + /** Assignment operator. */ + inline CoinArbitraryArrayWithLength& operator=(const CoinArbitraryArrayWithLength & rhs) + { CoinArrayWithLength::operator=(rhs); return *this;} + //@} + +protected: + /**@name Private member data */ + //@{ + /// Length in bytes + int lengthInBytes_; + //@} +}; +class CoinPartitionedVector : public CoinIndexedVector { + +public: +#ifndef COIN_PARTITIONS +#define COIN_PARTITIONS 8 +#endif + /**@name Get methods. */ + //@{ + /// Get the size of a partition + inline int getNumElements(int partition) const { assert (partition<COIN_PARTITIONS); + return numberElementsPartition_[partition]; } + /// Get number of partitions + inline int getNumPartitions() const + { return numberPartitions_; } + /// Get the size + inline int getNumElements() const { return nElements_; } + /// Get starts + inline int startPartition(int partition) const { assert (partition<=COIN_PARTITIONS); + return startPartition_[partition]; } + /// Get starts + inline const int * startPartitions() const + { return startPartition_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Set the size of a partition + inline void setNumElementsPartition(int partition, int value) { assert (partition<COIN_PARTITIONS); + if (numberPartitions_) numberElementsPartition_[partition]=value; } + /// Set the size of a partition (just for a tiny while) + inline void setTempNumElementsPartition(int partition, int value) { assert (partition<COIN_PARTITIONS); + numberElementsPartition_[partition]=value; } + /// Add up number of elements in partitions + void computeNumberElements(); + /// Add up number of elements in partitions and pack and get rid of partitions + void compact(); + /** Reserve space. + */ + void reserve(int n); + /// Setup partitions (needs end as well) + void setPartitions(int number,const int * starts); + /// Reset the vector (as if were just created an empty vector). Gets rid of partitions + void clearAndReset(); + /// Reset the vector (as if were just created an empty vector). Keeps partitions + void clearAndKeep(); + /// Clear a partition. + void clearPartition(int partition); +#ifndef NDEBUG + /// For debug check vector is clear i.e. no elements + void checkClear(); + /// For debug check vector is clean i.e. elements match indices + void checkClean(); +#else + inline void checkClear() {}; + inline void checkClean() {}; +#endif + /// Scan dense region and set up indices (returns number found) + int scan(int partition, double tolerance=0.0); + /** Scan dense region from start to < end and set up indices + returns number found + */ + /// Print out + void print() const; + //@} + + /**@name Sorting */ + //@{ + /** Sort the indexed storage vector (increasing indices). */ + void sort(); + //@} + + /**@name Constructors and destructors (not all wriiten) */ + //@{ + /** Default constructor */ + CoinPartitionedVector(); + /** Alternate Constructors - set elements to vector of doubles */ + CoinPartitionedVector(int size, const int * inds, const double * elems); + /** Alternate Constructors - set elements to same scalar value */ + CoinPartitionedVector(int size, const int * inds, double element); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinPartitionedVector(int size, const double * elements); + /** Alternate Constructors - just size */ + CoinPartitionedVector(int size); + /** Copy constructor. */ + CoinPartitionedVector(const CoinPartitionedVector &); + /** Copy constructor.2 */ + CoinPartitionedVector(const CoinPartitionedVector *); + /** Assignment operator. */ + CoinPartitionedVector & operator=(const CoinPartitionedVector &); + /** Destructor */ + ~CoinPartitionedVector (); + //@} +protected: + /**@name Private member data */ + //@{ + /// Starts + int startPartition_[COIN_PARTITIONS+1]; + /// Size of indices in a partition + int numberElementsPartition_[COIN_PARTITIONS]; + /// Number of partitions (0 means off) + int numberPartitions_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinLpIO.hpp b/thirdparty/linux/include/coin1/CoinLpIO.hpp new file mode 100644 index 0000000..43c0e20 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinLpIO.hpp @@ -0,0 +1,805 @@ +/* $Id: CoinLpIO.hpp 1749 2014-10-24 20:00:14Z tkr $ */ +// Last edit: 11/5/08 +// +// Name: CoinLpIO.hpp; Support for Lp files +// Author: Francois Margot +// Tepper School of Business +// Carnegie Mellon University, Pittsburgh, PA 15213 +// email: fmargot@andrew.cmu.edu +// Date: 12/28/03 +//----------------------------------------------------------------------------- +// Copyright (C) 2003, Francois Margot, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinLpIO_H +#define CoinLpIO_H + +#include <cstdio> + +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +class CoinSet; + +const int MAX_OBJECTIVES = 2; + +typedef int COINColumnIndex; + + /** Class to read and write Lp files + + Lp file format: + +/ this is a comment <BR> +\ this too <BR> + Min<BR> + obj: x0 + x1 + 3 x2 - 4.5 xyr + 1 <BR> + s.t. <BR> + cons1: x0 - x2 - 2.3 x4 <= 4.2 / this is another comment <BR> + c2: x1 + x2 >= 1 <BR> + cc: x1 + x2 + xyr = 2 <BR> + Bounds <BR> + 0 <= x1 <= 3 <BR> + 1 >= x2 <BR> + x3 = 1 <BR> + -2 <= x4 <= Inf <BR> + xyr free <BR> + Integers <BR> + x0 <BR> + Generals <BR> + x1 xyr <BR> + Binaries <BR> + x2 <BR> + End + +Notes: <UL> + <LI> Keywords are: Min, Max, Minimize, Maximize, s.t., Subject To, + Bounds, Integers, Generals, Binaries, End, Free, Inf. + <LI> Keywords are not case sensitive and may be in plural or singular form. + They should not be used as objective, row or column names. + <LI> Bounds, Integers, Generals, Binaries sections are optional. + <LI> Generals and Integers are synonymous. + <LI> Bounds section (if any) must come before Integers, Generals, and + Binaries sections. + <LI> Row names must be followed by ':' without blank space. + Row names are optional. If row names are present, + they must be distinct (if the k-th constraint has no given name, its name + is set automatically to "consk" for k=0,...,). + For valid row names, see the method is_invalid_name(). + <LI> Column names must be followed by a blank space. They must be distinct. + For valid column names, see the method is_invalid_name(). + <LI> Multiple objectives may be specified, but when there are multiple + objectives, they must have names (to indicate where each one starts). + <LI> The objective function names must be followed by ':' without blank space. + If there is a single objective, the objective function name is optional. + If no name is given, the name is set to "obj" by default. + For valid objective function names, see the method is_invalid_name(). + <LI> Ranged constraints are written as two constraints. + If a name is given for a ranged constraint, the upper bound constraint + has that name and the lower bound constraint has that name with "_low" + as suffix. This should be kept in mind when assigning names to ranged + constraint, as the resulting name must be distinct from all the other + names and be considered valid by the method is_invalid_name(). + <LI> At most one term related to any single variable may appear in the + objective function; if more than one term are present, only the last + one is taken into account. + At most one constant term may appear in the objective function; + if present, it must appear last. + <LI> Default bounds are 0 for lower bound and +infinity for upper bound. + <LI> Free variables get default lower bound -infinity and + default upper bound +infinity. Writing "x0 Free" in an + LP file means "set lower bound on x0 to -infinity". + <LI> If more than one upper (resp. lower) bound on a variable appears in + the Bounds section, the last one is the one taken into + account. The bounds for a binary variable are set to 0/1 only if this + bound is stronger than the bound obtained from the Bounds section. + <LI> Numbers larger than DBL_MAX (or larger than 1e+400) in the input file + might crash the code. + <LI> A comment must start with '\' or '/'. That symbol must either be + the first character of a line or be preceded by a blank space. The + comment ends at the end of the + line. Comments are skipped while reading an Lp file and they may be + inserted anywhere. +</UL> +*/ +class CoinLpIO { + friend void CoinLpIOUnitTest(const std::string & lpDir); +public: + + /**@name Constructor and Destructor */ + //@{ + /// Default Constructor + CoinLpIO(); + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment + void gutsOfCopy(const CoinLpIO &); + + /// assignment operator + CoinLpIO & operator = (const CoinLpIO& rhs) ; + + /// Copy constructor + CoinLpIO (const CoinLpIO &); + + /// Destructor + ~CoinLpIO(); + + /** Free the vector previous_names_[section] and set + card_previous_names_[section] to 0. + section = 0 for row names, + section = 1 for column names. + */ + void freePreviousNames(const int section); + + /// Free all memory (except memory related to hash tables and objName_). + void freeAll(); + //@} + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + + /**@name Queries */ + //@{ + + /// Get the problem name + const char * getProblemName() const; + + /// Set problem name + void setProblemName(const char *name); + + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + /** Get pointer to array[getNumRows()] of constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + Put another way, only ranged constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const int getNumObjectives() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients for objective j + const double * getObjCoefficients(int j) const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Get objective function name + const char * getObjName() const; + + /// Get objective function name for objective j + const char * getObjName(int j) const; + + /// Get pointer to array[*card_prev] of previous row names. + /// The value of *card_prev might be different than getNumRows()+1 if + /// non distinct + /// row names were present or if no previous names were saved or if + /// the object was holding a different problem before. + void getPreviousRowNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[*card_prev] of previous column names. + /// The value of *card_prev might be different than getNumCols() if non + /// distinct column names were present of if no previous names were saved, + /// or if the object was holding a different problem before. + void getPreviousColNames(char const * const * prev, + int *card_prev) const; + + /// Get pointer to array[getNumRows()+1] of row names, including + /// objective function name as last entry. + char const * const * getRowNames() const; + + /// Get pointer to array[getNumCols()] of column names + char const * const *getColNames() const; + + /// Return the row name for the specified index. + /// Return the objective function name if index = getNumRows(). + /// Return 0 if the index is out of range or if row names are not defined. + const char * rowName(int index) const; + + /// Return the column name for the specified index. + /// Return 0 if the index is out of range or if column names are not + /// defined. + const char * columnName(int index) const; + + /// Return the index for the specified row name. + /// Return getNumRows() for the objective function name. + /// Return -1 if the name is not found. + int rowIndex(const char * name) const; + + /// Return the index for the specified column name. + /// Return -1 if the name is not found. + int columnIndex(const char * name) const; + + ///Returns the (constant) objective offset + double objectiveOffset() const; + + ///Returns the (constant) objective offset for objective j + double objectiveOffset(int j) const; + + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_[0] = value;} + + /// Set objective offset + inline void setObjectiveOffset(double value, int j) + { objectiveOffset_[j] = value;} + + /// Return true if a column is an integer (binary or general + /// integer) variable + bool isInteger(int columnNumber) const; + + /// Get characteristic vector of integer variables + const char * integerColumns() const; + //@} + + /**@name Parameters */ + //@{ + /// Get infinity + double getInfinity() const; + + /// Set infinity. Any number larger is considered infinity. + /// Default: DBL_MAX + void setInfinity(const double); + + /// Get epsilon + double getEpsilon() const; + + /// Set epsilon. + /// Default: 1e-5. + void setEpsilon(const double); + + /// Get numberAcross, the number of monomials to be printed per line + int getNumberAcross() const; + + /// Set numberAcross. + /// Default: 10. + void setNumberAcross(const int); + + /// Get decimals, the number of digits to write after the decimal point + int getDecimals() const; + + /// Set decimals. + /// Default: 5 + void setDecimals(const int); + //@} + + /**@name Public methods */ + //@{ + /** Set the data of the object. + Set it from the coefficient matrix m, the lower bounds + collb, the upper bounds colub, objective function obj_coeff, + integrality vector integrality, lower/upper bounds on the constraints. + The sense of optimization of the objective function is assumed to be + a minimization. + Numbers larger than DBL_MAX (or larger than 1e+400) + might crash the code. There are two version. The second one is for + setting multiple objectives. + */ + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff, + const char* integrality, + const double* rowlb, const double* rowub); + + void setLpDataWithoutRowAndColNames( + const CoinPackedMatrix& m, + const double* collb, const double* colub, + const double* obj_coeff[MAX_OBJECTIVES], + int num_objectives, + const char* integrality, + const double* rowlb, const double* rowub); + + /** Return 0 if buff is a valid name for a row, a column or objective + function, return a positive number otherwise. + If parameter ranged = true, the name is intended for a ranged + constraint. <BR> + Return 1 if the name has more than 100 characters (96 characters + for a ranged constraint name, as "_low" will be added to the name).<BR> + Return 2 if the name starts with a number.<BR> + Return 3 if the name is not built with + the letters a to z, A to Z, the numbers 0 to 9 or the characters + " ! # $ % & ( ) . ; ? @ _ ' ` { } ~ <BR> + Return 4 if the name is a keyword.<BR> + Return 5 if the name is empty or NULL. */ + int is_invalid_name(const char *buff, const bool ranged) const; + + /** Return 0 if each of the card_vnames entries of vnames is a valid name, + return a positive number otherwise. The return value, if not 0, is the + return value of is_invalid_name() for the last invalid name + in vnames. If check_ranged = true, the names are row names and + names for ranged constaints must be checked for additional restrictions + since "_low" will be added to the name if an Lp file is written. + When check_ranged = true, card_vnames must have getNumRows()+1 entries, + with entry vnames[getNumRows()] being the + name of the objective function. + For a description of valid names and return values, see the method + is_invalid_name(). + + This method must not be called with check_ranged = true before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + */ + int are_invalid_names(char const * const *vnames, + const int card_vnames, + const bool check_ranged) const; + + /// Set objective function name to the default "obj" and row + /// names to the default "cons0", "cons1", ... + void setDefaultRowNames(); + + /// Set column names to the default "x0", "x1", ... + void setDefaultColNames(); + + /** Set the row and column names. + The array rownames must either be NULL or have exactly getNumRows()+1 + distinct entries, + each of them being a valid name (see is_invalid_name()) and the + last entry being the intended name for the objective function. + If rownames is NULL, existing row names and objective function + name are not changed. + If rownames is deemed invalid, default row names and objective function + name are used (see setDefaultRowNames()). The memory location of + array rownames (or its entries) should not be related + to the memory location of the array (or entries) obtained from + getRowNames() or getPreviousRowNames(), as the call to + setLpDataRowAndColNames() modifies the corresponding arrays. + Unpredictable results + are obtained if this requirement is ignored. + + Similar remarks apply to the array colnames, which must either be + NULL or have exactly getNumCols() entries. + */ + void setLpDataRowAndColNames(char const * const * const rownames, + char const * const * const colnames); + + /** Write the data in Lp format in the file with name filename. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(const char *filename, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /** Write the data in Lp format in the file pointed to by the paramater fp. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + Write objective function name and row names if useRowNames = true. + + Ranged constraints are written as two constraints. + If row names are used, the upper bound constraint has the + name of the original ranged constraint and the + lower bound constraint has for name the original name with + "_low" as suffix. If doing so creates two identical row names, + default row names are used (see setDefaultRowNames()). + */ + int writeLp(FILE *fp, + const double epsilon, + const int numberAcross, + const int decimals, + const bool useRowNames = true); + + /// Write the data in Lp format in the file with name filename. + /// Write objective function name and row names if useRowNames = true. + int writeLp(const char *filename, const bool useRowNames = true); + + /// Write the data in Lp format in the file pointed to by the parameter fp. + /// Write objective function name and row names if useRowNames = true. + int writeLp(FILE *fp, const bool useRowNames = true); + + /// Read the data in Lp format from the file with name filename, using + /// the given value for epsilon. If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename, const double epsilon); + + /// Read the data in Lp format from the file with name filename. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(const char *filename); + + /// Read the data in Lp format from the file stream, using + /// the given value for epsilon. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp, const double epsilon); + + /// Read the data in Lp format from the file stream. + /// If the original problem is + /// a maximization problem, the objective function is immediadtly + /// flipped to get a minimization problem. + void readLp(FILE *fp); + + /// Dump the data. Low level method for debugging. + void print() const; + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet * sets); + + /// Load in SOS stuff + void loadSOS(int numberSets,const CoinSet ** sets); + + /// Number of SOS sets + inline int numberSets() const + { return numberSets_;} + + /// Set information + inline CoinSet ** setInformation() const + { return set_;} + //@} +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + +protected: + /// Problem name + char * problemName_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of elements + int numberElements_; + + /// Pointer to column-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByColumn_; + + /// Pointer to row-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByRow_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of row rhs + mutable double * rhs_; + + /** Pointer to dense vector of slack variable upper bounds for ranged + constraints (undefined for non-ranged constraints) + */ + mutable double *rowrange_; + + /// Pointer to dense vector of row senses + mutable char * rowsense_; + + /// Pointer to dense vector of objective coefficients + double * objective_[MAX_OBJECTIVES]; + + /// Number of objectives + int num_objectives_; + + /// Constant offset for objective value + double objectiveOffset_[MAX_OBJECTIVES]; + + /// Pointer to dense vector specifying if a variable is continuous + /// (0) or integer (1). + char * integerType_; + + /// Pointer to sets + CoinSet ** set_; + + /// Number of sets + int numberSets_; + + /// Current file name + char * fileName_; + + /// Value to use for infinity + double infinity_; + + /// Value to use for epsilon + double epsilon_; + + /// Number of monomials printed in a row + int numberAcross_; + + /// Number of decimals printed for coefficients + int decimals_; + + /// Objective function name + char *objName_[MAX_OBJECTIVES]; + + /** Row names (including objective function name) + and column names when stopHash() for the corresponding + section was last called or for initial names (deemed invalid) + read from a file.<BR> + section = 0 for row names, + section = 1 for column names. */ + char **previous_names_[2]; + + /// card_previous_names_[section] holds the number of entries in the vector + /// previous_names_[section]. + /// section = 0 for row names, + /// section = 1 for column names. + int card_previous_names_[2]; + + /// Row names (including objective function name) + /// and column names (linked to Hash tables). + /// section = 0 for row names, + /// section = 1 for column names. + char **names_[2]; + + typedef struct { + int index, next; + } CoinHashLink; + + /// Maximum number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int maxHash_[2]; + + /// Number of entries in a hash table section. + /// section = 0 for row names, + /// section = 1 for column names. + int numberHash_[2]; + + /// Hash tables with two sections. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + mutable CoinHashLink *hash_[2]; + + /// Build the hash table for the given names. The parameter number is + /// the cardinality of parameter names. Remove duplicate names. + /// + /// section = 0 for row names, + /// section = 1 for column names. + void startHash(char const * const * const names, + const COINColumnIndex number, + int section); + + /// Delete hash storage. If section = 0, it also frees objName_. + /// section = 0 for row names, + /// section = 1 for column names. + void stopHash(int section); + + /// Return the index of the given name, return -1 if the name is not found. + /// Return getNumRows() for the objective function name. + /// section = 0 for row names (including objective function name), + /// section = 1 for column names. + COINColumnIndex findHash(const char *name, int section) const; + + /// Insert thisName in the hash table if not present yet; does nothing + /// if the name is already in. + /// section = 0 for row names, + /// section = 1 for column names. + void insertHash(const char *thisName, int section); + + /// Write a coefficient. + /// print_1 = 0 : do not print the value 1. + void out_coeff(FILE *fp, double v, int print_1) const; + + /// Locate the objective function. + /// Return 1 if found the keyword "Minimize" or one of its variants, + /// -1 if found keyword "Maximize" or one of its variants. + int find_obj(FILE *fp) const; + + /// Return an integer indicating if the keyword "subject to" or one + /// of its variants has been read. + /// Return 1 if buff is the keyword "s.t" or one of its variants. + /// Return 2 if buff is the keyword "subject" or one of its variants. + /// Return 0 otherwise. + int is_subject_to(const char *buff) const; + + /// Return 1 if the first character of buff is a number. + /// Return 0 otherwise. + int first_is_number(const char *buff) const; + + /// Return 1 if the first character of buff is '/' or '\'. + /// Return 0 otherwise. + int is_comment(const char *buff) const; + + /// Read the file fp until buff contains an end of line + void skip_comment(char *buff, FILE *fp) const; + + /// Put in buff the next string that is not part of a comment + void scan_next(char *buff, FILE *fp) const; + + /// Return 1 if buff is the keyword "free" or one of its variants. + /// Return 0 otherwise. + int is_free(const char *buff) const; + + /// Return 1 if buff is the keyword "inf" or one of its variants. + /// Return 0 otherwise. + int is_inf(const char *buff) const; + + /// Return an integer indicating the inequality sense read. + /// Return 0 if buff is '<='. + /// Return 1 if buff is '='. + /// Return 2 if buff is '>='. + /// Return -1 otherwise. + int is_sense(const char *buff) const; + + /// Return an integer indicating if one of the keywords "Bounds", "Integers", + /// "Generals", "Binaries", "Semi-continuous", "Sos", "End", or one + /// of their variants has been read. (note Semi-continuous not coded) + /// Return 1 if buff is the keyword "Bounds" or one of its variants. + /// Return 2 if buff is the keyword "Integers" or "Generals" or one of their + /// variants. + /// Return 3 if buff is the keyword "Binaries" or one of its variants. + /// Return 4 if buff is the keyword "Semi-continuous" or one of its variants. + /// Return 5 if buff is the keyword "Sos" or one of its variants. + /// Return 6 if buff is the keyword "End" or one of its variants. + /// Return 0 otherwise. + int is_keyword(const char *buff) const; + + /// Read a monomial of the objective function. + /// Return 1 if "subject to" or one of its variants has been read. + int read_monom_obj(FILE *fp, double *coeff, char **name, int *cnt, + char **obj_name, int *num_objectives, int *obj_starts); + + /// Read a monomial of a constraint. + /// Return a positive number if the sense of the inequality has been + /// read (see method is_sense() for the return code). + /// Return -1 otherwise. + int read_monom_row(FILE *fp, char *start_str, double *coeff, char **name, + int cnt_coeff) const; + + /// Reallocate vectors related to number of coefficients. + void realloc_coeff(double **coeff, char ***colNames, int *maxcoeff) const; + + /// Reallocate vectors related to rows. + void realloc_row(char ***rowNames, int **start, double **rhs, + double **rowlow, double **rowup, int *maxrow) const; + + /// Reallocate vectors related to columns. + void realloc_col(double **collow, double **colup, char **is_int, + int *maxcol) const; + + /// Read a constraint. + void read_row(FILE *fp, char *buff, double **pcoeff, char ***pcolNames, + int *cnt_coeff, int *maxcoeff, + double *rhs, double *rowlow, double *rowup, + int *cnt_row, double inf) const; + + /** Check that current objective name and all row names are distinct + including row names obtained by adding "_low" for ranged constraints. + If there is a conflict in the names, they are replaced by default + row names (see setDefaultRowNames()). + + This method must not be called before + setLpDataWithoutRowAndColNames() has been called, since access + to the indices of all the ranged constraints is required. + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the row names is required. + */ + void checkRowNames(); + + /** Check that current column names are distinct. + If not, they are replaced by default + column names (see setDefaultColNames()). + + This method must not be called before + setLpDataRowAndColNames() has been called, since access + to all the column names is required. + */ + void checkColNames(); + +}; + +void +CoinLpIOUnitTest(const std::string& lpDir); + + +#endif diff --git a/thirdparty/linux/include/coin1/CoinMessage.hpp b/thirdparty/linux/include/coin1/CoinMessage.hpp new file mode 100644 index 0000000..cfdcd49 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinMessage.hpp @@ -0,0 +1,96 @@ +/* $Id: CoinMessage.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessage_H +#define CoinMessage_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +/*! \file + + This file contains the enum for the standard set of Coin messages and a + class definition whose sole purpose is to supply a constructor. The text + ot the messages is defined in CoinMessage.cpp, + + CoinMessageHandler.hpp contains the generic facilities for message + handling. +*/ + +#include "CoinMessageHandler.hpp" + +/*! \brief Symbolic names for the standard set of COIN messages */ + +enum COIN_Message +{ + COIN_MPS_LINE=0, + COIN_MPS_STATS, + COIN_MPS_ILLEGAL, + COIN_MPS_BADIMAGE, + COIN_MPS_DUPOBJ, + COIN_MPS_DUPROW, + COIN_MPS_NOMATCHROW, + COIN_MPS_NOMATCHCOL, + COIN_MPS_FILE, + COIN_MPS_BADFILE1, + COIN_MPS_BADFILE2, + COIN_MPS_EOF, + COIN_MPS_RETURNING, + COIN_MPS_CHANGED, + COIN_SOLVER_MPS, + COIN_PRESOLVE_COLINFEAS, + COIN_PRESOLVE_ROWINFEAS, + COIN_PRESOLVE_COLUMNBOUNDA, + COIN_PRESOLVE_COLUMNBOUNDB, + COIN_PRESOLVE_NONOPTIMAL, + COIN_PRESOLVE_STATS, + COIN_PRESOLVE_INFEAS, + COIN_PRESOLVE_UNBOUND, + COIN_PRESOLVE_INFEASUNBOUND, + COIN_PRESOLVE_INTEGERMODS, + COIN_PRESOLVE_POSTSOLVE, + COIN_PRESOLVE_NEEDS_CLEANING, + COIN_PRESOLVE_PASS, +# if PRESOLVE_DEBUG + COIN_PRESOLDBG_FIRSTCHECK, + COIN_PRESOLDBG_RCOSTACC, + COIN_PRESOLDBG_RCOSTSTAT, + COIN_PRESOLDBG_STATSB, + COIN_PRESOLDBG_DUALSTAT, +# endif + COIN_GENERAL_INFO, + COIN_GENERAL_INFO2, + COIN_GENERAL_WARNING, + COIN_DUMMY_END +}; + + +/*! \class CoinMessage + \brief The standard set of Coin messages + + This class provides convenient access to the standard set of Coin messages. + In a nutshell, it's a CoinMessages object with a constructor that + preloads the standard Coin messages. +*/ + +class CoinMessage : public CoinMessages { + +public: + + /**@name Constructors etc */ + //@{ + /*! \brief Constructor + + Build a CoinMessages object and load it with the standard set of + Coin messages. + */ + CoinMessage(Language language=us_en); + //@} + +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinMessageHandler.hpp b/thirdparty/linux/include/coin1/CoinMessageHandler.hpp new file mode 100644 index 0000000..7922630 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinMessageHandler.hpp @@ -0,0 +1,666 @@ +/* $Id: CoinMessageHandler.hpp 1514 2011-12-10 23:35:23Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMessageHandler_H +#define CoinMessageHandler_H + +#include "CoinUtilsConfig.h" +#include "CoinPragma.hpp" + +#include <iostream> +#include <cstdio> +#include <string> +#include <vector> + +/** \file CoinMessageHandler.hpp + \brief This is a first attempt at a message handler. + + The COIN Project is in favo(u)r of multi-language support. This implementation + of a message handler tries to make it as lightweight as possible in the sense + that only a subset of messages need to be defined --- the rest default to US + English. + + The default handler at present just prints to stdout or to a FILE pointer + + \todo + This needs to be worked over for correct operation with ISO character codes. +*/ + +/* + I (jjf) am strongly in favo(u)r of language support for an open + source project, but I have tried to make it as lightweight as + possible in the sense that only a subset of messages need to be + defined - the rest default to US English. There will be different + sets of messages for each component - so at present there is a + Clp component and a Coin component. + + Because messages are only used in a controlled environment and have no + impact on code and are tested by other tests I have included tests such + as language and derivation in other unit tests. +*/ +/* + Where there are derived classes I (jjf) have started message numbers at 1001. +*/ + + +/** \brief Class for one massaged message. + + A message consists of a text string with formatting codes (#message_), + an integer identifier (#externalNumber_) which also determines the severity + level (#severity_) of the message, and a detail (logging) level (#detail_). + + CoinOneMessage is just a container to hold this information. The + interpretation is set by CoinMessageHandler, which see. + */ + +class CoinOneMessage { + +public: + /**@name Constructors etc */ + //@{ + /** Default constructor. */ + CoinOneMessage(); + /** Normal constructor */ + CoinOneMessage(int externalNumber, char detail, + const char * message); + /** Destructor */ + ~CoinOneMessage(); + /** The copy constructor */ + CoinOneMessage(const CoinOneMessage&); + /** assignment operator. */ + CoinOneMessage& operator=(const CoinOneMessage&); + //@} + + /**@name Useful stuff */ + //@{ + /// Replace message text (<i>e.g.</i>, text in a different language) + void replaceMessage(const char * message); + //@} + + /**@name Get and set methods */ + //@{ + /** Get message ID number */ + inline int externalNumber() const + {return externalNumber_;} + /** \brief Set message ID number + + In the default CoinMessageHandler, this number is printed in the message + prefix and is used to determine the message severity level. + */ + inline void setExternalNumber(int number) + {externalNumber_=number;} + /// Severity + inline char severity() const + {return severity_;} + /// Set detail level + inline void setDetail(int level) + {detail_=static_cast<char> (level);} + /// Get detail level + inline int detail() const + {return detail_;} + /// Return the message text + inline char * message() const + {return message_;} + //@} + + /**@name member data */ + //@{ + /// number to print out (also determines severity) + int externalNumber_; + /// Will only print if detail matches + char detail_; + /// Severity + char severity_; + /// Messages (in correct language) (not all 400 may exist) + mutable char message_[400]; + //@} +}; + +/** \brief Class to hold and manipulate an array of massaged messages. + + Note that the message index used to reference a message in the array of + messages is completely distinct from the external ID number stored with the + message. +*/ + +class CoinMessages { + +public: + /** \brief Supported languages + + These are the languages that are supported. At present only + us_en is serious and the rest are for testing. + */ + enum Language { + us_en = 0, + uk_en, + it + }; + + /**@name Constructors etc */ + //@{ + /** Constructor with number of messages. */ + CoinMessages(int numberMessages=0); + /** Destructor */ + ~CoinMessages(); + /** The copy constructor */ + CoinMessages(const CoinMessages&); + /** assignment operator. */ + CoinMessages& operator=(const CoinMessages&); + //@} + + /**@name Useful stuff */ + //@{ + /*! \brief Installs a new message in the specified index position + + Any existing message is replaced, and a copy of the specified message is + installed. + */ + void addMessage(int messageNumber, const CoinOneMessage & message); + /*! \brief Replaces the text of the specified message + + Any existing text is deleted and the specified text is copied into the + specified message. + */ + void replaceMessage(int messageNumber, const char * message); + /** Language. Need to think about iso codes */ + inline Language language() const + {return language_;} + /** Set language */ + void setLanguage(Language newlanguage) + {language_ = newlanguage;} + /// Change detail level for one message + void setDetailMessage(int newLevel, int messageNumber); + /** \brief Change detail level for several messages + + messageNumbers is expected to contain the indices of the messages to be + changed. + If numberMessages >= 10000 or messageNumbers is NULL, the detail level + is changed on all messages. + */ + void setDetailMessages(int newLevel, int numberMessages, + int * messageNumbers); + /** Change detail level for all messages with low <= ID number < high */ + void setDetailMessages(int newLevel, int low, int high); + + /// Returns class + inline int getClass() const + { return class_;} + /// Moves to compact format + void toCompact(); + /// Moves from compact format + void fromCompact(); + //@} + + /**@name member data */ + //@{ + /// Number of messages + int numberMessages_; + /// Language + Language language_; + /// Source (null-terminated string, maximum 4 characters). + char source_[5]; + /// Class - see later on before CoinMessageHandler + int class_; + /** Length of fake CoinOneMessage array. + First you get numberMessages_ pointers which point to stuff + */ + int lengthMessages_; + /// Messages + CoinOneMessage ** message_; + //@} +}; + +// for convenience eol +enum CoinMessageMarker { + CoinMessageEol = 0, + CoinMessageNewline = 1 +}; + +/** Base class for message handling + + The default behavior is described here: messages are printed, and (if the + severity is sufficiently high) execution will be aborted. Inherit and + redefine the methods #print and #checkSeverity to augment the behaviour. + + Messages can be printed with or without a prefix; the prefix will consist + of a source string, the external ID number, and a letter code, + <i>e.g.</i>, Clp6024W. + A prefix makes the messages look less nimble but is very useful + for "grep" <i>etc</i>. + + <h3> Usage </h3> + + The general approach to using the COIN messaging facility is as follows: + <ul> + <li> Define your messages. For each message, you must supply an external + ID number, a log (detail) level, and a format string. Typically, you + define a convenience structure for this, something that's easy to + use to create an array of initialised message definitions at compile + time. + <li> Create a CoinMessages object, sized to accommodate the number of + messages you've defined. (Incremental growth will happen if + necessary as messages are loaded, but it's inefficient.) + <li> Load the messages into the CoinMessages object. Typically this + entails creating a CoinOneMessage object for each message and + passing it as a parameter to CoinMessages::addMessage(). You specify + the message's internal ID as the other parameter to addMessage. + <li> Create and use a CoinMessageHandler object to print messages. + </ul> + See, for example, CoinMessage.hpp and CoinMessage.cpp for an example of + the first three steps. `Format codes' below has a simple example of + printing a message. + + <h3> External ID numbers and severity </h3> + + CoinMessageHandler assumes the following relationship between the + external ID number of a message and the severity of the message: + \li <3000 are informational ('I') + \li <6000 warnings ('W') + \li <9000 non-fatal errors ('E') + \li >=9000 aborts the program (after printing the message) ('S') + + <h3> Log (detail) levels </h3> + + The default behaviour is that a message will print if its detail level + is less than or equal to the handler's log level. If all you want to + do is set a single log level for the handler, use #setLogLevel(int). + + If you want to get fancy, here's how it really works: There's an array, + #logLevels_, which you can manipulate with #setLogLevel(int,int). Each + entry logLevels_[i] specifies the log level for messages of class i (see + CoinMessages::class_). If logLevels_[0] is set to the magic number -1000 + you get the simple behaviour described above, whatever the class of the + messages. If logLevels_[0] is set to a valid log level (>= 0), then + logLevels_[i] really is the log level for messages of class i. + + <h3> Format codes </h3> + + CoinMessageHandler can print integers (normal, long, and long long), + doubles, characters, and strings. See the descriptions of the + various << operators. + + When processing a standard message with a format string, the formatting + codes specified in the format string will be passed to the sprintf + function, along with the argument. When generating a message with no + format string, each << operator uses a simple format code appropriate for + its argument. Consult the documentation for the standard printf facility + for further information on format codes. + + The special format code `%?' provides a hook to enable or disable + printing. For each `%?' code, there must be a corresponding call to + printing(bool). This provides a way to define optional parts in + messages, delineated by the code `%?' in the format string. Printing can + be suppressed for these optional parts, but any operands must still be + supplied. For example, given the message string + \verbatim + "A message with%? an optional integer %d and%? a double %g." + \endverbatim + installed in CoinMessages \c exampleMsgs with index 5, and + \c CoinMessageHandler \c hdl, the code + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(true) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with an optional integer 42 and a double 53.5. + \endverbatim + while + \code + hdl.message(5,exampleMsgs) ; + hdl.printing(false) << 42 ; + hdl.printing(true) << 53.5 << CoinMessageEol ; + \endcode + will print + \verbatim + A message with a double 53.5. + \endverbatim + + For additional examples of usage, see CoinMessageHandlerUnitTest in + CoinMessageHandlerTest.cpp. +*/ + +class CoinMessageHandler { + +friend bool CoinMessageHandlerUnitTest () ; + +public: + /**@name Virtual methods that the derived classes may provide */ + //@{ + /** Print message, return 0 normally. + */ + virtual int print() ; + /** Check message severity - if too bad then abort + */ + virtual void checkSeverity() ; + //@} + + /**@name Constructors etc */ + //@{ + /// Constructor + CoinMessageHandler(); + /// Constructor to put to file pointer (won't be closed) + CoinMessageHandler(FILE *fp); + /** Destructor */ + virtual ~CoinMessageHandler(); + /** The copy constructor */ + CoinMessageHandler(const CoinMessageHandler&); + /** Assignment operator. */ + CoinMessageHandler& operator=(const CoinMessageHandler&); + /// Clone + virtual CoinMessageHandler * clone() const; + //@} + /**@name Get and set methods */ + //@{ + /// Get detail level of a message. + inline int detail(int messageNumber, const CoinMessages &normalMessage) const + { return normalMessage.message_[messageNumber]->detail();} + /** Get current log (detail) level. */ + inline int logLevel() const + { return logLevel_;} + /** \brief Set current log (detail) level. + + If the log level is equal or greater than the detail level of a message, + the message will be printed. A rough convention for the amount of output + expected is + - 0 - none + - 1 - minimal + - 2 - normal low + - 3 - normal high + - 4 - verbose + + Please assign log levels to messages accordingly. Log levels of 8 and + above (8,16,32, <i>etc</i>.) are intended for selective debugging. + The logical AND of the log level specified in the message and the current + log level is used to determine if the message is printed. (In other words, + you're using individual bits to determine which messages are printed.) + */ + void setLogLevel(int value); + /** Get alternative log level. */ + inline int logLevel(int which) const + { return logLevels_[which];} + /*! \brief Set alternative log level value. + + Can be used to store alternative log level information within the handler. + */ + void setLogLevel(int which, int value); + + /// Set the number of significant digits for printing floating point numbers + void setPrecision(unsigned int new_precision); + /// Current number of significant digits for printing floating point numbers + inline int precision() { return (g_precision_) ; } + + /// Switch message prefix on or off. + void setPrefix(bool yesNo); + /// Current setting for printing message prefix. + bool prefix() const; + /*! \brief Values of double fields already processed. + + As the parameter for a double field is processed, the value is saved + and can be retrieved using this function. + */ + inline double doubleValue(int position) const + { return doubleValue_[position];} + /*! \brief Number of double fields already processed. + + Incremented each time a field of type double is processed. + */ + inline int numberDoubleFields() const + {return static_cast<int>(doubleValue_.size());} + /*! \brief Values of integer fields already processed. + + As the parameter for a integer field is processed, the value is saved + and can be retrieved using this function. + */ + inline int intValue(int position) const + { return longValue_[position];} + /*! \brief Number of integer fields already processed. + + Incremented each time a field of type integer is processed. + */ + inline int numberIntFields() const + {return static_cast<int>(longValue_.size());} + /*! \brief Values of char fields already processed. + + As the parameter for a char field is processed, the value is saved + and can be retrieved using this function. + */ + inline char charValue(int position) const + { return charValue_[position];} + /*! \brief Number of char fields already processed. + + Incremented each time a field of type char is processed. + */ + inline int numberCharFields() const + {return static_cast<int>(charValue_.size());} + /*! \brief Values of string fields already processed. + + As the parameter for a string field is processed, the value is saved + and can be retrieved using this function. + */ + inline std::string stringValue(int position) const + { return stringValue_[position];} + /*! \brief Number of string fields already processed. + + Incremented each time a field of type string is processed. + */ + inline int numberStringFields() const + {return static_cast<int>(stringValue_.size());} + + /// Current message + inline CoinOneMessage currentMessage() const + {return currentMessage_;} + /// Source of current message + inline std::string currentSource() const + {return source_;} + /// Output buffer + inline const char * messageBuffer() const + {return messageBuffer_;} + /// Highest message number (indicates any errors) + inline int highestNumber() const + {return highestNumber_;} + /// Get current file pointer + inline FILE * filePointer() const + { return fp_;} + /// Set new file pointer + inline void setFilePointer(FILE * fp) + { fp_ = fp;} + //@} + + /**@name Actions to create a message */ + //@{ + /*! \brief Start a message + + Look up the specified message. A prefix will be generated if enabled. + The message will be printed if the current log level is equal or greater + than the log level of the message. + */ + CoinMessageHandler &message(int messageNumber, + const CoinMessages &messages) ; + + /*! \brief Start or continue a message + + With detail = -1 (default), does nothing except return a reference to the + handler. (I.e., msghandler.message() << "foo" is precisely equivalent + to msghandler << "foo".) If \p msgDetail is >= 0, is will be used + as the detail level to determine whether the message should print + (assuming class 0). + + This can be used with any of the << operators. One use is to start + a message which will be constructed entirely from scratch. Another + use is continuation of a message after code that interrupts the usual + sequence of << operators. + */ + CoinMessageHandler & message(int detail = -1) ; + + /*! \brief Print a complete message + + Generate a standard prefix and append \c msg `as is'. This is intended as + a transition mechanism. The standard prefix is generated (if enabled), + and \c msg is appended. The message must be ended with a CoinMessageEol + marker. Attempts to add content with << will have no effect. + + The default value of \p detail will not change printing status. If + \p detail is >= 0, it will be used as the detail level to determine + whether the message should print (assuming class 0). + + */ + CoinMessageHandler &message(int externalNumber, const char *source, + const char *msg, + char severity, int detail = -1) ; + + /*! \brief Process an integer parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (int intvalue); +#if COIN_BIG_INDEX==1 + /*! \brief Process a long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long longvalue); +#endif +#if COIN_BIG_INDEX==2 + /*! \brief Process a long long integer parameter value. + + The default format code is `%ld'. + */ + CoinMessageHandler & operator<< (long long longvalue); +#endif + /*! \brief Process a double parameter value. + + The default format code is `%d'. + */ + CoinMessageHandler & operator<< (double doublevalue); + /*! \brief Process a STL string parameter value. + + The default format code is `%g'. + */ + CoinMessageHandler & operator<< (const std::string& stringvalue); + /*! \brief Process a char parameter value. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (char charvalue); + /*! \brief Process a C-style string parameter value. + + The default format code is `%c'. + */ + CoinMessageHandler & operator<< (const char *stringvalue); + /*! \brief Process a marker. + + The default format code is `%s'. + */ + CoinMessageHandler & operator<< (CoinMessageMarker); + /** Finish (and print) the message. + + Equivalent to using the CoinMessageEol marker. + */ + int finish(); + /*! \brief Enable or disable printing of an optional portion of a message. + + Optional portions of a message are delimited by `%?' markers, and + printing processes one %? marker. If \c onOff is true, the subsequent + portion of the message (to the next %? marker or the end of the format + string) will be printed. If \c onOff is false, printing is suppressed. + Parameters must still be supplied, whether printing is suppressed or not. + See the class documentation for an example. + */ + CoinMessageHandler & printing(bool onOff); + + //@} + + /** Log levels will be by type and will then use type + given in CoinMessage::class_ + + - 0 - Branch and bound code or similar + - 1 - Solver + - 2 - Stuff in Coin directory + - 3 - Cut generators + */ +#define COIN_NUM_LOG 4 +/// Maximum length of constructed message (characters) +#define COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE 1000 +protected: + /**@name Protected member data */ + //@{ + /// values in message + std::vector<double> doubleValue_; + std::vector<int> longValue_; + std::vector<char> charValue_; + std::vector<std::string> stringValue_; + /// Log level + int logLevel_; + /// Log levels + int logLevels_[COIN_NUM_LOG]; + /// Whether we want prefix (may get more subtle so is int) + int prefix_; + /// Current message + CoinOneMessage currentMessage_; + /// Internal number for use with enums + int internalNumber_; + /// Format string for message (remainder) + char * format_; + /// Output buffer + char messageBuffer_[COIN_MESSAGE_HANDLER_MAX_BUFFER_SIZE]; + /// Position in output buffer + char * messageOut_; + /// Current source of message + std::string source_; + /** 0 - Normal. + 1 - Put in values, move along format, but don't print. + 2 - A complete message was provided; nothing more to do but print + when CoinMessageEol is processed. Any << operators are treated + as noops. + 3 - do nothing except look for CoinMessageEol (i.e., the message + detail level was not sufficient to cause it to print). + */ + int printStatus_; + /// Highest message number (indicates any errors) + int highestNumber_; + /// File pointer + FILE * fp_; + /// Current format for floating point numbers + char g_format_[8]; + /// Current number of significant digits for floating point numbers + int g_precision_ ; + //@} + +private: + + /** The body of the copy constructor and the assignment operator */ + void gutsOfCopy(const CoinMessageHandler &rhs) ; + + /*! \brief Internal function to locate next format code. + + Intended for internal use. Side effects modify the format string. + */ + char *nextPerCent(char *start, const bool initial = false) ; + + /*! \brief Internal printing function. + + Makes it easier to split up print into clean, print and check severity + */ + int internalPrint() ; + + /// Decide if this message should print. + void calcPrintStatus(int msglvl, int msgclass) ; + + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMessageHandler class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +bool +CoinMessageHandlerUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinModel.hpp b/thirdparty/linux/include/coin1/CoinModel.hpp new file mode 100644 index 0000000..6d1ff5b --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinModel.hpp @@ -0,0 +1,1054 @@ +/* $Id: CoinModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModel_H +#define CoinModel_H + +#include "CoinModelUseful.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinFinite.hpp" +class CoinBaseModel { + +public: + + + /**@name Constructors, destructor */ + //@{ + /// Default Constructor + CoinBaseModel (); + + /// Copy constructor + CoinBaseModel ( const CoinBaseModel &rhs); + + /// Assignment operator + CoinBaseModel & operator=( const CoinBaseModel& rhs); + + /// Clone + virtual CoinBaseModel * clone() const=0; + + /// Destructor + virtual ~CoinBaseModel () ; + //@} + + /**@name For getting information */ + //@{ + /// Return number of rows + inline int numberRows() const + { return numberRows_;} + /// Return number of columns + inline int numberColumns() const + { return numberColumns_;} + /// Return number of elements + virtual CoinBigIndex numberElements() const = 0; + /** Returns the (constant) objective offset + This is the RHS entry for the objective row + */ + inline double objectiveOffset() const + { return objectiveOffset_;} + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Get print level 0 - off, 1 - errors, 2 - more + inline int logLevel() const + { return logLevel_;} + /// Set print level 0 - off, 1 - errors, 2 - more + void setLogLevel(int value); + /// Return the problem name + inline const char * getProblemName() const + { return problemName_.c_str();} + /// Set problem name + void setProblemName(const char *name) ; + /// Set problem name + void setProblemName(const std::string &name) ; + /// Return the row block name + inline const std::string & getRowBlock() const + { return rowBlockName_;} + /// Set row block name + inline void setRowBlock(const std::string &name) + { rowBlockName_ = name;} + /// Return the column block name + inline const std::string & getColumnBlock() const + { return columnBlockName_;} + /// Set column block name + inline void setColumnBlock(const std::string &name) + { columnBlockName_ = name;} + /// Pass in message handler + void setMessageHandler(CoinMessageHandler * handler); + //@} + +protected: + /**@name Data members */ + //@{ + /// Current number of rows + int numberRows_; + /// Current number of columns + int numberColumns_; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + double optimizationDirection_; + /// Objective offset to be passed on + double objectiveOffset_; + /// Problem name + std::string problemName_; + /// Rowblock name + std::string rowBlockName_; + /// Columnblock name + std::string columnBlockName_; + /// Message handler (Passed in) + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + + /** Print level. + I could have gone for full message handling but this should normally + be silent and lightweight. + -1 - use passed in message handler + 0 - no output + 1 - on errors + 2 - more detailed + */ + int logLevel_; + //@} + /// data + +}; + +/** + This is a simple minded model which is stored in a format which makes + it easier to construct and modify but not efficient for algorithms. It has + to be passed across to ClpModel or OsiSolverInterface by addRows, addCol(umn)s + or loadProblem. + + It may have up to four parts - + 1) A matrix of doubles (or strings - see note A) + 2) Column information including integer information and names + 3) Row information including names + 4) Quadratic objective (not implemented - but see A) + + This class is meant to make it more efficient to build a model. It is at + its most efficient when all additions are done as addRow or as addCol but + not mixed. If only 1 and 2 exist then solver.addColumns may be used to pass to solver, + if only 1 and 3 exist then solver.addRows may be used. Otherwise solver.loadProblem + must be used. + + If addRows and addColumns are mixed or if individual elements are set then the + speed will drop to some extent and more memory will be used. + + It is also possible to iterate over existing elements and to access columns and rows + by name. Again each of these use memory and cpu time. However memory is unlikely + to be critical as most algorithms will use much more. + + Notes: + A) Although this could be used to pass nonlinear information around the + only use at present is to have named values e.g. value1 which can then be + set to a value after model is created. I have no idea whether that could + be useful but I thought it might be fun. + Quadratic terms are allowed in strings! A solver could try and use this + if so - the convention is that 0.5* quadratic is stored + + B) This class could be useful for modeling. +*/ + +class CoinModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a row - numberInRow may be zero */ + void addRow(int numberInRow, const int * columns, + const double * elements, double rowLower=-COIN_DBL_MAX, + double rowUpper=COIN_DBL_MAX, const char * name=NULL); + /// add a column - numberInColumn may be zero */ + void addColumn(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false); + /// add a column - numberInColumn may be zero */ + inline void addCol(int numberInColumn, const int * rows, + const double * elements, + double columnLower=0.0, + double columnUpper=COIN_DBL_MAX, double objectiveValue=0.0, + const char * name=NULL, bool isInteger=false) + { addColumn(numberInColumn, rows, elements, columnLower, columnUpper, objectiveValue, + name,isInteger);} + /// Sets value for row i and column j + inline void operator() (int i,int j,double value) + { setElement(i,j,value);} + /// Sets value for row i and column j + void setElement(int i,int j,double value) ; + /** Gets sorted row - user must provide enough space + (easiest is allocate number of columns). + If column or element NULL then just returns number + Returns number of elements + */ + int getRow(int whichRow, int * column, double * element); + /** Gets sorted column - user must provide enough space + (easiest is allocate number of rows). + If row or element NULL then just returns number + Returns number of elements + */ + int getColumn(int whichColumn, int * column, double * element); + /// Sets quadratic value for column i and j + void setQuadraticElement(int i,int j,double value) ; + /// Sets value for row i and column j as string + inline void operator() (int i,int j,const char * value) + { setElement(i,j,value);} + /// Sets value for row i and column j as string + void setElement(int i,int j,const char * value) ; + /// Associates a string with a value. Returns string id (or -1 if does not exist) + int associateElement(const char * stringValue, double value); + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,double rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,double rowUpper); + /** Sets rowLower and rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowBounds(int whichRow,double rowLower,double rowUpper); + /** Sets name (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowName(int whichRow,const char * rowName); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,double columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,double columnUpper); + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnBounds(int whichColumn,double columnLower,double columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,double columnObjective); + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnName(int whichColumn,const char * columnName); + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,bool columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer state (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setInteger(int whichColumn) + { setColumnIsInteger( whichColumn, true);} + /** Sets continuous (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setContinuous(int whichColumn) + { setColumnIsInteger( whichColumn, false);} + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColLower(int whichColumn,double columnLower) + { setColumnLower( whichColumn, columnLower);} + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColUpper(int whichColumn,double columnUpper) + { setColumnUpper( whichColumn, columnUpper);} + /** Sets columnLower and columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColBounds(int whichColumn,double columnLower,double columnUpper) + { setColumnBounds( whichColumn, columnLower, columnUpper);} + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColObjective(int whichColumn,double columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets name (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColName(int whichColumn,const char * columnName) + { setColumnName( whichColumn, columnName);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setColIsInteger(int whichColumn,bool columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Sets rowLower (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowLower(int whichRow,const char * rowLower); + /** Sets rowUpper (if row does not exist then + all rows up to this are defined with default values and no elements) + */ + void setRowUpper(int whichRow,const char * rowUpper); + /** Sets columnLower (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnLower(int whichColumn,const char * columnLower); + /** Sets columnUpper (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnUpper(int whichColumn,const char * columnUpper); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnObjective(int whichColumn,const char * columnObjective); + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + void setColumnIsInteger(int whichColumn,const char * columnIsInteger); + /** Sets columnObjective (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setObjective(int whichColumn,const char * columnObjective) + { setColumnObjective( whichColumn, columnObjective);} + /** Sets integer (if column does not exist then + all columns up to this are defined with default values and no elements) + */ + inline void setIsInteger(int whichColumn,const char * columnIsInteger) + { setColumnIsInteger( whichColumn, columnIsInteger);} + /** Deletes all entries in row and bounds. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteRow(int whichRow); + /** Deletes all entries in column and bounds and objective. Will be ignored by + writeMps etc and will be packed down if asked for. */ + void deleteColumn(int whichColumn); + /** Deletes all entries in column and bounds. If last column the number of columns + will be decremented and true returned. */ + inline void deleteCol(int whichColumn) + { deleteColumn(whichColumn);} + /// Takes element out of matrix - returning position (<0 if not there); + int deleteElement(int row, int column); + /// Takes element out of matrix when position known + void deleteThisElement(int row, int column,int position); + /** Packs down all rows i.e. removes empty rows permanently. Empty rows + have no elements and feasible bounds. returns number of rows deleted. */ + int packRows(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + int packColumns(); + /** Packs down all columns i.e. removes empty columns permanently. Empty columns + have no elements and no objective. returns number of columns deleted. */ + inline int packCols() + { return packColumns();} + /** Packs down all rows and columns. i.e. removes empty rows and columns permanently. + Empty rows have no elements and feasible bounds. + Empty columns have no elements and no objective. + returns number of rows+columns deleted. */ + int pack(); + + /** Sets columnObjective array + */ + void setObjective(int numberColumns,const double * objective) ; + /** Sets columnLower array + */ + void setColumnLower(int numberColumns,const double * columnLower); + /** Sets columnLower array + */ + inline void setColLower(int numberColumns,const double * columnLower) + { setColumnLower( numberColumns, columnLower);} + /** Sets columnUpper array + */ + void setColumnUpper(int numberColumns,const double * columnUpper); + /** Sets columnUpper array + */ + inline void setColUpper(int numberColumns,const double * columnUpper) + { setColumnUpper( numberColumns, columnUpper);} + /** Sets rowLower array + */ + void setRowLower(int numberRows,const double * rowLower); + /** Sets rowUpper array + */ + void setRowUpper(int numberRows,const double * rowUpper); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + May modify both models by cleaning up + */ + int differentModel(CoinModel & other, bool ignoreNames); + //@} + + + /**@name For structured models */ + //@{ + /// Pass in CoinPackedMatrix (and switch off element updates) + void passInMatrix(const CoinPackedMatrix & matrix); + /** Convert elements to CoinPackedMatrix (and switch off element updates). + Returns number of errors */ + int convertMatrix(); + /// Return a pointer to CoinPackedMatrix (or NULL) + inline const CoinPackedMatrix * packedMatrix() const + { return packedMatrix_;} + /// Return pointers to original rows (for decomposition) + inline const int * originalRows() const + { return rowType_;} + /// Return pointers to original columns (for decomposition) + inline const int * originalColumns() const + { return columnType_;} + //@} + + + /**@name For getting information */ + //@{ + /// Return number of elements + inline CoinBigIndex numberElements() const + { return numberElements_;} + /// Return elements as triples + inline const CoinModelTriple * elements() const + { return elements_;} + /// Returns value for row i and column j + inline double operator() (int i,int j) const + { return getElement(i,j);} + /// Returns value for row i and column j + double getElement(int i,int j) const; + /// Returns value for row rowName and column columnName + inline double operator() (const char * rowName,const char * columnName) const + { return getElement(rowName,columnName);} + /// Returns value for row rowName and column columnName + double getElement(const char * rowName,const char * columnName) const; + /// Returns quadratic value for columns i and j + double getQuadraticElement(int i,int j) const; + /** Returns value for row i and column j as string. + Returns NULL if does not exist. + Returns "Numeric" if not a string + */ + const char * getElementAsString(int i,int j) const; + /** Returns pointer to element for row i column j. + Only valid until next modification. + NULL if element does not exist */ + double * pointer (int i,int j) const; + /** Returns position in elements for row i column j. + Only valid until next modification. + -1 if element does not exist */ + int position (int i,int j) const; + + + /** Returns first element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInRow(int whichRow) const ; + /** Returns last element in given row - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInRow(int whichRow) const ; + /** Returns first element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink firstInColumn(int whichColumn) const ; + /** Returns last element in given column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInColumn(int whichColumn) const ; + /** Returns next element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.next would be NULL + */ + CoinModelLink next(CoinModelLink & current) const ; + /** Returns previous element in current row or column - index is -1 if none. + Index is given by .index and value by .value. + User could also tell because input.previous would be NULL + May not be correct if matrix updated. + */ + CoinModelLink previous(CoinModelLink & current) const ; + /** Returns first element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + May not be correct if matrix updated. + */ + CoinModelLink firstInQuadraticColumn(int whichColumn) const ; + /** Returns last element in given quadratic column - index is -1 if none. + Index is given by .index and value by .value + */ + CoinModelLink lastInQuadraticColumn(int whichColumn) const ; + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + double getRowLower(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + double getRowUpper(int whichRow) const ; + /** Gets name (if row does not exist then NULL) + */ + const char * getRowName(int whichRow) const ; + inline double rowLower(int whichRow) const + { return getRowLower(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline double rowUpper(int whichRow) const + { return getRowUpper(whichRow) ;} + /** Gets name (if row does not exist then NULL) + */ + inline const char * rowName(int whichRow) const + { return getRowName(whichRow);} + /** Gets columnLower (if column does not exist then 0.0) + */ + double getColumnLower(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + double getColumnUpper(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + double getColumnObjective(int whichColumn) const ; + /** Gets name (if column does not exist then NULL) + */ + const char * getColumnName(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + bool getColumnIsInteger(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double columnLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double columnUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double columnObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double objective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * columnName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool columnIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool isInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets columnLower (if column does not exist then 0.0) + */ + inline double getColLower(int whichColumn) const + { return getColumnLower(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline double getColUpper(int whichColumn) const + { return getColumnUpper(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline double getColObjective(int whichColumn) const + { return getColumnObjective(whichColumn);} + /** Gets name (if column does not exist then NULL) + */ + inline const char * getColName(int whichColumn) const + { return getColumnName(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline bool getColIsInteger(int whichColumn) const + { return getColumnIsInteger(whichColumn);} + /** Gets rowLower (if row does not exist then -COIN_DBL_MAX) + */ + const char * getRowLowerAsString(int whichRow) const ; + /** Gets rowUpper (if row does not exist then +COIN_DBL_MAX) + */ + const char * getRowUpperAsString(int whichRow) const ; + inline const char * rowLowerAsString(int whichRow) const + { return getRowLowerAsString(whichRow);} + /** Gets rowUpper (if row does not exist then COIN_DBL_MAX) + */ + inline const char * rowUpperAsString(int whichRow) const + { return getRowUpperAsString(whichRow) ;} + /** Gets columnLower (if column does not exist then 0.0) + */ + const char * getColumnLowerAsString(int whichColumn) const ; + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + const char * getColumnUpperAsString(int whichColumn) const ; + /** Gets columnObjective (if column does not exist then 0.0) + */ + const char * getColumnObjectiveAsString(int whichColumn) const ; + /** Gets if integer (if column does not exist then false) + */ + const char * getColumnIsIntegerAsString(int whichColumn) const ; + /** Gets columnLower (if column does not exist then 0.0) + */ + inline const char * columnLowerAsString(int whichColumn) const + { return getColumnLowerAsString(whichColumn);} + /** Gets columnUpper (if column does not exist then COIN_DBL_MAX) + */ + inline const char * columnUpperAsString(int whichColumn) const + { return getColumnUpperAsString(whichColumn) ;} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * columnObjectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets columnObjective (if column does not exist then 0.0) + */ + inline const char * objectiveAsString(int whichColumn) const + { return getColumnObjectiveAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * columnIsIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /** Gets if integer (if column does not exist then false) + */ + inline const char * isIntegerAsString(int whichColumn) const + { return getColumnIsIntegerAsString(whichColumn);} + /// Row index from row name (-1 if no names or no match) + int row(const char * rowName) const; + /// Column index from column name (-1 if no names or no match) + int column(const char * columnName) const; + /// Returns type + inline int type() const + { return type_;} + /// returns unset value + inline double unsetValue() const + { return -1.23456787654321e-97;} + /// Creates a packed matrix - return number of errors + int createPackedMatrix(CoinPackedMatrix & matrix, + const double * associated); + /** Fills in startPositive and startNegative with counts for +-1 matrix. + If not +-1 then startPositive[0]==-1 otherwise counts and + startPositive[numberColumns]== size + - return number of errors + */ + int countPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + const double * associated); + /** Creates +-1 matrix given startPositive and startNegative counts for +-1 matrix. + */ + void createPlusMinusOne(CoinBigIndex * startPositive, CoinBigIndex * startNegative, + int * indices, + const double * associated); + /// Creates copies of various arrays - return number of errors + int createArrays(double * & rowLower, double * & rowUpper, + double * & columnLower, double * & columnUpper, + double * & objective, int * & integerType, + double * & associated); + /// Says if strings exist + inline bool stringsExist() const + { return string_.numberItems()!=0;} + /// Return string array + inline const CoinModelHash * stringArray() const + { return &string_;} + /// Returns associated array + inline double * associatedArray() const + { return associated_;} + /// Return rowLower array + inline double * rowLowerArray() const + { return rowLower_;} + /// Return rowUpper array + inline double * rowUpperArray() const + { return rowUpper_;} + /// Return columnLower array + inline double * columnLowerArray() const + { return columnLower_;} + /// Return columnUpper array + inline double * columnUpperArray() const + { return columnUpper_;} + /// Return objective array + inline double * objectiveArray() const + { return objective_;} + /// Return integerType array + inline int * integerTypeArray() const + { return integerType_;} + /// Return row names array + inline const CoinModelHash * rowNames() const + { return &rowName_;} + /// Return column names array + inline const CoinModelHash * columnNames() const + { return &columnName_;} + /// Reset row names + inline void zapRowNames() + { rowName_=CoinModelHash();} + /// Reset column names + inline void zapColumnNames() + { columnName_=CoinModelHash();} + /// Returns array of 0 or nonzero if can be a cut (or returns NULL) + inline const int * cutMarker() const + { return cut_;} + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + /// Return pointer to more information + inline void * moreInfo() const + { return moreInfo_;} + /// Set pointer to more information + inline void setMoreInfo(void * info) + { moreInfo_ = info;} + /** Returns which parts of model are set + 1 - matrix + 2 - rhs + 4 - row names + 8 - column bounds and/or objective + 16 - column names + 32 - integer types + */ + int whatIsSet() const; + //@} + + /**@name for block models - matrix will be CoinPackedMatrix */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + void loadBlock (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadBlock method using rowlb and rowub for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadBlock method using sense/rhs/range for default + argument values. + */ + void loadBlock (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) ; + + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModel(); + /** Constructor with sizes. */ + CoinModel(int firstRows, int firstColumns, int firstElements,bool noNames=false); + /** Read a problem in MPS or GAMS format from the given filename. + */ + CoinModel(const char *fileName, int allowStrings=0); + /** Read a problem from AMPL nl file + NOTE - as I can't work out configure etc the source code is in Cbc_ampl.cpp! + */ + CoinModel( int nonLinear, const char * fileName,const void * info); + /// From arrays + CoinModel(int numberRows, int numberColumns, + const CoinPackedMatrix * matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + /// Clone + virtual CoinBaseModel * clone() const; + + /** Destructor */ + virtual ~CoinModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModel(const CoinModel&); + /// = + CoinModel& operator=(const CoinModel&); + //@} + + /**@name For debug */ + //@{ + /// Checks that links are consistent + void validateLinks() const; + //@} +private: + /// Resize + void resize(int maximumRows, int maximumColumns, int maximumElements); + /// Fill in default row information + void fillRows(int which,bool forceCreation,bool fromAddRow=false); + /// Fill in default column information + void fillColumns(int which,bool forceCreation,bool fromAddColumn=false); + /** Fill in default linked list information (1= row, 2 = column) + Marked as const as list is mutable */ + void fillList(int which, CoinModelLinkedList & list,int type) const ; + /** Create a linked list and synchronize free + type 1 for row 2 for column + Marked as const as list is mutable */ + void createList(int type) const; + /// Adds one string, returns index + int addString(const char * string); + /** Gets a double from a string possibly containing named strings, + returns unset if not found + */ + double getDoubleFromString(CoinYacc & info, const char * string); + /// Frees value memory + void freeStringMemory(CoinYacc & info); +public: + /// Fills in all associated - returning number of errors + int computeAssociated(double * associated); + /** Gets correct form for a quadratic row - user to delete + If row is not quadratic then returns which other variables are involved + with tiny (1.0e-100) elements and count of total number of variables which could not + be put in quadratic form + */ + CoinPackedMatrix * quadraticRow(int rowNumber,double * linear, + int & numberBad) const; + /// Replaces a quadratic row + void replaceQuadraticRow(int rowNumber,const double * linear, const CoinPackedMatrix * quadraticPart); + /** If possible return a model where if all variables marked nonzero are fixed + the problem will be linear. At present may only work if quadratic. + Returns NULL if not possible + */ + CoinModel * reorder(const char * mark) const; + /** Expands out all possible combinations for a knapsack + If buildObj NULL then just computes space needed - returns number elements + On entry numberOutput is maximum allowed, on exit it is number needed or + -1 (as will be number elements) if maximum exceeded. numberOutput will have at + least space to return values which reconstruct input. + Rows returned will be original rows but no entries will be returned for + any rows all of whose entries are in knapsack. So up to user to allow for this. + If reConstruct >=0 then returns number of entrie which make up item "reConstruct" + in expanded knapsack. Values in buildRow and buildElement; + */ + int expandKnapsack(int knapsackRow, int & numberOutput,double * buildObj, CoinBigIndex * buildStart, + int * buildRow, double * buildElement,int reConstruct=-1) const; + /// Sets cut marker array + void setCutMarker(int size,const int * marker); + /// Sets priority array + void setPriorities(int size,const int * priorities); + /// priorities (given for all columns (-1 if not integer) + inline const int * priorities() const + { return priority_;} + /// For decomposition set original row and column indices + void setOriginalIndices(const int * row, const int * column); + +private: + /** Read a problem from AMPL nl file + so not constructor so gdb will work + */ + void gdb( int nonLinear, const char * fileName, const void * info); + /// returns jColumn (-2 if linear term, -1 if unknown) and coefficient + int decodeBit(char * phrase, char * & nextPhrase, double & coefficient, bool ifFirst) const; + /// Aborts with message about packedMatrix + void badType() const; + /**@name Data members */ + //@{ + /// Maximum number of rows + int maximumRows_; + /// Maximum number of columns + int maximumColumns_; + /// Current number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// Current number of quadratic elements + int numberQuadraticElements_; + /// Maximum number of quadratic elements + int maximumQuadraticElements_; + /// Row lower + double * rowLower_; + /// Row upper + double * rowUpper_; + /// Row names + CoinModelHash rowName_; + /** Row types. + Has information - at present + bit 0 - rowLower is a string + bit 1 - rowUpper is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original rows (i.e. when decomposed) + */ + int * rowType_; + /// Objective + double * objective_; + /// Column Lower + double * columnLower_; + /// Column Upper + double * columnUpper_; + /// Column names + CoinModelHash columnName_; + /// Integer information + int * integerType_; + /// Strings + CoinModelHash string_; + /** Column types. + Has information - at present + bit 0 - columnLower is a string + bit 1 - columnUpper is a string + bit 2 - objective is a string + bit 3 - integer setting is a string + NOTE - if converted to CoinPackedMatrix - may be indices of + original columns (i.e. when decomposed) + */ + int * columnType_; + /// If simple then start of each row/column + int * start_; + /// Actual elements + CoinModelTriple * elements_; + /// Actual elements as CoinPackedMatrix + CoinPackedMatrix * packedMatrix_; + /// Hash for elements + mutable CoinModelHash2 hashElements_; + /// Linked list for rows + mutable CoinModelLinkedList rowList_; + /// Linked list for columns + mutable CoinModelLinkedList columnList_; + /// Actual quadratic elements (always linked lists) + CoinModelTriple * quadraticElements_; + /// Hash for quadratic elements + mutable CoinModelHash2 hashQuadraticElements_; + /// Array for sorting indices + int * sortIndices_; + /// Array for sorting elements + double * sortElements_; + /// Size of sort arrays + int sortSize_; + /// Linked list for quadratic rows + mutable CoinModelLinkedList quadraticRowList_; + /// Linked list for quadratic columns + mutable CoinModelLinkedList quadraticColumnList_; + /// Size of associated values + int sizeAssociated_; + /// Associated values + double * associated_; + /// Number of SOS - all these are done in one go e.g. from ampl + int numberSOS_; + /// SOS starts + int * startSOS_; + /// SOS members + int * memberSOS_; + /// SOS type + int * typeSOS_; + /// SOS priority + int * prioritySOS_; + /// SOS reference + double * referenceSOS_; + /// priorities (given for all columns (-1 if not integer) + int * priority_; + /// Nonzero if row is cut - done in one go e.g. from ampl + int * cut_; + /// Pointer to more information + void * moreInfo_; + /** Type of build - + -1 unset, + 0 for row, + 1 for column, + 2 linked. + 3 matrix is CoinPackedMatrix (and at present can't be modified); + */ + mutable int type_; + /// True if no names EVER being used (for users who know what they are doing) + bool noNames_; + /** Links present (could be tested by sizes of objects) + 0 - none, + 1 - row links, + 2 - column links, + 3 - both + */ + mutable int links_; + //@} +}; +/// Just function of single variable x +double getFunctionValueFromString(const char * string, const char * x, double xValue); +/// faster version +double getDoubleFromString(CoinYacc & info, const char * string, const char * x, double xValue); +#endif diff --git a/thirdparty/linux/include/coin1/CoinModelUseful.hpp b/thirdparty/linux/include/coin1/CoinModelUseful.hpp new file mode 100644 index 0000000..f9eeea3 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinModelUseful.hpp @@ -0,0 +1,441 @@ +/* $Id: CoinModelUseful.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinModelUseful_H +#define CoinModelUseful_H + + +#include <cstdlib> +#include <cmath> +#include <cassert> +#include <cfloat> +#include <cstring> +#include <cstdio> +#include <iostream> + + +#include "CoinPragma.hpp" + +/** + This is for various structures/classes needed by CoinModel. + + CoinModelLink + CoinModelLinkedList + CoinModelHash +*/ +/// for going through row or column + +class CoinModelLink { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLink(); + /** Destructor */ + ~CoinModelLink(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLink(const CoinModelLink&); + /// = + CoinModelLink& operator=(const CoinModelLink&); + //@} + + /**@name Sets and gets method */ + //@{ + /// Get row + inline int row() const + { return row_;} + /// Get column + inline int column() const + { return column_;} + /// Get value + inline double value() const + { return value_;} + /// Get value + inline double element() const + { return value_;} + /// Get position + inline int position() const + { return position_;} + /// Get onRow + inline bool onRow() const + { return onRow_;} + /// Set row + inline void setRow(int row) + { row_=row;} + /// Set column + inline void setColumn(int column) + { column_=column;} + /// Set value + inline void setValue(double value) + { value_=value;} + /// Set value + inline void setElement(double value) + { value_=value;} + /// Set position + inline void setPosition(int position) + { position_=position;} + /// Set onRow + inline void setOnRow(bool onRow) + { onRow_=onRow;} + //@} + +private: + /**@name Data members */ + //@{ + /// Row + int row_; + /// Column + int column_; + /// Value as double + double value_; + /// Position in data + int position_; + /// If on row chain + bool onRow_; + //@} +}; + +/// for linked lists +// for specifying triple +typedef struct { + // top bit is nonzero if string + // rest is row + unsigned int row; + //CoinModelRowIndex row; + int column; + double value; // If string then index into strings +} CoinModelTriple; +inline int rowInTriple(const CoinModelTriple & triple) +{ return triple.row&0x7fffffff;} +inline void setRowInTriple(CoinModelTriple & triple,int iRow) +{ triple.row = iRow|(triple.row&0x80000000);} +inline bool stringInTriple(const CoinModelTriple & triple) +{ return (triple.row&0x80000000)!=0;} +inline void setStringInTriple(CoinModelTriple & triple,bool string) +{ triple.row = (string ? 0x80000000 : 0)|(triple.row&0x7fffffff);} +inline void setRowAndStringInTriple(CoinModelTriple & triple, + int iRow,bool string) +{ triple.row = (string ? 0x80000000 : 0)|iRow;} +/// for names and hashing +// for hashing +typedef struct { + int index, next; +} CoinModelHashLink; + +/* Function type. */ +typedef double (*func_t) (double); + +/// For string evaluation +/* Data type for links in the chain of symbols. */ +struct symrec +{ + char *name; /* name of symbol */ + int type; /* type of symbol: either VAR or FNCT */ + union + { + double var; /* value of a VAR */ + func_t fnctptr; /* value of a FNCT */ + } value; + struct symrec *next; /* link field */ +}; + +typedef struct symrec symrec; + +class CoinYacc { +private: + CoinYacc(const CoinYacc& rhs); + CoinYacc& operator=(const CoinYacc& rhs); + +public: + CoinYacc() : symtable(NULL), symbuf(NULL), length(0), unsetValue(0) {} + ~CoinYacc() + { + if (length) { + free(symbuf); + symbuf = NULL; + } + symrec* s = symtable; + while (s) { + free(s->name); + symtable = s; + s = s->next; + free(symtable); + } + } + +public: + symrec * symtable; + char * symbuf; + int length; + double unsetValue; +}; + +class CoinModelHash { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash(); + /** Destructor */ + ~CoinModelHash(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash(const CoinModelHash&); + /// = + CoinModelHash& operator=(const CoinModelHash&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems,bool forceReHash=false); + /// Number of items i.e. rows if just row names + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + /// Names + inline const char *const * names() const + { return names_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(const char * name) const; + /// Adds to hash + void addHash(int index, const char * name); + /// Deletes from hash + void deleteHash(int index); + /// Returns name at position (or NULL) + const char * name(int which) const; + /// Returns non const name at position (or NULL) + char * getName(int which) const; + /// Sets name at position (does not create) + void setName(int which,char * name ) ; + /// Validates + void validateHash() const; +private: + /// Returns a hash value + int hashValue(const char * name) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// Names + char ** names_; + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +/// For int,int hashing +class CoinModelHash2 { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelHash2(); + /** Destructor */ + ~CoinModelHash2(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelHash2(const CoinModelHash2&); + /// = + CoinModelHash2& operator=(const CoinModelHash2&); + //@} + + /**@name sizing (just increases) */ + //@{ + /// Resize hash (also re-hashs) + void resize(int maxItems, const CoinModelTriple * triples,bool forceReHash=false); + /// Number of items + inline int numberItems() const + { return numberItems_;} + /// Set number of items + void setNumberItems(int number); + /// Maximum number of items + inline int maximumItems() const + { return maximumItems_;} + //@} + + /**@name hashing */ + //@{ + /// Returns index or -1 + int hash(int row, int column, const CoinModelTriple * triples) const; + /// Adds to hash + void addHash(int index, int row, int column, const CoinModelTriple * triples); + /// Deletes from hash + void deleteHash(int index, int row, int column); +private: + /// Returns a hash value + int hashValue(int row, int column) const; +public: + //@} +private: + /**@name Data members */ + //@{ + /// hash + CoinModelHashLink * hash_; + /// Number of items + int numberItems_; + /// Maximum number of items + int maximumItems_; + /// Last slot looked at + int lastSlot_; + //@} +}; +class CoinModelLinkedList { + +public: + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinModelLinkedList(); + /** Destructor */ + ~CoinModelLinkedList(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinModelLinkedList(const CoinModelLinkedList&); + /// = + CoinModelLinkedList& operator=(const CoinModelLinkedList&); + //@} + + /**@name sizing (just increases) */ + //@{ + /** Resize list - for row list maxMajor is maximum rows. + */ + void resize(int maxMajor,int maxElements); + /** Create list - for row list maxMajor is maximum rows. + type 0 row list, 1 column list + */ + void create(int maxMajor,int maxElements, + int numberMajor, int numberMinor, + int type, + int numberElements, const CoinModelTriple * triples); + /// Number of major items i.e. rows if just row links + inline int numberMajor() const + { return numberMajor_;} + /// Maximum number of major items i.e. rows if just row links + inline int maximumMajor() const + { return maximumMajor_;} + /// Number of elements + inline int numberElements() const + { return numberElements_;} + /// Maximum number of elements + inline int maximumElements() const + { return maximumElements_;} + /// First on free chain + inline int firstFree() const + { return first_[maximumMajor_];} + /// Last on free chain + inline int lastFree() const + { return last_[maximumMajor_];} + /// First on chain + inline int first(int which) const + { return first_[which];} + /// Last on chain + inline int last(int which) const + { return last_[which];} + /// Next array + inline const int * next() const + { return next_;} + /// Previous array + inline const int * previous() const + { return previous_;} + //@} + + /**@name does work */ + //@{ + /** Adds to list - easy case i.e. add row to row list + Returns where chain starts + */ + int addEasy(int majorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + */ + void addHard(int minorIndex, int numberOfElements, const int * indices, + const double * elements, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Adds to list - hard case i.e. add row to column list + This is when elements have been added to other copy + */ + void addHard(int first, const CoinModelTriple * triples, + int firstFree, int lastFree,const int * nextOther); + /** Deletes from list - same case i.e. delete row from row list + */ + void deleteSame(int which, CoinModelTriple * triples, + CoinModelHash2 & hash, bool zapTriples); + /** Deletes from list - other case i.e. delete row from column list + This is when elements have been deleted from other copy + */ + void updateDeleted(int which, CoinModelTriple * triples, + CoinModelLinkedList & otherList); + /** Deletes one element from Row list + */ + void deleteRowOne(int position, CoinModelTriple * triples, + CoinModelHash2 & hash); + /** Update column list for one element when + one element deleted from row copy + */ + void updateDeletedOne(int position, const CoinModelTriple * triples); + /// Fills first,last with -1 + void fill(int first,int last); + /** Puts in free list from other list */ + void synchronize(CoinModelLinkedList & other); + /// Checks that links are consistent + void validateLinks(const CoinModelTriple * triples) const; + //@} +private: + /**@name Data members */ + //@{ + /// Previous - maximumElements long + int * previous_; + /// Next - maximumElements long + int * next_; + /// First - maximumMajor+1 long (last free element chain) + int * first_; + /// Last - maximumMajor+1 long (last free element chain) + int * last_; + /// Number of major items i.e. rows if just row links + int numberMajor_; + /// Maximum number of major items i.e. rows if just row links + int maximumMajor_; + /// Number of elements + int numberElements_; + /// Maximum number of elements + int maximumElements_; + /// 0 row list, 1 column list + int type_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinMpsIO.hpp b/thirdparty/linux/include/coin1/CoinMpsIO.hpp new file mode 100644 index 0000000..8f0226a --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinMpsIO.hpp @@ -0,0 +1,1056 @@ +/* $Id: CoinMpsIO.hpp 1642 2013-10-16 00:43:14Z tkr $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinMpsIO_H +#define CoinMpsIO_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <vector> +#include <string> + +#include "CoinUtilsConfig.h" +#include "CoinPackedMatrix.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinFileIO.hpp" +class CoinModel; + +/// The following lengths are in decreasing order (for 64 bit etc) +/// Large enough to contain element index +/// This is already defined as CoinBigIndex +/// Large enough to contain column index +typedef int COINColumnIndex; + +/// Large enough to contain row index (or basis) +typedef int COINRowIndex; + +// We are allowing free format - but there is a limit! +// User can override by using CXXFLAGS += -DCOIN_MAX_FIELD_LENGTH=nnn +#ifndef COIN_MAX_FIELD_LENGTH +#define COIN_MAX_FIELD_LENGTH 160 +#endif +#define MAX_CARD_LENGTH 5*COIN_MAX_FIELD_LENGTH+80 + +enum COINSectionType { COIN_NO_SECTION, COIN_NAME_SECTION, COIN_ROW_SECTION, + COIN_COLUMN_SECTION, + COIN_RHS_SECTION, COIN_RANGES_SECTION, COIN_BOUNDS_SECTION, + COIN_ENDATA_SECTION, COIN_EOF_SECTION, COIN_QUADRATIC_SECTION, + COIN_CONIC_SECTION,COIN_QUAD_SECTION,COIN_SOS_SECTION, + COIN_BASIS_SECTION,COIN_UNKNOWN_SECTION +}; + +enum COINMpsType { COIN_N_ROW, COIN_E_ROW, COIN_L_ROW, COIN_G_ROW, + COIN_BLANK_COLUMN, COIN_S1_COLUMN, COIN_S2_COLUMN, COIN_S3_COLUMN, + COIN_INTORG, COIN_INTEND, COIN_SOSEND, COIN_UNSET_BOUND, + COIN_UP_BOUND, COIN_FX_BOUND, COIN_LO_BOUND, COIN_FR_BOUND, + COIN_MI_BOUND, COIN_PL_BOUND, COIN_BV_BOUND, + COIN_UI_BOUND, COIN_LI_BOUND, COIN_BOTH_BOUNDS_SET, + COIN_SC_BOUND, COIN_S1_BOUND, COIN_S2_BOUND, + COIN_BS_BASIS, COIN_XL_BASIS, COIN_XU_BASIS, + COIN_LL_BASIS, COIN_UL_BASIS, COIN_UNKNOWN_MPS_TYPE +}; +class CoinMpsIO; +/// Very simple code for reading MPS data +class CoinMpsCardReader { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor expects file to be open + /// This one takes gzFile if fp null + CoinMpsCardReader ( CoinFileInput *input, CoinMpsIO * reader ); + + /// Destructor + ~CoinMpsCardReader ( ); + //@} + + + /**@name card stuff */ + //@{ + /// Read to next section + COINSectionType readToNextSection ( ); + /// Gets next field and returns section type e.g. COIN_COLUMN_SECTION + COINSectionType nextField ( ); + /** Gets next field for .gms file and returns type. + -1 - EOF + 0 - what we expected (and processed so pointer moves past) + 1 - not what we expected + leading blanks always ignored + input types + 0 - anything - stops on non blank card + 1 - name (in columnname) + 2 - value + 3 - value name pair + 4 - equation type + 5 - ; + */ + int nextGmsField ( int expectedType ); + /// Returns current section type + inline COINSectionType whichSection ( ) const { + return section_; + } + /// Sets current section type + inline void setWhichSection(COINSectionType section ) { + section_=section; + } + /// Sees if free format. + inline bool freeFormat() const + { return freeFormat_;} + /// Sets whether free format. Mainly for blank RHS etc + inline void setFreeFormat(bool yesNo) + { freeFormat_=yesNo;} + /// Only for first field on card otherwise BLANK_COLUMN + /// e.g. COIN_E_ROW + inline COINMpsType mpsType ( ) const { + return mpsType_; + } + /// Reads and cleans card - taking out trailing blanks - return 1 if EOF + int cleanCard(); + /// Returns row name of current field + inline const char *rowName ( ) const { + return rowName_; + } + /// Returns column name of current field + inline const char *columnName ( ) const { + return columnName_; + } + /// Returns value in current field + inline double value ( ) const { + return value_; + } + /// Returns value as string in current field + inline const char *valueString ( ) const { + return valueString_; + } + /// Whole card (for printing) + inline const char *card ( ) const { + return card_; + } + /// Whole card - so we look at it (not const so nextBlankOr will work for gms reader) + inline char *mutableCard ( ) { + return card_; + } + /// set position (again so gms reader will work) + inline void setPosition(char * position) + { position_=position;} + /// get position (again so gms reader will work) + inline char * getPosition() const + { return position_;} + /// Returns card number + inline CoinBigIndex cardNumber ( ) const { + return cardNumber_; + } + /// Returns file input + inline CoinFileInput * fileInput ( ) const { + return input_; + } + /// Sets whether strings allowed + inline void setStringsAllowed() + { stringsAllowed_=true;} + //@} + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Current value + double value_; + /// Current card image + char card_[MAX_CARD_LENGTH]; + /// Current position within card image + char *position_; + /// End of card + char *eol_; + /// Current COINMpsType + COINMpsType mpsType_; + /// Current row name + char rowName_[COIN_MAX_FIELD_LENGTH]; + /// Current column name + char columnName_[COIN_MAX_FIELD_LENGTH]; + /// File input + CoinFileInput *input_; + /// Which section we think we are in + COINSectionType section_; + /// Card number + CoinBigIndex cardNumber_; + /// Whether free format. Just for blank RHS etc + bool freeFormat_; + /// Whether IEEE - 0 no, 1 INTEL, 2 not INTEL + int ieeeFormat_; + /// If all names <= 8 characters then allow embedded blanks + bool eightChar_; + /// MpsIO + CoinMpsIO * reader_; + /// Message handler + CoinMessageHandler * handler_; + /// Messages + CoinMessages messages_; + /// Current element as characters (only if strings allowed) + char valueString_[COIN_MAX_FIELD_LENGTH]; + /// Whether strings allowed + bool stringsAllowed_; + //@} +public: + /**@name methods */ + //@{ + /// type - 0 normal, 1 INTEL IEEE, 2 other IEEE + double osi_strtod(char * ptr, char ** output, int type); + /// remove blanks + static void strcpyAndCompress ( char *to, const char *from ); + /// + static char * nextBlankOr ( char *image ); + /// For strings + double osi_strtod(char * ptr, char ** output); + //@} + +}; + +//############################################################################# +#ifdef USE_SBB +class SbbObject; +class SbbModel; +#endif +/// Very simple class for containing data on set +class CoinSet { + +public: + + /**@name Constructor and destructor */ + //@{ + /// Default constructor + CoinSet ( ); + /// Constructor + CoinSet ( int numberEntries, const int * which); + + /// Copy constructor + CoinSet (const CoinSet &); + + /// Assignment operator + CoinSet & operator=(const CoinSet& rhs); + + /// Destructor + virtual ~CoinSet ( ); + //@} + + + /**@name gets */ + //@{ + /// Returns number of entries + inline int numberEntries ( ) const + { return numberEntries_; } + /// Returns type of set - 1 =SOS1, 2 =SOS2 + inline int setType ( ) const + { return setType_; } + /// Returns list of variables + inline const int * which ( ) const + { return which_; } + /// Returns weights + inline const double * weights ( ) const + { return weights_; } + //@} + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const + { return NULL;} + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Number of entries + int numberEntries_; + /// type of set + int setType_; + /// Which variables are in set + int * which_; + /// Weights + double * weights_; + //@} +}; + +//############################################################################# +/// Very simple class for containing SOS set +class CoinSosSet : public CoinSet{ + +public: + + /**@name Constructor and destructor */ + //@{ + /// Constructor + CoinSosSet ( int numberEntries, const int * which, const double * weights, int type); + + /// Destructor + virtual ~CoinSosSet ( ); + //@} + + +#ifdef USE_SBB + /**@name Use in sbb */ + //@{ + /// returns an object of type SbbObject + virtual SbbObject * sbbObject(SbbModel * model) const ; + //@} +#endif + +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + //@} +}; + +//############################################################################# + +/** MPS IO Interface + + This class can be used to read in mps files without a solver. After + reading the file, the CoinMpsIO object contains all relevant data, which + may be more than a particular OsiSolverInterface allows for. Items may + be deleted to allow for flexibility of data storage. + + The implementation makes the CoinMpsIO object look very like a dummy solver, + as the same conventions are used. +*/ + +class CoinMpsIO { + friend void CoinMpsIOUnitTest(const std::string & mpsDir); + +public: + +/** @name Methods to retrieve problem information + + These methods return information about the problem held by the CoinMpsIO + object. + + Querying an object that has no data associated with it result in zeros for + the number of rows and columns, and NULL pointers from the methods that + return vectors. Const pointers returned from any data-query method are + always valid +*/ +//@{ + /// Get number of columns + int getNumCols() const; + + /// Get number of rows + int getNumRows() const; + + /// Get number of nonzero elements + int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of constraint right-hand sides. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint right-hand side (rhs) is set as + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + + Given constraints with upper (rowupper) and/or lower (rowlower) bounds, + the constraint range (rowrange) is set as + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is 0.0 + </ul> + Put another way, only range constraints have a nontrivial value for + rowrange. + */ + const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + const double * getRowUpper() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + const double * getObjCoefficients() const; + + /// Get pointer to row-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of the coefficient matrix + const CoinPackedMatrix * getMatrixByCol() const; + + /// Return true if column is a continuous variable + bool isContinuous(int colNumber) const; + + /** Return true if a column is an integer variable + + Note: This function returns true if the the column + is a binary or general integer variable. + */ + bool isInteger(int columnNumber) const; + + /** Returns array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + const char * integerColumns() const; + + /** Returns the row name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * rowName(int index) const; + + /** Returns the column name for the specified index. + + Returns 0 if the index is out of range. + */ + const char * columnName(int index) const; + + /** Returns the index for the specified row name + + Returns -1 if the name is not found. + Returns numberRows for the objective row and > numberRows for + dropped free rows. + */ + int rowIndex(const char * name) const; + + /** Returns the index for the specified column name + + Returns -1 if the name is not found. + */ + int columnIndex(const char * name) const; + + /** Returns the (constant) objective offset + + This is the RHS entry for the objective row + */ + double objectiveOffset() const; + /// Set objective offset + inline void setObjectiveOffset(double value) + { objectiveOffset_=value;} + + /// Return the problem name + const char * getProblemName() const; + + /// Return the objective name + const char * getObjectiveName() const; + + /// Return the RHS vector name + const char * getRhsName() const; + + /// Return the range vector name + const char * getRangeName() const; + + /// Return the bound vector name + const char * getBoundName() const; + /// Number of string elements + inline int numberStringElements() const + { return numberStringElements_;} + /// String element + inline const char * stringElement(int i) const + { return stringElements_[i];} +//@} + + +/** @name Methods to set problem information + + Methods to load a problem into the CoinMpsIO object. +*/ +//@{ + + /// Set the problem data + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub, + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + char const * const * const colnames, + char const * const * const rownames); + void setMpsData(const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const char* rowsen, const double* rowrhs, + const double* rowrng, + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + + /** Pass in an array[getNumCols()] specifying if a variable is integer. + + At present, simply coded as zero (continuous) and non-zero (integer) + May be extended at a later date. + */ + void copyInIntegerInformation(const char * integerInformation); + + /// Set problem name + void setProblemName(const char *name) ; + + /// Set objective name + void setObjectiveName(const char *name) ; + +//@} + +/** @name Parameter set/get methods + + Methods to set and retrieve MPS IO parameters. +*/ + +//@{ + /// Set infinity + void setInfinity(double value); + + /// Get infinity + double getInfinity() const; + + /// Set default upper bound for integer variables + void setDefaultBound(int value); + + /// Get default upper bound for integer variables + int getDefaultBound() const; + /// Whether to allow string elements + inline int allowStringElements() const + { return allowStringElements_;} + /// Whether to allow string elements (0 no, 1 yes, 2 yes and try flip) + inline void setAllowStringElements(int yesNo) + { allowStringElements_ = yesNo;} + /** Small element value - elements less than this set to zero on input + default is 1.0e-14 */ + inline double getSmallElementValue() const + { return smallElement_;} + inline void setSmallElementValue(double value) + { smallElement_=value;} +//@} + + +/** @name Methods for problem input and output + + Methods to read and write MPS format problem files. + + The read and write methods return the number of errors that occurred during + the IO operation, or -1 if no file is opened. + + \note + If the CoinMpsIO class was compiled with support for libz then + readMps will automatically try to append .gz to the file name and open it as + a compressed file if the specified file name cannot be opened. + (Automatic append of the .bz2 suffix when libbz is used is on the TODO list.) + + \todo + Allow for file pointers and positioning +*/ + +//@{ + /// Set the current file name for the CoinMpsIO object + void setFileName(const char * name); + + /// Get the current file name for the CoinMpsIO object + const char * getFileName() const; + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + */ + int readMps(const char *filename, const char *extension = "mps"); + + /** Read a problem in MPS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readMps(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in MPS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + \todo + Provide an interface that will allow a client to associate a + CoinMpsCardReader object with a CoinMpsIO object by setting the + cardReader_ field. + */ + int readMps(); + /// and + int readMps(int & numberSets, CoinSet **& sets); + /** Read a basis in MPS format from the given filename. + If VALUES on NAME card and solution not NULL fills in solution + status values as for CoinWarmStartBasis (but one per char) + -1 file error, 0 normal, 1 has solution values + + Use "stdin" or "-" to read from stdin. + + If sizes of names incorrect - read without names + */ + int readBasis(const char *filename, const char *extension , + double * solution, unsigned char *rowStatus, unsigned char *columnStatus, + const std::vector<std::string> & colnames,int numberColumns, + const std::vector<std::string> & rownames, int numberRows); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + if convertObjective then massages objective column + */ + int readGms(const char *filename, const char *extension = "gms",bool convertObjective=false); + + /** Read a problem in GAMS format from the given filename. + + Use "stdin" or "-" to read from stdin. + But do sets as well + */ + int readGms(const char *filename, const char *extension , + int & numberSets, CoinSet **& sets); + + /** Read a problem in GAMS format from a previously opened file + + More precisely, read a problem using a CoinMpsCardReader object already + associated with this CoinMpsIO object. + + */ + // Not for now int readGms(); + /// and + int readGms(int & numberSets, CoinSet **& sets); + /** Read a problem in GMPL (subset of AMPL) format from the given filenames. + */ + int readGMPL(const char *modelName, const char * dataName=NULL, bool keepNames=false); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + \param quadratic specifies quadratic objective to be output + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, + CoinPackedMatrix * quadratic = NULL, + int numberSOS=0,const CoinSet * setInfo=NULL) const; + + /// Return card reader object so can see what last card was e.g. QUADOBJ + inline const CoinMpsCardReader * reader() const + { return cardReader_;} + + /** Read in a quadratic objective from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if QSECTION + Data is assumed to be Q and objective is c + 1/2 xT Q x + No assumption is made for symmetry, positive definite, etc. + No check is made for duplicates or non-triangular if checkSymmetry==0. + If 1 checks lower triangular (so off diagonal should be 2*Q) + if 2 makes lower triangular and assumes full Q (but adds off diagonals) + + Arrays should be deleted by delete [] + + Returns number of errors: + <ul> + <li> -1: bad file + <li> -2: no Quadratic section + <li> -3: an empty section + <li> +n: then matching errors etc (symmetry forced) + <li> -4: no matching errors but fails triangular test + (triangularity forced) + </ul> + columnStart is numberColumns+1 long, others numberNonZeros + */ + int readQuadraticMps(const char * filename, + int * &columnStart, int * &column, double * &elements, + int checkSymmetry); + + /** Read in a list of cones from the given filename. + + If filename is NULL (or the same as the currently open file) then + reading continues from the current file. + If not, the file is closed and the specified file is opened. + + Code should be added to + general MPS reader to read this if CSECTION + No checking is done that in unique cone + + Arrays should be deleted by delete [] + + Returns number of errors, -1 bad file, -2 no conic section, + -3 empty section + + columnStart is numberCones+1 long, other number of columns in matrix + + coneType is 1 for QUAD, 2 for RQUAD (numberCones long) +*/ + int readConicMps(const char * filename, + int * &columnStart, int * &column, int * &coneType, int & numberCones); + /// Set whether to move objective from matrix + inline void setConvertObjective(bool trueFalse) + { convertObjective_=trueFalse;} + /// copies in strings from a CoinModel - returns number + int copyStringElements(const CoinModel * model); + //@} + +/** @name Constructors and destructors */ +//@{ + /// Default Constructor + CoinMpsIO(); + + /// Copy constructor + CoinMpsIO (const CoinMpsIO &); + + /// Assignment operator + CoinMpsIO & operator=(const CoinMpsIO& rhs); + + /// Destructor + ~CoinMpsIO (); +//@} + + +/**@name Message handling */ +//@{ + /** Pass in Message handler + + Supply a custom message handler. It will not be destroyed when the + CoinMpsIO object is destroyed. + */ + void passInMessageHandler(CoinMessageHandler * handler); + + /// Set the language for messages. + void newLanguage(CoinMessages::Language language); + + /// Set the language for messages. + inline void setLanguage(CoinMessages::Language language) {newLanguage(language);} + + /// Return the message handler + inline CoinMessageHandler * messageHandler() const {return handler_;} + + /// Return the messages + inline CoinMessages messages() {return messages_;} + /// Return the messages pointer + inline CoinMessages * messagesPointer() {return & messages_;} +//@} + + +/**@name Methods to release storage + + These methods allow the client to reduce the storage used by the CoinMpsIO + object be selectively releasing unneeded problem information. +*/ +//@{ + /** Release all information which can be re-calculated. + + E.g., row sense, copies of rows, hash tables for names. + */ + void releaseRedundantInformation(); + + /// Release all row information (lower, upper) + void releaseRowInformation(); + + /// Release all column information (lower, upper, objective) + void releaseColumnInformation(); + + /// Release integer information + void releaseIntegerInformation(); + + /// Release row names + void releaseRowNames(); + + /// Release column names + void releaseColumnNames(); + + /// Release matrix information + void releaseMatrixInformation(); + //@} + +protected: + +/**@name Miscellaneous helper functions */ + //@{ + + /// Utility method used several times to implement public methods + void + setMpsDataWithoutRowAndColNames( + const CoinPackedMatrix& m, const double infinity, + const double* collb, const double* colub, + const double* obj, const char* integrality, + const double* rowlb, const double* rowub); + void + setMpsDataColAndRowNames( + const std::vector<std::string> & colnames, + const std::vector<std::string> & rownames); + void + setMpsDataColAndRowNames( + char const * const * const colnames, + char const * const * const rownames); + + + /// Does the heavy lifting for destruct and assignment. + void gutsOfDestructor(); + + /// Does the heavy lifting for copy and assignment. + void gutsOfCopy(const CoinMpsIO &); + + /// Clears problem data from the CoinMpsIO object. + void freeAll(); + + + /** A quick inlined function to convert from lb/ub style constraint + definition to sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from sense/rhs/range stryle + constraint definition to lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + + /** Deal with a filename + + As the name says. + Returns +1 if the file name is new, 0 if it's the same as before + (i.e., matches fileName_), and -1 if there's an error and the file + can't be opened. + Handles automatic append of .gz suffix when compiled with libz. + + \todo + Add automatic append of .bz2 suffix when compiled with libbz. + */ + + int dealWithFileName(const char * filename, const char * extension, + CoinFileInput * &input); + /** Add string to list + iRow==numberRows is objective, nr+1 is lo, nr+2 is up + iColumn==nc is rhs (can't cope with ranges at present) + */ + void addString(int iRow,int iColumn, const char * value); + /// Decode string + void decodeString(int iString, int & iRow, int & iColumn, const char * & value) const; + //@} + + + // for hashing + typedef struct { + int index, next; + } CoinHashLink; + + /**@name Hash table methods */ + //@{ + /// Creates hash list for names (section = 0 for rows, 1 columns) + void startHash ( char **names, const int number , int section ); + /// This one does it when names are already in + void startHash ( int section ) const; + /// Deletes hash storage + void stopHash ( int section ); + /// Finds match using hash, -1 not found + int findHash ( const char *name , int section ) const; + //@} + + /**@name Cached problem information */ + //@{ + /// Problem name + char * problemName_; + + /// Objective row name + char * objectiveName_; + + /// Right-hand side vector name + char * rhsName_; + + /// Range vector name + char * rangeName_; + + /// Bounds vector name + char * boundName_; + + /// Number of rows + int numberRows_; + + /// Number of columns + int numberColumns_; + + /// Number of coefficients + CoinBigIndex numberElements_; + + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack variable upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to column-wise copy of problem matrix coefficients. + CoinPackedMatrix *matrixByColumn_; + + /// Pointer to dense vector of row lower bounds + double * rowlower_; + + /// Pointer to dense vector of row upper bounds + double * rowupper_; + + /// Pointer to dense vector of column lower bounds + double * collower_; + + /// Pointer to dense vector of column upper bounds + double * colupper_; + + /// Pointer to dense vector of objective coefficients + double * objective_; + + /// Constant offset for objective value (i.e., RHS value for OBJ row) + double objectiveOffset_; + + + /** Pointer to dense vector specifying if a variable is continuous + (0) or integer (1). + */ + char * integerType_; + + /** Row and column names + Linked to hash table sections (0 - row names, 1 column names) + */ + char **names_[2]; + //@} + + /** @name Hash tables */ + //@{ + /// Current file name + char * fileName_; + + /// Number of entries in a hash table section + int numberHash_[2]; + + /// Hash tables (two sections, 0 - row names, 1 - column names) + mutable CoinHashLink *hash_[2]; + //@} + + /** @name CoinMpsIO object parameters */ + //@{ + /// Upper bound when no bounds for integers + int defaultBound_; + + /// Value to use for infinity + double infinity_; + /// Small element value + double smallElement_; + + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the message handler is the default handler. + + If true, the handler will be destroyed when the CoinMpsIO + object is destroyed; if false, it will not be destroyed. + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Card reader + CoinMpsCardReader * cardReader_; + /// If .gms file should it be massaged to move objective + bool convertObjective_; + /// Whether to allow string elements + int allowStringElements_; + /// Maximum number of string elements + int maximumStringElements_; + /// Number of string elements + int numberStringElements_; + /// String elements + char ** stringElements_; + //@} + +}; + +//############################################################################# +/** A function that tests the methods in the CoinMpsIO class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. Also, if this method is compiled with + optimization, the compilation takes 10-15 minutes and the machine pages + (has 256M core memory!)... */ +void +CoinMpsIOUnitTest(const std::string & mpsDir); +// Function to return number in most efficient way +// section is 0 for columns, 1 for rhs,ranges and 2 for bounds +/* formatType is + 0 - normal and 8 character names + 1 - extra accuracy + 2 - IEEE hex - INTEL + 3 - IEEE hex - not INTEL +*/ +void +CoinConvertDouble(int section, int formatType, double value, char outputValue[24]); + +#endif + diff --git a/thirdparty/linux/include/coin1/CoinOslFactorization.hpp b/thirdparty/linux/include/coin1/CoinOslFactorization.hpp new file mode 100644 index 0000000..0b51b01 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinOslFactorization.hpp @@ -0,0 +1,280 @@ +/* $Id: CoinOslFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 1987, 2009, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + Authors + + John Forrest + + */ +#ifndef CoinOslFactorization_H +#define CoinOslFactorization_H +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; +/** This deals with Factorization and Updates + This is ripped off from OSL!!!!!!!!! + + I am assuming that 32 bits is enough for number of rows or columns, but CoinBigIndex + may be redefined to get 64 bits. + */ + +typedef struct {int suc, pre;} EKKHlink; +typedef struct _EKKfactinfo { + double drtpiv; + double demark; + double zpivlu; + double zeroTolerance; + double areaFactor; + int *xrsadr; + int *xcsadr; + int *xrnadr; + int *xcnadr; + int *krpadr; + int *kcpadr; + int *mpermu; + int *bitArray; + int * back; + char * nonzero; + double * trueStart; + mutable double *kadrpm; + int *R_etas_index; + int *R_etas_start; + double *R_etas_element; + + int *xecadr; + int *xeradr; + double *xeeadr; + double *xe2adr; + EKKHlink * kp1adr; + EKKHlink * kp2adr; + double * kw1adr; + double * kw2adr; + double * kw3adr; + int * hpivcoR; + int nrow; + int nrowmx; + int firstDoRow; + int firstLRow; + int maxinv; + int nnetas; + int iterin; + int iter0; + int invok; + int nbfinv; + int num_resets; + int nnentl; + int nnentu; +#ifdef CLP_REUSE_ETAS + int save_nnentu; +#endif + int ndenuc; + int npivots; /* use as xpivsq in factorization */ + int kmxeta; + int xnetal; + int first_dense; + int last_dense; + int iterno; + int numberSlacks; + int lastSlack; + int firstNonSlack; + int xnetalval; + int lstart; + int if_sparse_update; + mutable int packedMode; + int switch_off_sparse_update; + int nuspike; + bool rows_ok; /* replaces test using mrstrt[1] */ +#ifdef CLP_REUSE_ETAS + mutable int reintro; +#endif + int nR_etas; + int sortedEta; /* if vector for F-T is sorted */ + int lastEtaCount; + int ifvsol; + int eta_size; + int last_eta_size; + int maxNNetas; +} EKKfactinfo; + +class CoinOslFactorization : public CoinOtherFactorization { + friend void CoinOslFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinOslFactorization ( ); + /// Copy constructor + CoinOslFactorization ( const CoinOslFactorization &other); + + /// Destructor + virtual ~CoinOslFactorization ( ); + /// = copy + CoinOslFactorization & operator = ( const CoinOslFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + /** When part of LP - given by basic variables. + Actually does factorization. + Arrays passed in have non negative value to say basic. + If status is okay, basic variables have pivot row - this is only needed + If status is singular, then basic variables have pivot row + and ones thrown out have -1 + returns 0 -okay, -1 singular, -2 too many in basis, -99 memory */ + int factorize ( const CoinPackedMatrix & matrix, + int rowIsBasic[], int columnIsBasic[] , + double areaFactor = 0.0 ); + //@} + + /**@name general stuff such as number of elements */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns array to put basis elements in + virtual CoinFactorizationDouble * elements() const; + /// Returns pivot row + virtual int * pivotRow() const; + /// Returns work area + virtual CoinFactorizationDouble * workArea() const; + /// Returns int work area + virtual int * intWorkArea() const; + /// Number of entries in each row + virtual int * numberInRow() const; + /// Number of entries in each column + virtual int * numberInColumn() const; + /// Returns array to put basis starts in + virtual CoinBigIndex * starts() const; + /// Returns permute back + virtual int * permuteBack() const; + /// Returns true if wants tableauColumn in replaceColumn + virtual bool wantsTableauColumn() const; + /** Useful information for factorization + 0 - iteration number + whereFrom is 0 for factorize and 1 for replaceColumn + */ + virtual void setUsefulInformation(const int * info,int whereFrom); + /// Set maximum pivots + virtual void maximumPivots ( int value ); + + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + /// Condition number - product of pivots after factorization + double conditionNumber() const; + /// Get rid of all memory + virtual void clearArrays(); + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + //inline void clearArrays() + //{ gutsOfDestructor();} + /// Returns array to put basis indices in + virtual int * indices() const; + /// Returns permute in + virtual inline int * permute() const + { return NULL;/*pivotRow_*/;} + //@} + + /// The real work of desstructor + void gutsOfDestructor(bool clearFact=true); + /// The real work of constructor + void gutsOfInitialize(bool zapFact=true); + /// The real work of copy + void gutsOfCopy(const CoinOslFactorization &other); + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// Osl factorization data + EKKfactinfo factInfo_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinPackedMatrix.hpp b/thirdparty/linux/include/coin1/CoinPackedMatrix.hpp new file mode 100644 index 0000000..c6837ac --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPackedMatrix.hpp @@ -0,0 +1,947 @@ +/* $Id: CoinPackedMatrix.hpp 1560 2012-11-24 00:29:01Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedMatrix_H +#define CoinPackedMatrix_H + +#include "CoinError.hpp" +#include "CoinTypes.hpp" +#ifndef CLP_NO_VECTOR +#include "CoinPackedVectorBase.hpp" +#include "CoinShallowPackedVector.hpp" +#else +class CoinRelFltEq; +#endif + +/** Sparse Matrix Base Class + + This class is intended to represent sparse matrices using row-major + or column-major ordering. The representation is very efficient for + adding, deleting, or retrieving major-dimension vectors. Adding + a minor-dimension vector is less efficient, but can be helped by + providing "extra" space as described in the next paragraph. Deleting + a minor-dimension vector requires inspecting all coefficients in the + matrix. Retrieving a minor-dimension vector would incur the same cost + and is not supported (except in the sense that you can write a loop to + retrieve all coefficients one at a time). Consider physically transposing + the matrix, or keeping a second copy with the other major-vector ordering. + + The sparse represention can be completely compact or it can have "extra" + space available at the end of each major vector. Incorporating extra + space into the sparse matrix representation can improve performance in + cases where new data needs to be inserted into the packed matrix against + the major-vector orientation (e.g, inserting a row into a matrix stored + in column-major order). + + For example if the matrix: + @verbatim + 3 1 0 -2 -1 0 0 -1 + 0 2 1.1 0 0 0 0 0 + 0 0 1 0 0 1 0 0 + 0 0 0 2.8 0 0 -1.2 0 + 5.6 0 0 0 1 0 0 1.9 + + was stored by rows (with no extra space) in + CoinPackedMatrix r then: + r.getElements() returns a vector containing: + 3 1 -2 -1 -1 2 1.1 1 1 2.8 -1.2 5.6 1 1.9 + r.getIndices() returns a vector containing: + 0 1 3 4 7 1 2 2 5 3 6 0 4 7 + r.getVectorStarts() returns a vector containing: + 0 5 7 9 11 14 + r.getNumElements() returns 14. + r.getMajorDim() returns 5. + r.getVectorSize(0) returns 5. + r.getVectorSize(1) returns 2. + r.getVectorSize(2) returns 2. + r.getVectorSize(3) returns 2. + r.getVectorSize(4) returns 3. + + If stored by columns (with no extra space) then: + c.getElements() returns a vector containing: + 3 5.6 1 2 1.1 1 -2 2.8 -1 1 1 -1.2 -1 1.9 + c.getIndices() returns a vector containing: + 0 4 0 1 1 2 0 3 0 4 2 3 0 4 + c.getVectorStarts() returns a vector containing: + 0 2 4 6 8 10 11 12 14 + c.getNumElements() returns 14. + c.getMajorDim() returns 8. + @endverbatim + + Compiling this class with CLP_NO_VECTOR defined will excise all methods + which use CoinPackedVectorBase, CoinPackedVector, or CoinShallowPackedVector + as parameters or return types. + + Compiling this class with COIN_FAST_CODE defined removes index range checks. +*/ +class CoinPackedMatrix { + friend void CoinPackedMatrixUnitTest(); + +public: + + + //--------------------------------------------------------------------------- + /**@name Query members */ + //@{ + /** Return the current setting of the extra gap. */ + inline double getExtraGap() const { return extraGap_; } + /** Return the current setting of the extra major. */ + inline double getExtraMajor() const { return extraMajor_; } + + /** Reserve sufficient space for appending major-ordered vectors. + If create is true, empty columns are created (for column generation) */ + void reserve(const int newMaxMajorDim, const CoinBigIndex newMaxSize, + bool create=false); + /** Clear the data, but do not free any arrays */ + void clear(); + + /** Whether the packed matrix is column major ordered or not. */ + inline bool isColOrdered() const { return colOrdered_; } + + /** Whether the packed matrix has gaps or not. */ + inline bool hasGaps() const { return (size_<start_[majorDim_]) ; } + + /** Number of entries in the packed matrix. */ + inline CoinBigIndex getNumElements() const { return size_; } + + /** Number of columns. */ + inline int getNumCols() const + { return colOrdered_ ? majorDim_ : minorDim_; } + + /** Number of rows. */ + inline int getNumRows() const + { return colOrdered_ ? minorDim_ : majorDim_; } + + /*! \brief A vector containing the elements in the packed matrix. + + Returns #elements_. Note that there might be gaps in this vector, + entries that do not belong to any major-dimension vector. To get + the actual elements one should look at this vector together with + vectorStarts (#start_) and vectorLengths (#length_). + */ + inline const double * getElements() const { return element_; } + + /*! \brief A vector containing the minor indices of the elements in + the packed matrix. + + Returns #index_. Note that there might be gaps in this list, + entries that do not belong to any major-dimension vector. To get + the actual elements one should look at this vector together with + vectorStarts (#start_) and vectorLengths (#length_). + */ + inline const int * getIndices() const { return index_; } + + /*! \brief The size of the <code>vectorStarts</code> array + + See #start_. + */ + inline int getSizeVectorStarts() const + { return ((majorDim_ > 0)?(majorDim_+1):(0)) ; } + + /*! \brief The size of the <code>vectorLengths</code> array + + See #length_. + */ + inline int getSizeVectorLengths() const { return majorDim_; } + + /*! \brief The positions where the major-dimension vectors start in + elements and indices. + + See #start_. + */ + inline const CoinBigIndex * getVectorStarts() const { return start_; } + + /*! \brief The lengths of the major-dimension vectors. + + See #length_. + */ + inline const int * getVectorLengths() const { return length_; } + + /** The position of the first element in the i'th major-dimension vector. + */ + CoinBigIndex getVectorFirst(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorFirst", "CoinPackedMatrix"); +#endif + return start_[i]; + } + /** The position of the last element (well, one entry <em>past</em> the + last) in the i'th major-dimension vector. */ + CoinBigIndex getVectorLast(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorLast", "CoinPackedMatrix"); +#endif + return start_[i] + length_[i]; + } + /** The length of i'th vector. */ + inline int getVectorSize(const int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vectorSize", "CoinPackedMatrix"); +#endif + return length_[i]; + } +#ifndef CLP_NO_VECTOR + /** Return the i'th vector in matrix. */ + const CoinShallowPackedVector getVector(int i) const { +#ifndef COIN_FAST_CODE + if (i < 0 || i >= majorDim_) + throw CoinError("bad index", "vector", "CoinPackedMatrix"); +#endif + return CoinShallowPackedVector(length_[i], + index_ + start_[i], + element_ + start_[i], + false); + } +#endif + /** Returns an array containing major indices. The array is + getNumElements long and if getVectorStarts() is 0,2,5 then + the array would start 0,0,1,1,1,2... + This method is provided to go back from a packed format + to a triple format. It returns NULL if there are gaps in + matrix so user should use removeGaps() if there are any gaps. + It does this as this array has to match getElements() and + getIndices() and because it makes no sense otherwise. + The returned array is allocated with <code>new int[]</code>, + free it with <code>delete[]</code>. */ + int * getMajorIndices() const; + //@} + + //--------------------------------------------------------------------------- + /**@name Modifying members */ + //@{ + /*! \brief Set the dimensions of the matrix. + + The method name is deceptive; the effect is to append empty columns + and/or rows to the matrix to reach the specified dimensions. + A negative number for either dimension means that that dimension + doesn't change. An exception will be thrown if the specified dimensions + are smaller than the current dimensions. + */ + void setDimensions(int numrows, int numcols); + + /** Set the extra gap to be allocated to the specified value. */ + void setExtraGap(const double newGap); + /** Set the extra major to be allocated to the specified value. */ + void setExtraMajor(const double newMajor); +#ifndef CLP_NO_VECTOR + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const CoinPackedVectorBase& vec); +#endif + /*! Append a column to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the column vector specifies a nonexistent row index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendCol(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of columns to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the column vectors specify a nonexistent row index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendCols(const int numcols, + const CoinPackedVectorBase * const * cols); +#endif + /*! Append a set of columns to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate row index). + No error checking is performed if \p numberRows < 0. + */ + int appendCols(const int numcols, + const CoinBigIndex * columnStarts, const int * row, + const double * element, int numberRows=-1); +#ifndef CLP_NO_VECTOR + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const CoinPackedVectorBase& vec); +#endif + /*! Append a row to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if the row vector specifies a nonexistent column index. Otherwise the + method assumes that every index fits into the matrix. + */ + void appendRow(const int vecsize, + const int *vecind, const double *vecelem); +#ifndef CLP_NO_VECTOR + /*! Append a set of rows to the end of the matrix. + + When compiled with COIN_DEBUG defined this method throws an exception + if any of the row vectors specify a nonexistent column index. Otherwise + the method assumes that every index fits into the matrix. + */ + void appendRows(const int numrows, + const CoinPackedVectorBase * const * rows); +#endif + /*! Append a set of rows to the end of the matrix. + + Returns the number of errors (nonexistent or duplicate column index). + No error checking is performed if \p numberColumns < 0. + */ + int appendRows(const int numrows, + const CoinBigIndex * rowStarts, const int * column, + const double * element, int numberColumns=-1); + + /** Append the argument to the "right" of the current matrix. Imagine this + as adding new columns (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of rows + is different in the matrices. */ + void rightAppendPackedMatrix(const CoinPackedMatrix& matrix); + /** Append the argument to the "bottom" of the current matrix. Imagine this + as adding new rows (don't worry about how the matrices are ordered, + that is taken care of). An exception is thrown if the number of columns + is different in the matrices. */ + void bottomAppendPackedMatrix(const CoinPackedMatrix& matrix); + + /** Delete the columns whose indices are listed in <code>indDel</code>. */ + void deleteCols(const int numDel, const int * indDel); + /** Delete the rows whose indices are listed in <code>indDel</code>. */ + void deleteRows(const int numDel, const int * indDel); + + /** Replace the elements of a vector. The indices remain the same. + At most the number specified will be replaced. + The index is between 0 and major dimension of matrix */ + void replaceVector(const int index, + const int numReplace, const double * newElements); + /** Modify one element of packed matrix. An element may be added. + This works for either ordering + If the new element is zero it will be deleted unless + keepZero true */ + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false); + /** Return one element of packed matrix. + This works for either ordering + If it is not present will return 0.0 */ + double getCoefficient(int row, int column) const; + + /** Eliminate all elements in matrix whose + absolute value is less than threshold. + The column starts are not affected. Returns number of elements + eliminated. Elements eliminated are at end of each vector + */ + int compress(double threshold); + /** Eliminate all duplicate AND small elements in matrix + The column starts are not affected. Returns number of elements + eliminated. + */ + int eliminateDuplicates(double threshold); + /** Sort all columns so indices are increasing.in each column */ + void orderMatrix(); + /** Really clean up matrix. + a) eliminate all duplicate AND small elements in matrix + b) remove all gaps and set extraGap_ and extraMajor_ to 0.0 + c) reallocate arrays and make max lengths equal to lengths + d) orders elements + returns number of elements eliminated + */ + int cleanMatrix(double threshold=1.0e-20); + //@} + + //--------------------------------------------------------------------------- + /**@name Methods that reorganize the whole matrix */ + //@{ + /** Remove the gaps from the matrix if there were any + Can also remove small elements fabs() <= removeValue*/ + void removeGaps(double removeValue=-1.0); + + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Does not allow duplicates. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); + /** Extract a submatrix from matrix. Those major-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. Allows duplicates and keeps order. */ + void submatrixOfWithDuplicates(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor); +#if 0 + /** Extract a submatrix from matrix. Those major/minor-dimension vectors of + the matrix comprise the submatrix whose indices are given in the + arguments. */ + void submatrixOf(const CoinPackedMatrix& matrix, + const int numMajor, const int * indMajor, + const int numMinor, const int * indMinor); +#endif + + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. */ + void copyOf(const CoinPackedMatrix& rhs); + /** Copy the arguments to the matrix. If <code>len</code> is a NULL pointer + then the matrix is assumed to have no gaps in it and <code>len</code> + will be created accordingly. */ + void copyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /** Copy method. This method makes an exact replica of the argument, + including the extra space parameters. + If there is room it will re-use arrays */ + void copyReuseArrays(const CoinPackedMatrix& rhs); + + /*! \brief Make a reverse-ordered copy. + + This method makes an exact replica of the argument with the major + vector orientation changed from row (column) to column (row). + The extra space parameters are also copied and reversed. + (Cf. #reverseOrdering, which does the same thing in place.) + */ + void reverseOrderedCopyOf(const CoinPackedMatrix& rhs); + + /** Assign the arguments to the matrix. If <code>len</code> is a NULL + pointer then the matrix is assumed to have no gaps in it and + <code>len</code> will be created accordingly. <br> + <strong>NOTE 1</strong>: After this method returns the pointers + passed to the method will be NULL pointers! <br> + <strong>NOTE 2</strong>: When the matrix is eventually destructed the + arrays will be deleted by <code>delete[]</code>. Hence one should use + this method ONLY if all array swere allocated by <code>new[]</code>! */ + void assignMatrix(const bool colordered, + const int minor, const int major, + const CoinBigIndex numels, + double *& elem, int *& ind, + CoinBigIndex *& start, int *& len, + const int maxmajor = -1, const CoinBigIndex maxsize = -1); + + + + /** Assignment operator. This copies out the data, but uses the current + matrix's extra space parameters. */ + CoinPackedMatrix & operator=(const CoinPackedMatrix& rhs); + + /*! \brief Reverse the ordering of the packed matrix. + + Change the major vector orientation of the matrix data structures from + row (column) to column (row). (Cf. #reverseOrderedCopyOf, which does + the same thing but produces a new matrix.) + */ + void reverseOrdering(); + + /*! \brief Transpose the matrix. + + \note + If you start with a column-ordered matrix and invoke transpose, you + will have a row-ordered transposed matrix. To change the major vector + orientation (e.g., to transform a column-ordered matrix to a + column-ordered transposed matrix), invoke transpose() followed by + #reverseOrdering(). + */ + void transpose(); + + /*! \brief Swap the content of two packed matrices. */ + void swap(CoinPackedMatrix& matrix); + + //@} + + //--------------------------------------------------------------------------- + /**@name Matrix times vector methods */ + //@{ + /** Return <code>A * x</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numColumns()</code> + @pre <code>y</code> must be of size <code>numRows()</code> */ + void times(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> in <code>y</code>. Same as the previous + method, just <code>x</code> is given in the form of a packed vector. */ + void times(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return <code>x * A</code> in <code>y</code>. + @pre <code>x</code> must be of size <code>numRows()</code> + @pre <code>y</code> must be of size <code>numColumns()</code> */ + void transposeTimes(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>x * A</code> in <code>y</code>. Same as the previous + method, just <code>x</code> is given in the form of a packed vector. */ + void transposeTimes(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Helper functions used internally, but maybe useful externally. + + These methods do not worry about testing whether the packed matrix is + row or column major ordered; they operate under the assumption that the + correct version is invoked. In fact, a number of other methods simply + just call one of these after testing the ordering of the matrix. */ + //@{ + + //------------------------------------------------------------------------- + /**@name Queries */ + //@{ + /** Count the number of entries in every minor-dimension vector and + return an array containing these lengths. The returned array is + allocated with <code>new int[]</code>, free it with + <code>delete[]</code>. */ + int * countOrthoLength() const; + /** Count the number of entries in every minor-dimension vector and + fill in an array containing these lengths. */ + void countOrthoLength(int * counts) const; + /** Major dimension. For row ordered matrix this would be the number of + rows. */ + inline int getMajorDim() const { return majorDim_; } + /** Set major dimension. For row ordered matrix this would be the number of + rows. Use with great care.*/ + inline void setMajorDim(int value) { majorDim_ = value; } + /** Minor dimension. For row ordered matrix this would be the number of + columns. */ + inline int getMinorDim() const { return minorDim_; } + /** Set minor dimension. For row ordered matrix this would be the number of + columns. Use with great care.*/ + inline void setMinorDim(int value) { minorDim_ = value; } + /** Current maximum for major dimension. For row ordered matrix this many + rows can be added without reallocating the vector related to the + major dimension (<code>start_</code> and <code>length_</code>). */ + inline int getMaxMajorDim() const { return maxMajorDim_; } + + /** Dump the matrix on stdout. When in dire straits this method can + help. */ + void dumpMatrix(const char* fname = NULL) const; + + /// Print a single matrix element. + void printMatrixElement(const int row_val, const int col_val) const; + //@} + + //------------------------------------------------------------------------- + /*! @name Append vectors + + \details + When compiled with COIN_DEBUG defined these methods throw an exception + if the major (minor) vector contains an index that's invalid for the + minor (major) dimension. Otherwise the methods assume that every index + fits into the matrix. + */ + //@{ +#ifndef CLP_NO_VECTOR + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a major-dimension vector to the end of the matrix. */ + void appendMajorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several major-dimensonvectors to the end of the matrix */ + void appendMajorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); + + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const CoinPackedVectorBase& vec); +#endif + /** Append a minor-dimension vector to the end of the matrix. */ + void appendMinorVector(const int vecsize, const int *vecind, + const double *vecelem); +#ifndef CLP_NO_VECTOR + /** Append several minor-dimension vectors to the end of the matrix */ + void appendMinorVectors(const int numvecs, + const CoinPackedVectorBase * const * vecs); +#endif + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + This case is when we know there are no gaps and majorDim_ will not + change. + + \todo + This method really belongs in the group of protected methods with + #appendMinor; there are no safeties here even with COIN_DEBUG. + Apparently this method was needed in ClpPackedMatrix and giving it + proper visibility was too much trouble. Should be moved. + */ + void appendMinorFast(const int number, + const CoinBigIndex * starts, const int * index, + const double * element); + //@} + + //------------------------------------------------------------------------- + /*! \name Append matrices + + \details + We'll document these methods assuming that the current matrix is + column major ordered (Hence in the <code>...SameOrdered()</code> + methods the argument is column ordered, in the + <code>OrthoOrdered()</code> methods the argument is row ordered.) + */ + //@{ + /** Append the columns of the argument to the right end of this matrix. + @pre <code>minorDim_ == matrix.minorDim_</code> <br> + This method throws an exception if the minor dimensions are not the + same. */ + void majorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the columns of the argument to the bottom end of this matrix. + @pre <code>majorDim_ == matrix.majorDim_</code> <br> + This method throws an exception if the major dimensions are not the + same. */ + void minorAppendSameOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the right end of this matrix. + @pre <code>minorDim_ == matrix.majorDim_</code> <br> + This method throws an exception if the minor dimension of the + current matrix is not the same as the major dimension of the + argument matrix. */ + void majorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + /** Append the rows of the argument to the bottom end of this matrix. + @pre <code>majorDim_ == matrix.minorDim_</code> <br> + This method throws an exception if the major dimension of the + current matrix is not the same as the minor dimension of the + argument matrix. */ + void minorAppendOrthoOrdered(const CoinPackedMatrix& matrix); + //@} + + //----------------------------------------------------------------------- + /**@name Delete vectors */ + //@{ + /** Delete the major-dimension vectors whose indices are listed in + <code>indDel</code>. */ + void deleteMajorVectors(const int numDel, const int * indDel); + /** Delete the minor-dimension vectors whose indices are listed in + <code>indDel</code>. */ + void deleteMinorVectors(const int numDel, const int * indDel); + //@} + + //----------------------------------------------------------------------- + /**@name Various dot products. */ + //@{ + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. + @pre <code>x</code> must be of size <code>majorDim()</code> + @pre <code>y</code> must be of size <code>minorDim()</code> */ + void timesMajor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. Same as the previous method, just <code>x</code> is + given in the form of a packed vector. */ + void timesMajor(const CoinPackedVectorBase& x, double * y) const; +#endif + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. + @pre <code>x</code> must be of size <code>minorDim()</code> + @pre <code>y</code> must be of size <code>majorDim()</code> */ + void timesMinor(const double * x, double * y) const; +#ifndef CLP_NO_VECTOR + /** Return <code>A * x</code> (multiplied from the "right" direction) in + <code>y</code>. Same as the previous method, just <code>x</code> is + given in the form of a packed vector. */ + void timesMinor(const CoinPackedVectorBase& x, double * y) const; +#endif + //@} + //@} + + //-------------------------------------------------------------------------- + /**@name Logical Operations. */ + //@{ +#ifndef CLP_NO_VECTOR + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + The operator used to test for equality can be specified using the + \p FloatEqual template parameter. + */ + template <class FloatEqual> bool + isEquivalent(const CoinPackedMatrix& rhs, const FloatEqual& eq) const + { + // Both must be column order or both row ordered and must be of same size + if ((isColOrdered() ^ rhs.isColOrdered()) || + (getNumCols() != rhs.getNumCols()) || + (getNumRows() != rhs.getNumRows()) || + (getNumElements() != rhs.getNumElements())) + return false; + + for (int i=getMajorDim()-1; i >= 0; --i) { + CoinShallowPackedVector pv = getVector(i); + CoinShallowPackedVector rhsPv = rhs.getVector(i); + if ( !pv.isEquivalent(rhsPv,eq) ) + return false; + } + return true; + } + + /*! \brief Test for equivalence and report differences + + Equivalence is defined as for #isEquivalent. In addition, this method will + print differences to std::cerr. Intended for use in unit tests and + for debugging. + */ + bool isEquivalent2(const CoinPackedMatrix& rhs) const; +#else + /*! \brief Test for equivalence. + + Two matrices are equivalent if they are both row- or column-ordered, + they have the same dimensions, and each (major) vector is equivalent. + This method is optimised for speed. CoinPackedVector#isEquivalent is + replaced with more efficient code for repeated comparison of + equal-length vectors. The CoinRelFltEq operator is used. + */ + bool isEquivalent(const CoinPackedMatrix& rhs, const CoinRelFltEq & eq) const; +#endif + /*! \brief Test for equivalence. + + The test for element equality is the default CoinRelFltEq operator. + */ + bool isEquivalent(const CoinPackedMatrix& rhs) const; + //@} + + //-------------------------------------------------------------------------- + /*! \name Non-const methods + + These are to be used with great care when doing column generation, etc. + */ + //@{ + /** A vector containing the elements in the packed matrix. Note that there + might be gaps in this list, entries that do not belong to any + major-dimension vector. To get the actual elements one should look at + this vector together with #start_ and #length_. */ + inline double * getMutableElements() const { return element_; } + /** A vector containing the minor indices of the elements in the packed + matrix. Note that there might be gaps in this list, entries that do not + belong to any major-dimension vector. To get the actual elements one + should look at this vector together with #start_ and + #length_. */ + inline int * getMutableIndices() const { return index_; } + + /** The positions where the major-dimension vectors start in #element_ and + #index_. */ + inline CoinBigIndex * getMutableVectorStarts() const { return start_; } + /** The lengths of the major-dimension vectors. */ + inline int * getMutableVectorLengths() const { return length_; } + /// Change the size of the bulk store after modifying - be careful + inline void setNumElements(CoinBigIndex value) + { size_ = value;} + /*! NULLify element array + + Used when space is very tight. Does not free the space! + */ + inline void nullElementArray() {element_=NULL;} + + /*! NULLify start array + + Used when space is very tight. Does not free the space! + */ + inline void nullStartArray() {start_=NULL;} + + /*! NULLify length array + + Used when space is very tight. Does not free the space! + */ + inline void nullLengthArray() {length_=NULL;} + + /*! NULLify index array + + Used when space is very tight. Does not free the space! + */ + inline void nullIndexArray() {index_=NULL;} + //@} + + //-------------------------------------------------------------------------- + /*! \name Constructors and destructors */ + //@{ + /// Default Constructor creates an empty column ordered packed matrix + CoinPackedMatrix(); + + /// A constructor where the ordering and the gaps are specified + CoinPackedMatrix(const bool colordered, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor, const double extraGap); + + CoinPackedMatrix(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + + /** Create packed matrix from triples. + If colordered is true then the created matrix will be column ordered. + Duplicate matrix elements are allowed. The created matrix will have + the sum of the duplicates. <br> + For example if: <br> + rowIndices[0]=2; colIndices[0]=5; elements[0]=2.0 <br> + rowIndices[1]=2; colIndices[1]=5; elements[1]=0.5 <br> + then the created matrix will contain a value of 2.5 in row 2 and column 5.<br> + The matrix is created without gaps. + */ + CoinPackedMatrix(const bool colordered, + const int * rowIndices, + const int * colIndices, + const double * elements, + CoinBigIndex numels ); + + /// Copy constructor + CoinPackedMatrix(const CoinPackedMatrix& m); + + /*! \brief Copy constructor with fine tuning + + This constructor allows for the specification of an exact amount of extra + space and/or reverse ordering. + + \p extraForMajor is the exact number of spare major vector slots after + any possible reverse ordering. If \p extraForMajor < 0, all gaps and small + elements will be removed from the copy, otherwise gaps and small elements + are preserved. + + \p extraElements is the exact number of spare element entries. + + The usual multipliers, #extraMajor_ and #extraGap_, are set to zero. + */ + CoinPackedMatrix(const CoinPackedMatrix &m, + int extraForMajor, int extraElements, + bool reverseOrdering = false) ; + + /** Subset constructor (without gaps). Duplicates are allowed + and order is as given */ + CoinPackedMatrix (const CoinPackedMatrix & wholeModel, + int numberRows, const int * whichRows, + int numberColumns, const int * whichColumns); + + /// Destructor + virtual ~CoinPackedMatrix(); + //@} + + /*! \name Debug Utilities */ + //@{ + /*! \brief Scan the matrix for anomalies. + + Returns the number of anomalies. Scans the structure for gaps, + obviously bogus indices and coefficients, and inconsistencies. Gaps + are not an error unless #hasGaps() says the matrix should be + gap-free. Zeroes are not an error unless \p zeroesAreError is set to + true. + + Values for verbosity are: + - 0: No messages, just the return value + - 1: Messages about errors + - 2: If there are no errors, a message indicating the matrix was + checked is printed (positive confirmation). + - 3: Adds a bit more information about the matrix. + - 4: Prints warnings about zeroes even if they're not considered + errors. + + Obviously bogus coefficients are coefficients that are NaN or have + absolute value greater than 1e50. Zeros have absolute value less + than 1e-50. + */ + int verifyMtx(int verbosity = 1, bool zeroesAreError = false) const ; + //@} + + //-------------------------------------------------------------------------- +protected: + void gutsOfDestructor(); + void gutsOfCopyOf(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len, + const double extraMajor=0.0, const double extraGap=0.0); + /// When no gaps we can do faster + void gutsOfCopyOfNoGaps(const bool colordered, + const int minor, const int major, + const double * elem, const int * ind, + const CoinBigIndex * start); + void gutsOfOpEqual(const bool colordered, + const int minor, const int major, const CoinBigIndex numels, + const double * elem, const int * ind, + const CoinBigIndex * start, const int * len); + void resizeForAddingMajorVectors(const int numVec, const int * lengthVec); + void resizeForAddingMinorVectors(const int * addedEntries); + + /*! \brief Append a set of rows (columns) to the end of a row (colum) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or invalid indices and return the + number of errors. A valid minor index must satisfy + \code 0 <= k < numberOther \endcode + If \p numberOther < 0 no checking is performed. + */ + int appendMajor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + /*! \brief Append a set of rows (columns) to the end of a column (row) + ordered matrix. + + If \p numberOther > 0 the method will check if any of the new rows + (columns) contain duplicate indices or indices outside the current + range for the major dimension and return the number of violations. + If \p numberOther <= 0 the major dimension will be expanded as + necessary and there are no checks for duplicate indices. + */ + int appendMinor(const int number, + const CoinBigIndex * starts, const int * index, + const double * element, int numberOther=-1); + +private: + inline CoinBigIndex getLastStart() const { + return majorDim_ == 0 ? 0 : start_[majorDim_]; + } + + //-------------------------------------------------------------------------- +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /** A flag indicating whether the matrix is column or row major ordered. */ + bool colOrdered_; + /** This much times more space should be allocated for each major-dimension + vector (with respect to the number of entries in the vector) when the + matrix is resized. The purpose of these gaps is to allow fast insertion + of new minor-dimension vectors. */ + double extraGap_; + /** his much times more space should be allocated for major-dimension + vectors when the matrix is resized. The purpose of these gaps is to + allow fast addition of new major-dimension vectors. */ + double extraMajor_; + + /** List of nonzero element values. The entries in the gaps between + major-dimension vectors are undefined. */ + double *element_; + /** List of nonzero element minor-dimension indices. The entries in the gaps + between major-dimension vectors are undefined. */ + int *index_; + /** Starting positions of major-dimension vectors. */ + CoinBigIndex *start_; + /** Lengths of major-dimension vectors. */ + int *length_; + + /// number of vectors in matrix + int majorDim_; + /// size of other dimension + int minorDim_; + /// the number of nonzero entries + CoinBigIndex size_; + + /// max space allocated for major-dimension + int maxMajorDim_; + /// max space allocated for entries + CoinBigIndex maxSize_; + //@} +}; + +//############################################################################# +/*! \brief Test the methods in the CoinPackedMatrix class. + + The only reason for it not to be a member method is that this way + it doesn't have to be compiled into the library. And that's a gain, + because the library should be compiled with optimization on, but this + method should be compiled with debugging. +*/ +void +CoinPackedMatrixUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPackedVector.hpp b/thirdparty/linux/include/coin1/CoinPackedVector.hpp new file mode 100644 index 0000000..9ea1feb --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPackedVector.hpp @@ -0,0 +1,657 @@ +/* $Id: CoinPackedVector.hpp 1509 2011-12-05 13:50:48Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVector_H +#define CoinPackedVector_H + +#include <map> + +#include "CoinPragma.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinSort.hpp" + +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif +/** Sparse Vector + +Stores vector of indices and associated element values. +Supports sorting of vector while maintaining the original indices. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 } + double el[ne] = { 10., 40., 1., 50. } + + // Create vector and set its value + CoinPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==0 ); + assert( r.originalPosition()[1]==1 ); + assert( r.originalPosition()[2]==2 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // sort Elements in increasing order + r.sortIncrElement(); + + // access each index and element + assert( r.indices ()[0]== 0 ); + assert( r.elements()[0]== 1. ); + assert( r.indices ()[1]== 1 ); + assert( r.elements()[1]==10. ); + assert( r.indices ()[2]== 4 ); + assert( r.elements()[2]==40. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access original position of index + assert( r.originalPosition()[0]==2 ); + assert( r.originalPosition()[1]==0 ); + assert( r.originalPosition()[2]==1 ); + assert( r.originalPosition()[3]==3 ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Restore orignal sort order + r.sortOriginalOrder(); + + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // Tests for equality and equivalence + CoinPackedVector r1; + r1=r; + assert( r==r1 ); + assert( r.equivalent(r1) ); + r.sortIncrElement(); + assert( r!=r1 ); + assert( r.equivalent(r1) ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinPackedVector : public CoinPackedVectorBase { + friend void CoinPackedVectorUnitTest(); + +public: + /**@name Get methods. */ + //@{ + /// Get the size + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + /// Get indices of elements + int * getIndices() { return indices_; } + /// Get the size + inline int getVectorNumElements() const { return nElements_; } + /// Get indices of elements + inline const int * getVectorIndices() const { return indices_; } + /// Get element values + inline const double * getVectorElements() const { return elements_; } + /// Get element values + double * getElements() { return elements_; } + /** Get pointer to int * vector of original postions. + If the packed vector has not been sorted then this + function returns the vector: 0, 1, 2, ..., size()-1. */ + const int * getOriginalPosition() const { return origIndices_; } + //@} + + //------------------------------------------------------------------- + // Set indices and elements + //------------------------------------------------------------------- + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator. <br> + <strong>NOTE</strong>: This operator keeps the current + <code>testForDuplicateIndex</code> setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVector &); + /** Assignment operator from a CoinPackedVectorBase. <br> + <strong>NOTE</strong>: This operator keeps the current + <code>testForDuplicateIndex</code> setting, and affter copying the data + it acts accordingly. */ + CoinPackedVector & operator=(const CoinPackedVectorBase & rhs); + + /** Assign the ownership of the arguments to this vector. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument indicates whether this vector will have + to be tested for duplicate indices. + */ + void assignVector(int size, int*& inds, double*& elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set vector size, indices, and elements. + Size is the length of both the indices and elements vectors. + The indices and elements vectors are copied into this class instance's + member data. The last argument specifies whether this vector will have + to be checked for duplicate indices whenever that can happen. */ + void setVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Elements set to have the same scalar value */ + void setConstant(int size, const int * inds, double elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1 */ + void setFull(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Indices are not specified and are taken to be 0,1,...,size-1, + but only where non zero*/ + void setFullNonZero(int size, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + + /** Set an existing element in the packed vector + The first argument is the "index" into the elements() array + */ + void setElement(int index, double element); + + /// Insert an element into the vector + void insert(int index, double element); + /// Append a CoinPackedVector to the end + void append(const CoinPackedVectorBase & caboose); + + /// Swap values in positions i and j of indices and elements + void swap(int i, int j); + + /** Resize the packed vector to be the first newSize elements. + Problem with truncate: what happens with origIndices_ ??? */ + void truncate(int newSize); + //@} + + /**@name Arithmetic operators. */ + //@{ + /// add <code>value</code> to every entry + void operator+=(double value); + /// subtract <code>value</code> from every entry + void operator-=(double value); + /// multiply every entry by <code>value</code> + void operator*=(double value); + /// divide every entry by <code>value</code> + void operator/=(double value); + //@} + + /**@name Sorting */ + //@{ + /** Sort the packed storage vector. + Typcical usages: + <pre> + packedVector.sort(CoinIncrIndexOrdered()); //increasing indices + packedVector.sort(CoinIncrElementOrdered()); // increasing elements + </pre> + */ + template <class CoinCompare3> + void sort(const CoinCompare3 & tc) + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + tc); } + + void sortIncrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstLess_3<int, int, double>()); } + + void sortDecrIndex() + { CoinSort_3(indices_, indices_ + nElements_, origIndices_, elements_, + CoinFirstGreater_3<int, int, double>()); } + + void sortIncrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstLess_3<double, int, int>()); } + + void sortDecrElement() + { CoinSort_3(elements_, elements_ + nElements_, origIndices_, indices_, + CoinFirstGreater_3<double, int, int>()); } + + + /** Sort in original order. + If the vector has been sorted, then this method restores + to its orignal sort order. + */ + void sortOriginalOrder(); + //@} + + /**@name Memory usage */ + //@{ + /** Reserve space. + If one knows the eventual size of the packed vector, + then it may be more efficient to reserve the space. + */ + void reserve(int n); + /** capacity returns the size which could be accomodated without + having to reallocate storage. + */ + int capacity() const { return capacity_; } + //@} + /**@name Constructors and destructors */ + //@{ + /** Default constructor */ + CoinPackedVector(bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor copies the vectors provided as parameters. + */ + CoinPackedVector(int size, const int * inds, const double * elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** \brief Alternate Constructors - set elements to vector of doubles + + This constructor takes ownership of the vectors passed as parameters. + \p inds and \p elems will be NULL on return. + */ + CoinPackedVector(int capacity, int size, int *&inds, double *&elems, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - set elements to same scalar value */ + CoinPackedVector(int size, const int * inds, double element, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Alternate Constructors - construct full storage with indices 0 through + size-1. */ + CoinPackedVector(int size, const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /** Copy constructor. */ + CoinPackedVector(const CoinPackedVector &); + /** Copy constructor <em>from a PackedVectorBase</em>. */ + CoinPackedVector(const CoinPackedVectorBase & rhs); + /** Destructor */ + virtual ~CoinPackedVector (); + //@} + +private: + /**@name Private methods */ + //@{ + /// Copy internal date + void gutsOfSetVector(int size, + const int * inds, const double * elems, + bool testForDuplicateIndex, + const char * method); + /// + void gutsOfSetConstant(int size, + const int * inds, double value, + bool testForDuplicateIndex, + const char * method); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + int * indices_; + ///Vector elements + double * elements_; + /// Size of indices and elements vectors + int nElements_; + /// original unsorted indices + int * origIndices_; + /// Amount of memory allocated for indices_, origIndices_, and elements_. + int capacity_; + //@} +}; + +//############################################################################# + +/**@name Arithmetic operators on packed vectors. + + <strong>NOTE</strong>: These methods operate on those positions where at + least one of the arguments has a value listed. At those positions the + appropriate operation is executed, Otherwise the result of the operation is + considered 0.<br> + <strong>NOTE 2</strong>: There are two kind of operators here. One is used + like "c = binaryOp(a, b)", the other is used like "binaryOp(c, a, b)", but + they are really the same. The first is much more natural to use, but it + involves the creation of a temporary object (the function *must* return an + object), while the second form puts the result directly into the argument + "c". Therefore, depending on the circumstances, the second form can be + significantly faster. + */ +//@{ +template <class BinaryFunction> void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + retVal.clear(); + const int s = op1.getNumElements(); + if (s > 0) { + retVal.reserve(s); + const int * inds = op1.getIndices(); + const double * elems = op1.getElements(); + for (int i=0; i<s; ++i ) { + retVal.insert(inds[i], bf(value, elems[i])); + } + } +} + +template <class BinaryFunction> inline void +binaryOp(CoinPackedVector& retVal, + double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + binaryOp(retVal, op2, value, bf); +} + +template <class BinaryFunction> void +binaryOp(CoinPackedVector& retVal, + const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + retVal.clear(); + const int s1 = op1.getNumElements(); + const int s2 = op2.getNumElements(); +/* + Replaced || with &&, in response to complaint from Sven deVries, who + rightly points out || is not appropriate for additive operations. && + should be ok as long as binaryOp is understood not to create something + from nothing. -- lh, 04.06.11 +*/ + if (s1 == 0 && s2 == 0) + return; + + retVal.reserve(s1+s2); + + const int * inds1 = op1.getIndices(); + const double * elems1 = op1.getElements(); + const int * inds2 = op2.getIndices(); + const double * elems2 = op2.getElements(); + + int i; + // loop once for each element in op1 + for ( i=0; i<s1; ++i ) { + const int index = inds1[i]; + const int pos2 = op2.findIndex(index); + const double val = bf(elems1[i], pos2 == -1 ? 0.0 : elems2[pos2]); + // if (val != 0.0) // *THINK* : should we put in only nonzeros? + retVal.insert(index, val); + } + // loop once for each element in operand2 + for ( i=0; i<s2; ++i ) { + const int index = inds2[i]; + // if index exists in op1, then element was processed in prior loop + if ( op1.isExistingIndex(index) ) + continue; + // Index does not exist in op1, so the element value must be zero + const double val = bf(0.0, elems2[i]); + // if (val != 0.0) // *THINK* : should we put in only nonzeros? + retVal.insert(index, val); + } +} + +//----------------------------------------------------------------------------- + +template <class BinaryFunction> CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, double value, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, value, bf); + return retVal; +} + +template <class BinaryFunction> CoinPackedVector +binaryOp(double value, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op2, value, bf); + return retVal; +} + +template <class BinaryFunction> CoinPackedVector +binaryOp(const CoinPackedVectorBase& op1, const CoinPackedVectorBase& op2, + BinaryFunction bf) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, bf); + return retVal; +} + +//----------------------------------------------------------------------------- +/// Return the sum of two packed vectors +inline CoinPackedVector operator+(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::plus<double>()); + return retVal; +} + +/// Return the difference of two packed vectors +inline CoinPackedVector operator-(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::minus<double>()); + return retVal; +} + +/// Return the element-wise product of two packed vectors +inline CoinPackedVector operator*(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::multiplies<double>()); + return retVal; +} + +/// Return the element-wise ratio of two packed vectors +inline CoinPackedVector operator/(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2) +{ + CoinPackedVector retVal; + retVal.setTestForDuplicateIndex(true); + binaryOp(retVal, op1, op2, std::divides<double>()); + return retVal; +} +//@} + +/// Returns the dot product of two CoinPackedVector objects whose elements are +/// doubles. Use this version if the vectors are *not* guaranteed to be sorted. +inline double sparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int len, i; + double acc = 0.0; + CoinPackedVector retVal; + + CoinPackedVector retval = op1*op2; + len = retval.getNumElements(); + double * CParray = retval.getElements(); + + for(i = 0; i < len; i++){ + acc += CParray[i]; + } +return acc; +} + + +/// Returns the dot product of two sorted CoinPackedVector objects. +/// The vectors should be sorted in ascending order of indices. +inline double sortedSparseDotProduct(const CoinPackedVectorBase& op1, + const CoinPackedVectorBase& op2){ + int i, j, len1, len2; + double acc = 0.0; + + const double* v1val = op1.getElements(); + const double* v2val = op2.getElements(); + const int* v1ind = op1.getIndices(); + const int* v2ind = op2.getIndices(); + + len1 = op1.getNumElements(); + len2 = op2.getNumElements(); + + i = 0; + j = 0; + + while(i < len1 && j < len2){ + if(v1ind[i] == v2ind[j]){ + acc += v1val[i] * v2val[j]; + i++; + j++; + } + else if(v2ind[j] < v1ind[i]){ + j++; + } + else{ + i++; + } // end if-else-elseif + } // end while + return acc; + } + + +//----------------------------------------------------------------------------- + +/**@name Arithmetic operators on packed vector and a constant. <br> + These functions create a packed vector as a result. That packed vector will + have the same indices as <code>op1</code> and the specified operation is + done entry-wise with the given value. */ +//@{ +/// Return the sum of a packed vector and a constant +inline CoinPackedVector +operator+(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a packed vector and a constant +inline CoinPackedVector +operator-(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal -= value; + return retVal; +} + +/// Return the element-wise product of a packed vector and a constant +inline CoinPackedVector +operator*(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a packed vector and a constant +inline CoinPackedVector +operator/(const CoinPackedVectorBase& op1, double value) +{ + CoinPackedVector retVal(op1); + retVal /= value; + return retVal; +} + +//----------------------------------------------------------------------------- + +/// Return the sum of a constant and a packed vector +inline CoinPackedVector +operator+(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal += value; + return retVal; +} + +/// Return the difference of a constant and a packed vector +inline CoinPackedVector +operator-(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value - elems[i]; + } + return retVal; +} + +/// Return the element-wise product of a constant and a packed vector +inline CoinPackedVector +operator*(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + retVal *= value; + return retVal; +} + +/// Return the element-wise ratio of a a constant and packed vector +inline CoinPackedVector +operator/(double value, const CoinPackedVectorBase& op1) +{ + CoinPackedVector retVal(op1); + const int size = retVal.getNumElements(); + double* elems = retVal.getElements(); + for (int i = 0; i < size; ++i) { + elems[i] = value / elems[i]; + } + return retVal; +} +//@} + +//############################################################################# +/** A function that tests the methods in the CoinPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPackedVectorBase.hpp b/thirdparty/linux/include/coin1/CoinPackedVectorBase.hpp new file mode 100644 index 0000000..dccc1cd --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPackedVectorBase.hpp @@ -0,0 +1,269 @@ +/* $Id: CoinPackedVectorBase.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPackedVectorBase_H +#define CoinPackedVectorBase_H + +#include <set> +#include <map> +#include "CoinPragma.hpp" +#include "CoinError.hpp" + +class CoinPackedVector; + +/** Abstract base class for various sparse vectors. + + Since this class is abstract, no object of this type can be created. The + sole purpose of this class is to provide access to a <em>constant</em> + packed vector. All members of this class are const methods, they can't + change the object. */ + +class CoinPackedVectorBase { + +public: + /**@name Virtual methods that the derived classes must provide */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const = 0; + /// Get indices of elements + virtual const int * getIndices() const = 0; + /// Get element values + virtual const double * getElements() const = 0; + //@} + + /**@name Methods related to whether duplicate-index checking is performed. + + If the checking for duplicate indices is turned off, then + some CoinPackedVector methods may not work correctly if there + are duplicate indices. + Turning off the checking for duplicate indices may result in + better run time performance. + */ + //@{ + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur. + + Calling this method with \p test set to true will trigger an immediate + check for duplicate indices. + */ + void setTestForDuplicateIndex(bool test) const; + /** \brief Set to the argument value whether to test for duplicate indices + in the vector whenever they can occur BUT we know that right + now the vector has no duplicate indices. + + Calling this method with \p test set to true will <em>not</em> trigger + an immediate check for duplicate indices; instead, it's assumed that + the result of the test will be true. + */ + void setTestForDuplicateIndexWhenTrue(bool test) const; + /** Returns true if the vector should be tested for duplicate indices when + they can occur. */ + bool testForDuplicateIndex() const { return testForDuplicateIndex_; } + /// Just sets test stuff false without a try etc + inline void setTestsOff() const + { testForDuplicateIndex_=false; testedDuplicateIndex_=false;} + //@} + + /**@name Methods for getting info on the packed vector as a full vector */ + //@{ + /** Get the vector as a dense vector. The argument specifies how long this + dense vector is. <br> + <strong>NOTE</strong>: The user needs to <code>delete[]</code> this + pointer after it's not needed anymore. + */ + double * denseVector(int denseSize) const; + /** Access the i'th element of the full storage vector. + If the i'th is not stored, then zero is returned. The initial use of + this method has some computational and storage overhead associated with + it.<br> + <strong>NOTE</strong>: This is <em>very</em> expensive. It is probably + much better to use <code>denseVector()</code>. + */ + double operator[](int i) const; + //@} + + /**@name Index methods */ + //@{ + /// Get value of maximum index + int getMaxIndex() const; + /// Get value of minimum index + int getMinIndex() const; + + /// Throw an exception if there are duplicate indices + void duplicateIndex(const char* methodName = NULL, + const char * className = NULL) const; + + /** Return true if the i'th element of the full storage vector exists in + the packed storage vector.*/ + bool isExistingIndex(int i) const; + + /** Return the position of the i'th element of the full storage vector. + If index does not exist then -1 is returned */ + int findIndex(int i) const; + + //@} + + /**@name Comparison operators on two packed vectors */ + //@{ + /** Equal. Returns true if vectors have same length and corresponding + element of each vector is equal. */ + bool operator==(const CoinPackedVectorBase & rhs) const; + /// Not equal + bool operator!=(const CoinPackedVectorBase & rhs) const; + +#if 0 + // LL: This should be implemented eventually. It is useful to have. + /** Lexicographic comparisons of two packed vectors. Returns + negative/0/positive depending on whether \c this is + smaller/equal.greater than \c rhs */ + int lexCompare(const CoinPackedVectorBase& rhs); +#endif + + /** This method establishes an ordering on packed vectors. It is complete + ordering, but not the same as lexicographic ordering. However, it is + quick and dirty to compute and thus it is useful to keep packed vectors + in a heap when all we care is to quickly check whether a particular + vector is already in the heap or not. Returns negative/0/positive + depending on whether \c this is smaller/equal.greater than \c rhs. */ + int compare(const CoinPackedVectorBase& rhs) const; + + /** equivalent - If shallow packed vector A & B are equivalent, then they + are still equivalent no matter how they are sorted. + In this method the FloatEqual function operator can be specified. The + default equivalence test is that the entries are relatively equal.<br> + <strong>NOTE</strong>: This is a relatively expensive method as it + sorts the two shallow packed vectors. + */ + template <class FloatEqual> bool + isEquivalent(const CoinPackedVectorBase& rhs, const FloatEqual& eq) const + { + if (getNumElements() != rhs.getNumElements()) + return false; + + duplicateIndex("equivalent", "CoinPackedVector"); + rhs.duplicateIndex("equivalent", "CoinPackedVector"); + + std::map<int,double> mv; + const int * inds = getIndices(); + const double * elems = getElements(); + int i; + for ( i = getNumElements() - 1; i >= 0; --i) { + mv.insert(std::make_pair(inds[i], elems[i])); + } + + std::map<int,double> mvRhs; + inds = rhs.getIndices(); + elems = rhs.getElements(); + for ( i = getNumElements() - 1; i >= 0; --i) { + mvRhs.insert(std::make_pair(inds[i], elems[i])); + } + + std::map<int,double>::const_iterator mvI = mv.begin(); + std::map<int,double>::const_iterator mvIlast = mv.end(); + std::map<int,double>::const_iterator mvIrhs = mvRhs.begin(); + while (mvI != mvIlast) { + if (mvI->first != mvIrhs->first || ! eq(mvI->second, mvIrhs->second)) + return false; + ++mvI; + ++mvIrhs; + } + return true; + } + + bool isEquivalent(const CoinPackedVectorBase& rhs) const; + //@} + + + /**@name Arithmetic operators. */ + //@{ + /// Create the dot product with a full vector + double dotProduct(const double* dense) const; + + /// Return the 1-norm of the vector + double oneNorm() const; + + /// Return the square of the 2-norm of the vector + double normSquare() const; + + /// Return the 2-norm of the vector + double twoNorm() const; + + /// Return the infinity-norm of the vector + double infNorm() const; + + /// Sum elements of vector. + double sum() const; + //@} + +protected: + + /**@name Constructors, destructor + <strong>NOTE</strong>: All constructors are protected. There's no need + to expose them, after all, this is an abstract class. */ + //@{ + /** Default constructor. */ + CoinPackedVectorBase(); + +public: + /** Destructor */ + virtual ~CoinPackedVectorBase(); + //@} + +private: + /**@name Disabled methods */ + //@{ + /** The copy constructor. <br> + This must be at least protected, but we make it private. The reason is + that when, say, a shallow packed vector is created, first the + underlying class, it this one is constructed. However, at that point we + don't know how much of the data members of this class we need to copy + over. Therefore the copy constructor is not used. */ + CoinPackedVectorBase(const CoinPackedVectorBase&); + /** This class provides <em>const</em> access to packed vectors, so there's + no need to provide an assignment operator. */ + CoinPackedVectorBase& operator=(const CoinPackedVectorBase&); + //@} + +protected: + + /**@name Protected methods */ + //@{ + /// Find Maximum and Minimum Indices + void findMaxMinIndices() const; + + /// Return indexSetPtr_ (create it if necessary). + std::set<int> * indexSet(const char* methodName = NULL, + const char * className = NULL) const; + + /// Delete the indexSet + void clearIndexSet() const; + void clearBase() const; + void copyMaxMinIndex(const CoinPackedVectorBase & x) const { + maxIndex_ = x.maxIndex_; + minIndex_ = x.minIndex_; + } + //@} + +private: + /**@name Protected member data */ + //@{ + /// Contains max index value or -infinity + mutable int maxIndex_; + /// Contains minimum index value or infinity + mutable int minIndex_; + /** Store the indices in a set. This set is only created if it is needed. + Its primary use is testing for duplicate indices. + */ + mutable std::set<int> * indexSetPtr_; + /** True if the vector should be tested for duplicate indices when they can + occur. */ + mutable bool testForDuplicateIndex_; + /** True if the vector has already been tested for duplicate indices. Most + of the operations in CoinPackedVector preserves this flag. */ + mutable bool testedDuplicateIndex_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinParam.hpp b/thirdparty/linux/include/coin1/CoinParam.hpp new file mode 100644 index 0000000..30cccc2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinParam.hpp @@ -0,0 +1,644 @@ +/* $Id: CoinParam.hpp 1493 2011-11-01 16:56:07Z tkr $ */ +#ifndef CoinParam_H +#define CoinParam_H + +/* + Copyright (C) 2002, International Business Machines + Corporation and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinParam.hpp + \brief Declaration of a class for command line parameters. +*/ + +#include <vector> +#include <string> +#include <cstdio> + +/*! \class CoinParam + \brief A base class for `keyword value' command line parameters. + + The underlying paradigm is that a parameter specifies an action to be + performed on a target object. The base class provides two function + pointers, a `push' function and a `pull' function. By convention, a push + function will set some value in the target object or perform some action + using the target object. A `pull' function will retrieve some value from + the target object. This is only a convention, however; CoinParam and + associated utilities make no use of these functions and have no hardcoded + notion of how they should be used. + + The action to be performed, and the target object, will be specific to a + particular application. It is expected that users will derive + application-specific parameter classes from this base class. A derived + class will typically add fields and methods to set/get a code for the + action to be performed (often, an enum class) and the target object (often, + a pointer or reference). + + Facilities provided by the base class and associated utility routines + include: + <ul> + <li> Support for common parameter types with numeric, string, or + keyword values. + <li> Support for short and long help messages. + <li> Pointers to `push' and `pull' functions as described above. + <li> Command line parsing and keyword matching. + </ul> + All utility routines are declared in the #CoinParamUtils namespace. + + The base class recognises five types of parameters: actions (which require + no value); numeric parameters with integer or real (double) values; keyword + parameters, where the value is one of a defined set of value-keywords; + and string parameters (where the value is a string). + The base class supports the definition of a valid range, a default value, + and short and long help messages for a parameter. + + As defined by the #CoinParamFunc typedef, push and pull functions + should take a single parameter, a pointer to a CoinParam. Typically this + object will actually be a derived class as described above, and the + implementation function will have access to all capabilities of CoinParam and + of the derived class. + + When specified as command line parameters, the expected syntax is `-keyword + value' or `-keyword=value'. You can also use the Gnu double-dash style, + `--keyword'. Spaces around the `=' will \e not work. + + The keyword (name) for a parameter can be defined with an `!' to mark the + minimal match point. For example, allow!ableGap will be considered matched + by the strings `allow', `allowa', `allowab', \e etc. Similarly, the + value-keyword strings for keyword parameters can be defined with `!' to + mark the minimal match point. Matching of keywords and value-keywords is + \e not case sensitive. +*/ + +class CoinParam +{ + +public: + +/*! \name Subtypes */ +//@{ + + /*! \brief Enumeration for the types of parameters supported by CoinParam + + CoinParam provides support for several types of parameters: + <ul> + <li> Action parameters, which require no value. + <li> Integer and double numeric parameters, with upper and lower bounds. + <li> String parameters that take an arbitrary string value. + <li> Keyword parameters that take a defined set of string (value-keyword) + values. Value-keywords are associated with integers in the order in + which they are added, starting from zero. + </ul> + */ + typedef enum { coinParamInvalid = 0, + coinParamAct, coinParamInt, coinParamDbl, + coinParamStr, coinParamKwd } CoinParamType ; + + /*! \brief Type declaration for push and pull functions. + + By convention, a return code of 0 indicates execution without error, >0 + indicates nonfatal error, and <0 indicates fatal error. This is only + convention, however; the base class makes no use of the push and pull + functions and has no hardcoded interpretation of the return code. + */ + typedef int (*CoinParamFunc)(CoinParam *param) ; + +//@} + +/*! \name Constructors and Destructors + + Be careful how you specify parameters for the constructors! Some compilers + are entirely too willing to convert almost anything to bool. +*/ +//@{ + + /*! \brief Default constructor */ + + CoinParam() ; + + /*! \brief Constructor for a parameter with a double value + + The default value is 0.0. Be careful to clearly indicate that \p lower and + \p upper are real (double) values to distinguish this constructor from the + constructor for an integer parameter. + */ + CoinParam(std::string name, std::string help, + double lower, double upper, double dflt = 0.0, + bool display = true) ; + + /*! \brief Constructor for a parameter with an integer value + + The default value is 0. + */ + CoinParam(std::string name, std::string help, + int lower, int upper, int dflt = 0, + bool display = true) ; + + /*! \brief Constructor for a parameter with keyword values + + The string supplied as \p firstValue becomes the first value-keyword. + Additional value-keywords can be added using appendKwd(). It's necessary + to specify both the first value-keyword (\p firstValue) and the default + value-keyword index (\p dflt) in order to distinguish this constructor + from the constructors for string and action parameters. + + Value-keywords are associated with an integer, starting with zero and + increasing as each keyword is added. The value-keyword given as \p + firstValue will be associated with the integer zero. The integer supplied + for \p dflt can be any value, as long as it will be valid once all + value-keywords have been added. + */ + CoinParam(std::string name, std::string help, + std::string firstValue, int dflt, bool display = true) ; + + /*! \brief Constructor for a string parameter + + For some compilers, the default value (\p dflt) must be specified + explicitly with type std::string to distinguish the constructor for a + string parameter from the constructor for an action parameter. For + example, use std::string("default") instead of simply "default", or use a + variable of type std::string. + */ + CoinParam(std::string name, std::string help, + std::string dflt, bool display = true) ; + + /*! \brief Constructor for an action parameter */ + + CoinParam(std::string name, std::string help, + bool display = true) ; + + /*! \brief Copy constructor */ + + CoinParam(const CoinParam &orig) ; + + /*! \brief Clone */ + + virtual CoinParam *clone() ; + + /*! \brief Assignment */ + + CoinParam &operator=(const CoinParam &rhs) ; + + /*! \brief Destructor */ + + virtual ~CoinParam() ; + +//@} + +/*! \name Methods to query and manipulate the value(s) of a parameter */ +//@{ + + /*! \brief Add an additional value-keyword to a keyword parameter */ + + void appendKwd(std::string kwd) ; + + /*! \brief Return the integer associated with the specified value-keyword + + Returns -1 if no value-keywords match the specified string. + */ + int kwdIndex(std::string kwd) const ; + + /*! \brief Return the value-keyword that is the current value of the + keyword parameter + */ + std::string kwdVal() const ; + + /*! \brief Set the value of the keyword parameter using the integer + associated with a value-keyword. + + If \p printIt is true, the corresponding value-keyword string will be + echoed to std::cout. + */ + void setKwdVal(int value, bool printIt = false) ; + + /*! \brief Set the value of the keyword parameter using a value-keyword + string. + + The given string will be tested against the set of value-keywords for + the parameter using the shortest match rules. + */ + void setKwdVal(const std::string value ) ; + + /*! \brief Prints the set of value-keywords defined for this keyword + parameter + */ + void printKwds() const ; + + + /*! \brief Set the value of a string parameter */ + + void setStrVal(std::string value) ; + + /*! \brief Get the value of a string parameter */ + + std::string strVal() const ; + + + /*! \brief Set the value of a double parameter */ + + void setDblVal(double value) ; + + /*! \brief Get the value of a double parameter */ + + double dblVal() const ; + + + /*! \brief Set the value of a integer parameter */ + + void setIntVal(int value) ; + + /*! \brief Get the value of a integer parameter */ + + int intVal() const ; + + + /*! \brief Add a short help string to a parameter */ + + inline void setShortHelp(const std::string help) { shortHelp_ = help ; } + + /*! \brief Retrieve the short help string */ + + inline std::string shortHelp() const { return (shortHelp_) ; } + + /*! \brief Add a long help message to a parameter + + See printLongHelp() for a description of how messages are broken into + lines. + */ + inline void setLongHelp(const std::string help) { longHelp_ = help ; } + + /*! \brief Retrieve the long help message */ + + inline std::string longHelp() const { return (longHelp_) ; } + + /*! \brief Print long help + + Prints the long help string, plus the valid range and/or keywords if + appropriate. The routine makes a best effort to break the message into + lines appropriate for an 80-character line. Explicit line breaks in the + message will be observed. The short help string will be used if + long help is not available. + */ + void printLongHelp() const ; + +//@} + +/*! \name Methods to query and manipulate a parameter object */ +//@{ + + /*! \brief Return the type of the parameter */ + + inline CoinParamType type() const { return (type_) ; } + + /*! \brief Set the type of the parameter */ + + inline void setType(CoinParamType type) { type_ = type ; } + + /*! \brief Return the parameter keyword (name) string */ + + inline std::string name() const { return (name_) ; } + + /*! \brief Set the parameter keyword (name) string */ + + inline void setName(std::string name) { name_ = name ; processName() ; } + + /*! \brief Check if the specified string matches the parameter keyword (name) + string + + Returns 1 if the string matches and meets the minimum match length, + 2 if the string matches but doesn't meet the minimum match length, + and 0 if the string doesn't match. Matches are \e not case-sensitive. + */ + int matches (std::string input) const ; + + /*! \brief Return the parameter keyword (name) string formatted to show + the minimum match length + + For example, if the parameter name was defined as allow!ableGap, the + string returned by matchName would be allow(ableGap). + */ + std::string matchName() const ; + + /*! \brief Set visibility of parameter + + Intended to control whether the parameter is shown when a list of + parameters is processed. Used by CoinParamUtils::printHelp when printing + help messages for a list of parameters. + */ + inline void setDisplay(bool display) { display_ = display ; } + + /*! \brief Get visibility of parameter */ + + inline bool display() const { return (display_) ; } + + /*! \brief Get push function */ + + inline CoinParamFunc pushFunc() { return (pushFunc_) ; } + + /*! \brief Set push function */ + + inline void setPushFunc(CoinParamFunc func) { pushFunc_ = func ; } + + /*! \brief Get pull function */ + + inline CoinParamFunc pullFunc() { return (pullFunc_) ; } + + /*! \brief Set pull function */ + + inline void setPullFunc(CoinParamFunc func) { pullFunc_ = func ; } + +//@} + +private: + +/*! \name Private methods */ +//@{ + + /*! Process a name for efficient matching */ + void processName() ; + +//@} + +/*! \name Private parameter data */ +//@{ + /// Parameter type (see #CoinParamType) + CoinParamType type_ ; + + /// Parameter name + std::string name_ ; + + /// Length of parameter name + size_t lengthName_ ; + + /*! \brief Minimum length required to declare a match for the parameter + name. + */ + size_t lengthMatch_ ; + + /// Lower bound on value for a double parameter + double lowerDblValue_ ; + + /// Upper bound on value for a double parameter + double upperDblValue_ ; + + /// Double parameter - current value + double dblValue_ ; + + /// Lower bound on value for an integer parameter + int lowerIntValue_ ; + + /// Upper bound on value for an integer parameter + int upperIntValue_ ; + + /// Integer parameter - current value + int intValue_ ; + + /// String parameter - current value + std::string strValue_ ; + + /// Set of valid value-keywords for a keyword parameter + std::vector<std::string> definedKwds_ ; + + /*! \brief Current value for a keyword parameter (index into #definedKwds_) + */ + int currentKwd_ ; + + /// Push function + CoinParamFunc pushFunc_ ; + + /// Pull function + CoinParamFunc pullFunc_ ; + + /// Short help + std::string shortHelp_ ; + + /// Long help + std::string longHelp_ ; + + /// Display when processing lists of parameters? + bool display_ ; +//@} + +} ; + +/*! \relatesalso CoinParam + \brief A type for a parameter vector. +*/ +typedef std::vector<CoinParam*> CoinParamVec ; + +/*! \relatesalso CoinParam + \brief A stream output function for a CoinParam object. +*/ +std::ostream &operator<< (std::ostream &s, const CoinParam ¶m) ; + +/* + Bring in the utility functions for parameter handling (CbcParamUtils). +*/ + +/*! \brief Utility functions for processing CoinParam parameters. + + The functions in CoinParamUtils support command line or interactive + parameter processing and a help facility. Consult the `Related Functions' + section of the CoinParam class documentation for individual function + documentation. +*/ +namespace CoinParamUtils { + /*! \relatesalso CoinParam + \brief Take command input from the file specified by src. + + Use stdin for \p src to specify interactive prompting for commands. + */ + void setInputSrc(FILE *src) ; + + /*! \relatesalso CoinParam + \brief Returns true if command line parameters are being processed. + */ + bool isCommandLine() ; + + /*! \relatesalso CoinParam + \brief Returns true if parameters are being obtained from stdin. + */ + bool isInteractive() ; + + /*! \relatesalso CoinParam + \brief Attempt to read a string from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a string is parsed + without error, 2 if no field is present. + */ + std::string getStringField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read an integer from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if an integer is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + int getIntField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Attempt to read a real (double) from the input. + + \p argc and \p argv are used only if isCommandLine() would return true. + If \p valid is supplied, it will be set to 0 if a real number is parsed + without error, 1 if there's a parse error, and 2 if no field is present. + */ + double getDoubleField(int argc, const char *argv[], int *valid) ; + + /*! \relatesalso CoinParam + \brief Scan a parameter vector for parameters whose keyword (name) string + matches \p name using minimal match rules. + + \p matchNdx is set to the index of the last parameter that meets the + minimal match criteria (but note there should be at most one matching + parameter if the parameter vector is properly configured). \p shortCnt + is set to the number of short matches (should be zero for a properly + configured parameter vector if a minimal match is found). The return + value is the number of matches satisfying the minimal match requirement + (should be 0 or 1 in a properly configured vector). + */ + int matchParam(const CoinParamVec ¶mVec, std::string name, + int &matchNdx, int &shortCnt) ; + + /*! \relatesalso CoinParam + \brief Get the next command keyword (name) + + To be precise, return the next field from the current command input + source, after a bit of processing. In command line mode (isCommandLine() + returns true) the next field will normally be of the form `-keyword' or + `--keyword' (\e i.e., a parameter keyword), and the string returned would + be `keyword'. In interactive mode (isInteractive() returns true), the + user will be prompted if necessary. It is assumed that the user knows + not to use the `-' or `--' prefixes unless specifying parameters on the + command line. + + There are a number of special cases if we're in command line mode. The + order of processing of the raw string goes like this: + <ul> + <li> A stand-alone `-' is forced to `stdin'. + <li> A stand-alone '--' is returned as a word; interpretation is up to + the client. + <li> A prefix of '-' or '--' is stripped from the string. + </ul> + If the result is the string `stdin', command processing shifts to + interactive mode and the user is immediately prompted for a new command. + + Whatever results from the above sequence is returned to the user as the + return value of the function. An empty string indicates end of input. + + \p prompt will be used only if it's necessary to prompt the user in + interactive mode. + */ + + std::string getCommand(int argc, const char *argv[], + const std::string prompt, std::string *pfx = 0) ; + + /*! \relatesalso CoinParam + \brief Look up the command keyword (name) in the parameter vector. + Print help if requested. + + In the most straightforward use, \p name is a string without `?', and the + value returned is the index in \p paramVec of the single parameter that + matched \p name. One or more '?' characters at the end of \p name is a + query for information. The routine prints short (one '?') or long (more + than one '?') help messages for a query. Help is also printed in the case + where the name is ambiguous (some of the matches did not meet the minimal + match length requirement). + + Note that multiple matches meeting the minimal match requirement is a + configuration error. The mimimal match length for the parameters + involved is too short. + + If provided as parameters, on return + <ul> + <li> \p matchCnt will be set to the number of matches meeting the + minimal match requirement + <li> \p shortCnt will be set to the number of matches that did not + meet the miminal match requirement + <li> \p queryCnt will be set to the number of '?' characters at the + end of the name + </ul> + + The return values are: + <ul> + <li> >0: index in \p paramVec of the single unique match for \p name + <li> -1: a query was detected (one or more '?' characters at the end + of \p name + <li> -2: one or more short matches, not a query + <li> -3: no matches, not a query + <li> -4: multiple matches meeting the minimal match requirement + (configuration error) + </ul> + */ + int lookupParam(std::string name, CoinParamVec ¶mVec, + int *matchCnt = 0, int *shortCnt = 0, int *queryCnt = 0) ; + + /*! \relatesalso CoinParam + \brief Utility to print a long message as filled lines of text + + The routine makes a best effort to break lines without exceeding the + standard 80 character line length. Explicit newlines in \p msg will + be obeyed. + */ + void printIt(const char *msg) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given a short match or explicit + request for help. + + The two really are related, in that a query (a string that ends with + one or more `?' characters) will often result in a short match. The + routine expects that \p name matches a single parameter, and does not + look for multiple matches. + + If called with \p matchNdx < 0, the routine will look up \p name in \p + paramVec and print the full name from the parameter. If called with \p + matchNdx > 0, it just prints the name from the specified parameter. If + the name is a query, short (one '?') or long (more than one '?') help + is printed. + + */ void shortOrHelpOne(CoinParamVec ¶mVec,int matchNdx, std::string + name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help given multiple matches. + + If the name is not a query, or asks for short help (\e i.e., contains + zero or one '?' characters), the list of matching names is printed. If + the name asks for long help (contains two or more '?' characters), + short help is printed for each matching name. + */ + void shortOrHelpMany(CoinParamVec ¶mVec, + std::string name, int numQuery) ; + + /*! \relatesalso CoinParam + \brief Print a generic `how to use the command interface' help message. + + The message is hard coded to match the behaviour of the parsing utilities. + */ + void printGenericHelp() ; + + /*! \relatesalso CoinParam + \brief Utility routine to print help messages for one or more + parameters. + + Intended as a utility to implement explicit `help' commands. Help will be + printed for all parameters in \p paramVec from \p firstParam to \p + lastParam, inclusive. If \p shortHelp is true, short help messages will + be printed. If \p longHelp is true, long help messages are printed. \p + shortHelp overrules \p longHelp. If neither is true, only command + keywords are printed. \p prefix is printed before each line; it's an + imperfect attempt at indentation. + */ + void printHelp(CoinParamVec ¶mVec, int firstParam, int lastParam, + std::string prefix, + bool shortHelp, bool longHelp, bool hidden) ; +} + + +#endif /* CoinParam_H */ + diff --git a/thirdparty/linux/include/coin1/CoinPragma.hpp b/thirdparty/linux/include/coin1/CoinPragma.hpp new file mode 100644 index 0000000..b9f8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPragma.hpp @@ -0,0 +1,26 @@ +/* $Id: CoinPragma.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPragma_H +#define CoinPragma_H + +//------------------------------------------------------------------- +// +// This is a file which can contain Pragma's that are +// generally applicable to any source file. +// +//------------------------------------------------------------------- + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +// Turn off compiler warning: +// "empty controlled statement found; is this the intent?" +# pragma warning(disable:4390) +// Turn off compiler warning about deprecated functions +# pragma warning(disable:4996) +#endif + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveDoubleton.hpp b/thirdparty/linux/include/coin1/CoinPresolveDoubleton.hpp new file mode 100644 index 0000000..3ad8cd2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveDoubleton.hpp @@ -0,0 +1,73 @@ +/* $Id: CoinPresolveDoubleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDoubleton_H +#define CoinPresolveDoubleton_H + +#define DOUBLETON 5 + +/*! \class doubleton_action + \brief Solve ax+by=c for y and substitute y out of the problem. + + This moves the bounds information for y onto x, making y free and allowing + us to substitute it away. + \verbatim + a x + b y = c + l1 <= x <= u1 + l2 <= y <= u2 ==> + + l2 <= (c - a x) / b <= u2 + b/-a > 0 ==> (b l2 - c) / -a <= x <= (b u2 - c) / -a + b/-a < 0 ==> (b u2 - c) / -a <= x <= (b l2 - c) / -a + \endverbatim +*/ +class doubleton_action : public CoinPresolveAction { + public: + struct action { + + double clox; + double cupx; + double costx; + + double costy; + + double rlo; + + double coeffx; + double coeffy; + + double *colel; + + int icolx; + int icoly; + int row; + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("doubleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~doubleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin1/CoinPresolveDual.hpp b/thirdparty/linux/include/coin1/CoinPresolveDual.hpp new file mode 100644 index 0000000..b021ce0 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveDual.hpp @@ -0,0 +1,85 @@ +/* $Id: CoinPresolveDual.hpp 1510 2011-12-08 23:56:01Z lou $ */ + +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDual_H +#define CoinPresolveDual_H + +/*! \class remove_dual_action + \brief Attempt to fix variables by bounding reduced costs + + The reduced cost of x_j is d_j = c_j - y*a_j (1). Assume minimization, + so that at optimality d_j >= 0 for x_j nonbasic at lower bound, and + d_j <= 0 for x_j nonbasic at upper bound. + + For a slack variable s_i, c_(n+i) = 0 and a_(n+i) is a unit vector, hence + d_(n+i) = -y_i. If s_i has a finite lower bound and no upper bound, we + must have y_i <= 0 at optimality. Similarly, if s_i has no lower bound and a + finite upper bound, we must have y_i >= 0. + + For a singleton variable x_j, d_j = c_j - y_i*a_ij. Given x_j with a + single finite bound, we can bound d_j greater or less than 0 at + optimality, and that allows us to calculate an upper or lower bound on y_i + (depending on the bound on d_j and the sign of a_ij). + + Now we have bounds on some subset of the y_i, and we can use these to + calculate upper and lower bounds on the d_j, using bound propagation on + (1). If we can manage to bound some d_j as strictly positive or strictly + negative, then at optimality the corresponding variable must be nonbasic + at its lower or upper bound, respectively. If the required bound is lacking, + the problem is unbounded. +*/ + +class remove_dual_action : public CoinPresolveAction { + + public: + + /// Destructor + ~remove_dual_action () ; + + /// Name + inline const char *name () const { return ("remove_dual_action") ; } + + /*! \brief Attempt to fix variables by bounding reduced costs + + Always scans all variables. Propagates bounds on reduced costs until there's + no change or until some set of variables can be fixed. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + /*! \brief Postsolve + + In addition to fixing variables (handled by make_fixed_action), we may + need use our own postsolve to restore constraint bounds. + */ + void postsolve (CoinPostsolveMatrix *prob) const ; + + private: + + /// Postsolve (bound restore) instruction + struct action { + double rlo_ ; ///< restored row lower bound + double rup_ ; ///< restored row upper bound + int ndx_ ; ///< row index + } ; + + /// Constructor with postsolve actions. + remove_dual_action(int nactions, const action *actions, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + /// Count of bound restore entries + const int nactions_ ; + /// Bound restore entries + const action *actions_ ; + +} ; +#endif + + diff --git a/thirdparty/linux/include/coin1/CoinPresolveDupcol.hpp b/thirdparty/linux/include/coin1/CoinPresolveDupcol.hpp new file mode 100644 index 0000000..16d3c91 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveDupcol.hpp @@ -0,0 +1,226 @@ +/* $Id: CoinPresolveDupcol.hpp 1817 2015-03-22 16:43:28Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveDupcol_H +#define CoinPresolveDupcol_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define DUPCOL 10 + +/*! \class dupcol_action + \brief Detect and remove duplicate columns + + The general technique is to sum the coefficients a_(*,j) of each column. + Columns with identical sums are duplicates. The obvious problem is that, + <i>e.g.</i>, [1 0 1 0] and [0 1 0 1] both add to 2. To minimize the + chances of false positives, the coefficients of each row are multipled by + a random number r_i, so that we sum r_i*a_ij. + + Candidate columns are checked to confirm they are identical. Where the + columns have the same objective coefficient, the two are combined. If the + columns have different objective coefficients, complications ensue. In order + to remove the duplicate, it must be possible to fix the variable at a bound. +*/ + +class dupcol_action : public CoinPresolveAction { + dupcol_action(); + dupcol_action(const dupcol_action& rhs); + dupcol_action& operator=(const dupcol_action& rhs); + + struct action { + double thislo; + double thisup; + double lastlo; + double lastup; + int ithis; + int ilast; + + double *colels; + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + dupcol_action(int nactions, const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~dupcol_action(); + +}; + + +/*! \class duprow_action + \brief Detect and remove duplicate rows + + The algorithm to detect duplicate rows is as outlined for dupcol_action. + + If the feasible interval for one constraint is strictly contained in the + other, the tighter (contained) constraint is kept. If the feasible + intervals are disjoint, the problem is infeasible. If the feasible + intervals overlap, both constraints are kept. + + duprow_action is definitely a work in progress; #postsolve is + unimplemented. + This doesn't matter as it uses useless_constraint. +*/ + +class duprow_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +class duprow3_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + duprow3_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + duprow3_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~duprow_action() { delete[]actions_; } +}; + +/*! \class gubrow_action + \brief Detect and remove entries whose sum is known + + If we have an equality row where all entries same then + For other rows where all entries for that equality row are same + then we can delete entries and modify rhs + gubrow_action is definitely a work in progress; #postsolve is + unimplemented. +*/ + +class gubrow_action : public CoinPresolveAction { + struct action { + int row; + double lbound; + double ubound; + }; + + const int nactions_; + const action *const actions_; + + gubrow_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + gubrow_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + //~gubrow_action() { delete[]actions_; } +}; + +/*! \class twoxtwo_action + \brief Detect interesting 2 by 2 blocks + + If a variable has two entries and for each row there are only + two entries with same other variable then we can get rid of + one constraint and modify costs. + + This is a work in progress - I need more examples +*/ + +class twoxtwo_action : public CoinPresolveAction { + struct action { + double lbound_row; + double ubound_row; + double lbound_col; + double ubound_col; + double cost_col; + double cost_othercol; + int row; + int col; + int othercol; + }; + + const int nactions_; + const action *const actions_; + + twoxtwo_action():CoinPresolveAction(NULL),nactions_(0),actions_(NULL) {} + twoxtwo_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + ~twoxtwo_action() { delete [] actions_; } +}; + +#endif + diff --git a/thirdparty/linux/include/coin1/CoinPresolveEmpty.hpp b/thirdparty/linux/include/coin1/CoinPresolveEmpty.hpp new file mode 100644 index 0000000..336f1fd --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveEmpty.hpp @@ -0,0 +1,116 @@ +/* $Id: CoinPresolveEmpty.hpp 1561 2012-11-24 00:32:16Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveEmpty_H +#define CoinPresolveEmpty_H + +/*! \file + + Drop/reinsert empty rows/columns. +*/ + +const int DROP_ROW = 3; +const int DROP_COL = 4; + +/*! \class drop_empty_cols_action + \brief Physically removes empty columns in presolve, and reinserts + empty columns in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is <b>not</b> maintained by this transform. + + To physically drop the columns, CoinPrePostsolveMatrix::mcstrt_ and + CoinPrePostsolveMatrix::hincol_ are compressed, along with column bounds, + objective, and (if present) the column portions of the solution. This + renumbers the columns. drop_empty_cols_action::presolve will reconstruct + CoinPresolveMatrix::clink_. + + \todo Confirm correct behaviour with solution in presolve. +*/ + +class drop_empty_cols_action : public CoinPresolveAction { +private: + const int nactions_; + + struct action { + double clo; + double cup; + double cost; + double sol; + int jcol; + }; + const action *const actions_; + + drop_empty_cols_action(int nactions, + const action *const actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) + {} + + public: + const char *name() const { return ("drop_empty_cols_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const int *ecols, + int necols, + const CoinPresolveAction*); + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_cols_action() { deleteAction(actions_,action*); } +}; + + +/*! \class drop_empty_rows_action + \brief Physically removes empty rows in presolve, and reinserts + empty rows in postsolve. + + Physical removal of rows and columns should be the last activities + performed during presolve. Do them exactly once. The row-major matrix + is <b>not</b> maintained by this transform. + + To physically drop the rows, the rows are renumbered, excluding empty + rows. This involves rewriting CoinPrePostsolveMatrix::hrow_ and compressing + the row bounds and (if present) the row portions of the solution. + + \todo Confirm behaviour when a solution is present in presolve. +*/ +class drop_empty_rows_action : public CoinPresolveAction { +private: + struct action { + double rlo; + double rup; + int row; + int fill_row; // which row was moved into position row to fill it + }; + + const int nactions_; + const action *const actions_; + + drop_empty_rows_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("drop_empty_rows_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_empty_rows_action() { deleteAction(actions_,action*); } +}; +#endif + diff --git a/thirdparty/linux/include/coin1/CoinPresolveFixed.hpp b/thirdparty/linux/include/coin1/CoinPresolveFixed.hpp new file mode 100644 index 0000000..dc59207 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveFixed.hpp @@ -0,0 +1,181 @@ +/* $Id: CoinPresolveFixed.hpp 1510 2011-12-08 23:56:01Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveFixed_H +#define CoinPresolveFixed_H +#define FIXED_VARIABLE 1 + +/*! \class remove_fixed_action + \brief Excise fixed variables from the model. + + Implements the action of virtually removing one or more fixed variables + x_j from the model by substituting the value sol_j in each constraint. + Specifically, for each constraint i where a_ij != 0, rlo_i and rup_i + are adjusted by -a_ij*sol_j and a_ij is set to 0. + + There is an implicit assumption that the variable already has the correct + value. If this isn't true, corrections to row activity may be incorrect. + If you want to guard against this possibility, consider make_fixed_action. + + Actual removal of the empty column from the matrix is handled by + drop_empty_cols_action. Correction of the objective function is done there. +*/ +class remove_fixed_action : public CoinPresolveAction { + public: + /*! \brief Structure to hold information necessary to reintroduce a + column into the problem representation. + */ + struct action { + int col; ///< column index of variable + int start; ///< start of coefficients in #colels_ and #colrows_ + double sol; ///< value of variable + }; + /// Array of row indices for coefficients of excised columns + int *colrows_; + /// Array of coefficients of excised columns + double *colels_; + /// Number of entries in #actions_ + int nactions_; + /// Vector specifying variable(s) affected by this object + action *actions_; + + private: + /*! \brief Constructor */ + remove_fixed_action(int nactions, + action *actions, + double * colels, + int * colrows, + const CoinPresolveAction *next); + + public: + /// Returns string "remove_fixed_action". + const char *name() const; + + /*! \brief Excise the specified columns. + + Remove the specified columns (\p nfcols, \p fcols) from the problem + representation (\p prob), leaving the appropriate postsolve object + linked as the head of the list of postsolve objects (currently headed + by \p next). + */ + static const remove_fixed_action *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~remove_fixed_action(); +}; + + +/*! \relates remove_fixed_action + \brief Scan the problem for fixed columns and remove them. + + A front end to collect a list of columns with equal bounds and hand them to + remove_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *remove_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + +/*! \class make_fixed_action + \brief Fix a variable at a specified bound. + + Implements the action of fixing a variable by forcing both bounds to the same + value and forcing the value of the variable to match. + + If the bounds are already equal, and the value of the variable is already + correct, consider remove_fixed_action. +*/ +class make_fixed_action : public CoinPresolveAction { + + /// Structure to preserve the bound overwritten when fixing a variable + struct action { + double bound; ///< Value of bound overwritten to fix variable. + int col ; ///< column index of variable + }; + + /// Number of preserved bounds + int nactions_; + /// Vector of preserved bounds, one for each variable fixed in this object + const action *actions_; + + /*! \brief True to fix at lower bound, false to fix at upper bound. + + Note that this applies to all variables fixed in this object. + */ + const bool fix_to_lower_; + + /*! \brief The postsolve object with the information required to repopulate + the fixed columns. + */ + const remove_fixed_action *faction_; + + /*! \brief Constructor */ + make_fixed_action(int nactions, const action *actions, bool fix_to_lower, + const remove_fixed_action *faction, + const CoinPresolveAction *next) + : CoinPresolveAction(next), + nactions_(nactions), actions_(actions), + fix_to_lower_(fix_to_lower), + faction_(faction) + {} + + public: + /// Returns string "make_fixed_action". + const char *name() const; + + /*! \brief Perform actions to fix variables and return postsolve object + + For each specified variable (\p nfcols, \p fcols), fix the variable to + the specified bound (\p fix_to_lower) by setting the variable's bounds + to be equal in \p prob. Create a postsolve object, link it at the head of + the list of postsolve objects (\p next), and return the object. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *fcols, + int nfcols, + bool fix_to_lower, + const CoinPresolveAction *next); + + /*! \brief Postsolve (unfix variables) + + Back out the variables fixed by the presolve side of this object. + */ + void postsolve(CoinPostsolveMatrix *prob) const; + + /// Destructor + virtual ~make_fixed_action() { + deleteAction(actions_,action*); + delete faction_; + } +}; + +/*! \relates make_fixed_action + \brief Scan variables and fix any with equal bounds + + A front end to collect a list of columns with equal bounds and hand them to + make_fixed_action::presolve() for processing. +*/ + +const CoinPresolveAction *make_fixed(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + +/*! \brief Transfer costs from singleton variables + \relates make_fixed_action + + Transfers costs from singleton variables in equalities onto the other + variables. Will also transfer costs from one integer variable to other + integer variables with zero cost if there's a net gain in integer variables + with non-zero cost. + + The relation to make_fixed_action is tenuous, but this transform should be + attempted before the initial round of variable fixing. +*/ +void transferCosts(CoinPresolveMatrix * prob); +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveForcing.hpp b/thirdparty/linux/include/coin1/CoinPresolveForcing.hpp new file mode 100644 index 0000000..ee5a641 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveForcing.hpp @@ -0,0 +1,61 @@ +/* $Id: CoinPresolveForcing.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveForcing_H +#define CoinPresolveForcing_H + +#include "CoinPresolveMatrix.hpp" + +/*! + \file +*/ + +#define IMPLIED_BOUND 7 + +/*! \class forcing_constraint_action + \brief Detect and process forcing constraints and useless constraints + + A constraint is useless if the bounds on the variables prevent the constraint + from ever being violated. + + A constraint is a forcing constraint if the bounds on the constraint force + the value of an involved variable to one of its bounds. A constraint can + force more than one variable. +*/ +class forcing_constraint_action : public CoinPresolveAction { + forcing_constraint_action(); + forcing_constraint_action(const forcing_constraint_action& rhs); + forcing_constraint_action& operator=(const forcing_constraint_action& rhs); +public: + struct action { + const int *rowcols; + const double *bounds; + int row; + int nlo; + int nup; + }; +private: + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + +public: + forcing_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~forcing_constraint_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveImpliedFree.hpp b/thirdparty/linux/include/coin1/CoinPresolveImpliedFree.hpp new file mode 100644 index 0000000..8215b98 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveImpliedFree.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveImpliedFree.hpp 1694 2014-04-29 02:08:35Z tkr $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveImpliedFree_H +#define CoinPresolveImpliedFree_H + +/*! + \file +*/ + +#define IMPLIED_FREE 9 + +/*! \class implied_free_action + \brief Detect and process implied free variables + + Consider a singleton variable x (<i>i.e.</i>, a variable involved in only + one constraint). Suppose that the bounds on that constraint, combined with + the bounds on the other variables involved in the constraint, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. Both x and + the constraint can be deleted from the problem. + + A similar transform for the case where the variable is not a natural column + singleton is handled by #subst_constraint_action. +*/ +class implied_free_action : public CoinPresolveAction { + struct action { + int row, col; + double clo, cup; + double rlo, rup; + const double *rowels; + const double *costs; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + implied_free_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int & fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~implied_free_action(); +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveIsolated.hpp b/thirdparty/linux/include/coin1/CoinPresolveIsolated.hpp new file mode 100644 index 0000000..38c700f --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveIsolated.hpp @@ -0,0 +1,51 @@ +/* $Id: CoinPresolveIsolated.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveIsolated_H +#define CoinPresolveIsolated_H + +#include "CoinPresolveMatrix.hpp" + +class isolated_constraint_action : public CoinPresolveAction { + isolated_constraint_action(); + isolated_constraint_action(const isolated_constraint_action& rhs); + isolated_constraint_action& operator=(const isolated_constraint_action& rhs); + + double rlo_; + double rup_; + int row_; + int ninrow_; + // the arrays are owned by the class and must be deleted at destruction + const int *rowcols_; + const double *rowels_; + const double *costs_; + + isolated_constraint_action(double rlo, + double rup, + int row, + int ninrow, + const int *rowcols, + const double *rowels, + const double *costs, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + rlo_(rlo), rup_(rup), row_(row), ninrow_(ninrow), + rowcols_(rowcols), rowels_(rowels), costs_(costs) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + int row, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~isolated_constraint_action(); +}; + + + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveMatrix.hpp b/thirdparty/linux/include/coin1/CoinPresolveMatrix.hpp new file mode 100644 index 0000000..e608738 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveMatrix.hpp @@ -0,0 +1,1842 @@ +/* $Id: CoinPresolveMatrix.hpp 1761 2014-12-10 09:43:07Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveMatrix_H +#define CoinPresolveMatrix_H + +#include "CoinPragma.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinMessage.hpp" +#include "CoinTime.hpp" + +#include <cmath> +#include <cassert> +#include <cfloat> +#include <cassert> +#include <cstdlib> + +#if PRESOLVE_DEBUG > 0 +#include "CoinFinite.hpp" +#endif + +/*! \file + + Declarations for CoinPresolveMatrix and CoinPostsolveMatrix and their + common base class CoinPrePostsolveMatrix. Also declarations for + CoinPresolveAction and a number of non-member utility functions. +*/ + + +#if defined(_MSC_VER) +// Avoid MS Compiler problem in recognizing type to delete +// by casting to type. +// Is this still necessary? -- lh, 111202 -- +#define deleteAction(array,type) delete [] ((type) array) +#else +#define deleteAction(array,type) delete [] array +#endif + +/* + Define PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure command + line or in a Makefile! See comments in CoinPresolvePsdebug.hpp. +*/ +#if PRESOLVE_DEBUG > 0 || PRESOLVE_CONSISTENCY > 0 + +#define PRESOLVE_STMT(s) s + +#define PRESOLVEASSERT(x) \ + ((x) ? 1 : ((std::cerr << "FAILED ASSERTION at line " \ + << __LINE__ << ": " #x "\n"), abort(), 0)) + +inline void DIE(const char *s) { std::cout << s ; abort() ; } + +/*! \brief Indicate column or row present at start of postsolve + + This code is used during postsolve in [cr]done to indicate columns and rows + that are present in the presolved system (i.e., present at the start of + postsolve processing). + + \todo + There are a bunch of these code definitions, scattered through presolve + files. They should be collected in one place. +*/ +#define PRESENT_IN_REDUCED '\377' + +#else + +#define PRESOLVEASSERT(x) {} +#define PRESOLVE_STMT(s) {} + +inline void DIE(const char *) {} + +#endif + +/* + Unclear why these are separate from standard debug. +*/ +#ifndef PRESOLVE_DETAIL +#define PRESOLVE_DETAIL_PRINT(s) {} +#else +#define PRESOLVE_DETAIL_PRINT(s) s +#endif + +/*! \brief Zero tolerance + + OSL had a fixed zero tolerance; we still use that here. +*/ +const double ZTOLDP = 1e-12 ; +/*! \brief Alternate zero tolerance + + Use a different one if we are doing doubletons, etc. +*/ +const double ZTOLDP2 = 1e-10 ; + +/// The usual finite infinity +#define PRESOLVE_INF COIN_DBL_MAX +/// And a small infinity +#define PRESOLVE_SMALL_INF 1.0e20 +/// Check for infinity using finite infinity +#define PRESOLVEFINITE(n) (-PRESOLVE_INF < (n) && (n) < PRESOLVE_INF) + + +class CoinPostsolveMatrix ; + +/*! \class CoinPresolveAction + \brief Abstract base class of all presolve routines. + + The details will make more sense after a quick overview of the grand plan: + A presolve object is handed a problem object, which it is expected to + modify in some useful way. Assuming that it succeeds, the presolve object + should create a postsolve object, <i>i.e.</i>, an object that contains + instructions for backing out the presolve transform to recover the original + problem. These postsolve objects are accumulated in a linked list, with each + successive presolve action adding its postsolve action to the head of the + list. The end result of all this is a presolved problem object, and a list + of postsolve objects. The presolved problem object is then handed to a + solver for optimization, and the problem object augmented with the + results. The list of postsolve objects is then traversed. Each of them + (un)modifies the problem object, with the end result being the original + problem, augmented with solution information. + + The problem object representation is CoinPrePostsolveMatrix and subclasses. + Check there for details. The \c CoinPresolveAction class and subclasses + represent the presolve and postsolve objects. + + In spite of the name, the only information held in a \c CoinPresolveAction + object is the information needed to postsolve (<i>i.e.</i>, the information + needed to back out the presolve transformation). This information is not + expected to change, so the fields are all \c const. + + A subclass of \c CoinPresolveAction, implementing a specific pre/postsolve + action, is expected to declare a static function that attempts to perform a + presolve transformation. This function will be handed a CoinPresolveMatrix + to transform, and a pointer to the head of the list of postsolve objects. + If the transform is successful, the function will create a new + \c CoinPresolveAction object, link it at the head of the list of postsolve + objects, and return a pointer to the postsolve object it has just created. + Otherwise, it should return 0. It is expected that these static functions + will be the only things that can create new \c CoinPresolveAction objects; + this is expressed by making each subclass' constructor(s) private. + + Every subclass must also define a \c postsolve method. + This function will be handed a CoinPostsolveMatrix to transform. + + It is the client's responsibility to implement presolve and postsolve driver + routines. See OsiPresolve for examples. + + \note Since the only fields in a \c CoinPresolveAction are \c const, anything + one can do with a variable declared \c CoinPresolveAction* can also be + done with a variable declared \c const \c CoinPresolveAction* It is + expected that all derived subclasses of \c CoinPresolveAction also have + this property. +*/ +class CoinPresolveAction +{ + public: + /*! \brief Stub routine to throw exceptions. + + Exceptions are inefficient, particularly with g++. Even with xlC, the + use of exceptions adds a long prologue to a routine. Therefore, rather + than use throw directly in the routine, I use it in a stub routine. + */ + static void throwCoinError(const char *error, const char *ps_routine) + { throw CoinError(error, ps_routine, "CoinPresolve"); } + + /*! \brief The next presolve transformation + + Set at object construction. + */ + const CoinPresolveAction *next; + + /*! \brief Construct a postsolve object and add it to the transformation list. + + This is an `add to head' operation. This object will point to the + one passed as the parameter. + */ + CoinPresolveAction(const CoinPresolveAction *next) : next(next) {} + /// modify next (when building rather than passing) + inline void setNext(const CoinPresolveAction *nextAction) + { next = nextAction;} + + /*! \brief A name for debug printing. + + It is expected that the name is not stored in the transform itself. + */ + virtual const char *name() const = 0; + + /*! \brief Apply the postsolve transformation for this particular + presolve action. + */ + virtual void postsolve(CoinPostsolveMatrix *prob) const = 0; + + /*! \brief Virtual destructor. */ + virtual ~CoinPresolveAction() {} +}; + +/* + These are needed for OSI-aware constructors associated with + CoinPrePostsolveMatrix, CoinPresolveMatrix, and CoinPostsolveMatrix. +*/ +class ClpSimplex; +class OsiSolverInterface; + +/* + CoinWarmStartBasis is required for methods in CoinPrePostsolveMatrix + that accept/return a CoinWarmStartBasis object. +*/ +class CoinWarmStartBasis ; + +/*! \class CoinPrePostsolveMatrix + \brief Collects all the information about the problem that is needed + in both presolve and postsolve. + + In a bit more detail, a column-major representation of the constraint + matrix and upper and lower bounds on variables and constraints, plus row + and column solutions, reduced costs, and status. There's also a set of + arrays holding the original row and column numbers. + + As presolve and postsolve transform the matrix, it will occasionally be + necessary to expand the number of entries in a column. There are two + aspects: + <ul> + <li> During postsolve, the constraint system is expected to grow as + the smaller presolved system is transformed back to the original + system. + <li> During both pre- and postsolve, transforms can increase the number + of coefficients in a row or column. (See the + variable substitution, doubleton, and tripleton transforms.) + </ul> + + The first is addressed by the members #ncols0_, #nrows0_, and #nelems0_. + These should be set (via constructor parameters) to values large enough + for the largest size taken on by the constraint system. Typically, this + will be the size of the original constraint system. + + The second is addressed by a generous allocation of extra (empty) space + for the arrays used to hold coefficients and row indices. When columns + must be expanded, they are moved into the empty space. When it is used up, + the arrays are compacted. When compaction fails to produce sufficient + space, presolve/postsolve will fail. + + CoinPrePostsolveMatrix isn't really intended to be used `bare' --- the + expectation is that it'll be used through CoinPresolveMatrix or + CoinPostsolveMatrix. Some of the functions needed to load a problem are + defined in the derived classes. + + When CoinPresolve is applied when reoptimising, we need to be prepared to + accept a basis and modify it in step with the presolve actions (otherwise + we throw away all the advantages of warm start for reoptimization). But + other solution components (#acts_, #rowduals_, #sol_, and #rcosts_) are + needed only for postsolve, where they're used in places to determine the + proper action(s) when restoring rows or columns. If presolve is provided + with a solution, it will modify it in step with the presolve actions. + Moving the solution components from CoinPrePostsolveMatrix to + CoinPostsolveMatrix would break a lot of code. It's not clear that it's + worth it, and it would preclude upgrades to the presolve side that might + make use of any of these. -- lh, 080501 -- + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPrePostsolveMatrix +{ + public: + + /*! \name Constructors & Destructors */ + + //@{ + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. On + the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPrePostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPrePostsolveMatrix(const OsiSolverInterface * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_); + + /*! ClpOsi constructor + + See Clp code for the definition. + */ + CoinPrePostsolveMatrix(const ClpSimplex * si, + int ncols_, + int nrows_, + CoinBigIndex nelems_, + double bulkRatio); + + /// Destructor + ~CoinPrePostsolveMatrix(); + //@} + + /*! \brief Enum for status of various sorts + + Matches CoinWarmStartBasis::Status and adds superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + superBasic is an unresolved problem: there's no analogue in + CoinWarmStartBasis::Status. + */ + enum Status { + isFree = 0x00, + basic = 0x01, + atUpperBound = 0x02, + atLowerBound = 0x03, + superBasic = 0x04 + }; + + /*! \name Functions to work with variable status + + Functions to work with the CoinPrePostsolveMatrix::Status enum and + related vectors. + + \todo + Why are we futzing around with three bit status? A holdover from the + packed arrays of CoinWarmStartBasis? Big swaths of the presolve code + manipulates colstat_ and rowstat_ as unsigned char arrays using simple + assignment to set values. + */ + //@{ + + /// Set row status (<i>i.e.</i>, status of artificial for this row) + inline void setRowStatus(int sequence, Status status) + { + unsigned char & st_byte = rowstat_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & (~7)) ; + st_byte = static_cast<unsigned char>(st_byte | status) ; + } + /// Get row status + inline Status getRowStatus(int sequence) const + {return static_cast<Status> (rowstat_[sequence]&7);} + /// Check if artificial for this row is basic + inline bool rowIsBasic(int sequence) const + {return (static_cast<Status> (rowstat_[sequence]&7)==basic);} + /// Set column status (<i>i.e.</i>, status of primal variable) + inline void setColumnStatus(int sequence, Status status) + { + unsigned char & st_byte = colstat_[sequence]; + st_byte = static_cast<unsigned char>(st_byte & (~7)) ; + st_byte = static_cast<unsigned char>(st_byte | status) ; + +# ifdef PRESOLVE_DEBUG + switch (status) + { case isFree: + { if (clo_[sequence] > -PRESOLVE_INF || cup_[sequence] < PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " isFree, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case basic: + { break ; } + case atUpperBound: + { if (cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atUpperBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case atLowerBound: + { if (clo_[sequence] <= -PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " atLowerBound, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + case superBasic: + { if (clo_[sequence] <= -PRESOLVE_INF && cup_[sequence] >= PRESOLVE_INF) + { std::cout << "Bad status: Var " << sequence + << " superBasic, lb = " << clo_[sequence] + << ", ub = " << cup_[sequence] << std::endl ; } + break ; } + default: + { assert(false) ; + break ; } } +# endif + } + /// Get column (structural variable) status + inline Status getColumnStatus(int sequence) const + {return static_cast<Status> (colstat_[sequence]&7);} + /// Check if column (structural variable) is basic + inline bool columnIsBasic(int sequence) const + {return (static_cast<Status> (colstat_[sequence]&7)==basic);} + /*! \brief Set status of row (artificial variable) to the correct nonbasic + status given bounds and current value + */ + void setRowStatusUsingValue(int iRow); + /*! \brief Set status of column (structural variable) to the correct + nonbasic status given bounds and current value + */ + void setColumnStatusUsingValue(int iColumn); + /*! \brief Set column (structural variable) status vector */ + void setStructuralStatus(const char *strucStatus, int lenParam) ; + /*! \brief Set row (artificial variable) status vector */ + void setArtificialStatus(const char *artifStatus, int lenParam) ; + /*! \brief Set the status of all variables from a basis */ + void setStatus(const CoinWarmStartBasis *basis) ; + /*! \brief Get status in the form of a CoinWarmStartBasis */ + CoinWarmStartBasis *getStatus() ; + /*! \brief Return a print string for status of a column (structural + variable) + */ + const char *columnStatusString(int j) const ; + /*! \brief Return a print string for status of a row (artificial + variable) + */ + const char *rowStatusString(int i) const ; + //@} + + /*! \name Functions to load problem and solution information + + These functions can be used to load portions of the problem definition + and solution. See also the CoinPresolveMatrix and CoinPostsolveMatrix + classes. + */ + //@{ + /// Set the objective function offset for the original system. + void setObjOffset(double offset) ; + /*! \brief Set the objective sense (max/min) + + Coded as 1.0 for min, -1.0 for max. + Yes, there's a method, and a matching attribute. No, you really + don't want to set this to maximise. + */ + void setObjSense(double objSense) ; + /// Set the primal feasibility tolerance + void setPrimalTolerance(double primTol) ; + /// Set the dual feasibility tolerance + void setDualTolerance(double dualTol) ; + /// Set column lower bounds + void setColLower(const double *colLower, int lenParam) ; + /// Set column upper bounds + void setColUpper(const double *colUpper, int lenParam) ; + /// Set column solution + void setColSolution(const double *colSol, int lenParam) ; + /// Set objective coefficients + void setCost(const double *cost, int lenParam) ; + /// Set reduced costs + void setReducedCost(const double *redCost, int lenParam) ; + /// Set row lower bounds + void setRowLower(const double *rowLower, int lenParam) ; + /// Set row upper bounds + void setRowUpper(const double *rowUpper, int lenParam) ; + /// Set row solution + void setRowPrice(const double *rowSol, int lenParam) ; + /// Set row activity + void setRowActivity(const double *rowAct, int lenParam) ; + //@} + + /*! \name Functions to retrieve problem and solution information */ + //@{ + /// Get current number of columns + inline int getNumCols() const + { return (ncols_) ; } + /// Get current number of rows + inline int getNumRows() const + { return (nrows_) ; } + /// Get current number of non-zero coefficients + inline int getNumElems() const + { return (nelems_) ; } + /// Get column start vector for column-major packed matrix + inline const CoinBigIndex *getColStarts() const + { return (mcstrt_) ; } + /// Get column length vector for column-major packed matrix + inline const int *getColLengths() const + { return (hincol_) ; } + /// Get vector of row indices for column-major packed matrix + inline const int *getRowIndicesByCol() const + { return (hrow_) ; } + /// Get vector of elements for column-major packed matrix + inline const double *getElementsByCol() const + { return (colels_) ; } + /// Get column lower bounds + inline const double *getColLower() const + { return (clo_) ; } + /// Get column upper bounds + inline const double *getColUpper() const + { return (cup_) ; } + /// Get objective coefficients + inline const double *getCost() const + { return (cost_) ; } + /// Get row lower bounds + inline const double *getRowLower() const + { return (rlo_) ; } + /// Get row upper bounds + inline const double *getRowUpper() const + { return (rup_) ; } + /// Get column solution (primal variable values) + inline const double *getColSolution() const + { return (sol_) ; } + /// Get row activity (constraint lhs values) + inline const double *getRowActivity() const + { return (acts_) ; } + /// Get row solution (dual variables) + inline const double *getRowPrice() const + { return (rowduals_) ; } + /// Get reduced costs + inline const double *getReducedCost() const + { return (rcosts_) ; } + /// Count empty columns + inline int countEmptyCols() + { int empty = 0 ; + for (int i = 0 ; i < ncols_ ; i++) if (hincol_[i] == 0) empty++ ; + return (empty) ; } + //@} + + + /*! \name Message handling */ + //@{ + /// Return message handler + inline CoinMessageHandler *messageHandler() const + { return handler_; } + /*! \brief Set message handler + + The client retains responsibility for the handler --- it will not be + destroyed with the \c CoinPrePostsolveMatrix object. + */ + inline void setMessageHandler(CoinMessageHandler *handler) + { if (defaultHandler_ == true) + { delete handler_ ; + defaultHandler_ = false ; } + handler_ = handler ; } + /// Return messages + inline CoinMessages messages() const + { return messages_; } + //@} + + /*! \name Current and Allocated Size + + During pre- and postsolve, the matrix will change in size. During presolve + it will shrink; during postsolve it will grow. Hence there are two sets of + size variables, one for the current size and one for the allocated size. + (See the general comments for the CoinPrePostsolveMatrix class for more + information.) + */ + //@{ + + /// current number of columns + int ncols_; + /// current number of rows + int nrows_; + /// current number of coefficients + CoinBigIndex nelems_; + + /// Allocated number of columns + int ncols0_; + /// Allocated number of rows + int nrows0_ ; + /// Allocated number of coefficients + CoinBigIndex nelems0_ ; + /*! \brief Allocated size of bulk storage for row indices and coefficients + + This is the space allocated for hrow_ and colels_. This must be large + enough to allow columns to be copied into empty space when they need to + be expanded. For efficiency (to minimize the number of times the + representation must be compressed) it's recommended that this be at least + 2*nelems0_. + */ + CoinBigIndex bulk0_ ; + /// Ratio of bulk0_ to nelems0_; default is 2. + double bulkRatio_; + //@} + + /*! \name Problem representation + + The matrix is the common column-major format: A pair of vectors with + positional correspondence to hold coefficients and row indices, and a + second pair of vectors giving the starting position and length of each + column in the first pair. + */ + //@{ + /// Vector of column start positions in #hrow_, #colels_ + CoinBigIndex *mcstrt_; + /// Vector of column lengths + int *hincol_; + /// Row indices (positional correspondence with #colels_) + int *hrow_; + /// Coefficients (positional correspondence with #hrow_) + double *colels_; + + /// Objective coefficients + double *cost_; + /// Original objective offset + double originalOffset_; + + /// Column (primal variable) lower bounds + double *clo_; + /// Column (primal variable) upper bounds + double *cup_; + + /// Row (constraint) lower bounds + double *rlo_; + /// Row (constraint) upper bounds + double *rup_; + + /*! \brief Original column numbers + + Over the current range of column numbers in the presolved problem, + the entry for column j will contain the index of the corresponding + column in the original problem. + */ + int * originalColumn_; + /*! \brief Original row numbers + + Over the current range of row numbers in the presolved problem, the + entry for row i will contain the index of the corresponding row in + the original problem. + */ + int * originalRow_; + + /// Primal feasibility tolerance + double ztolzb_; + /// Dual feasibility tolerance + double ztoldj_; + + /*! \brief Maximization/minimization + + Yes, there's a variable here. No, you really don't want to set this to + maximise. See the main notes for CoinPresolveMatrix. + */ + double maxmin_; + //@} + + /*! \name Problem solution information + + The presolve phase will work without any solution information + (appropriate for initial optimisation) or with solution information + (appropriate for reoptimisation). When solution information is supplied, + presolve will maintain it to the best of its ability. #colstat_ is + checked to determine the presence/absence of status information. #sol_ is + checked for primal solution information, and #rowduals_ for dual solution + information. + + The postsolve phase requires the complete solution information from the + presolved problem (status, primal and dual solutions). It will be + transformed into a correct solution for the original problem. + */ + //@{ + /*! \brief Vector of primal variable values + + If #sol_ exists, it is assumed that primal solution information should be + updated and that #acts_ also exists. + */ + double *sol_; + /*! \brief Vector of dual variable values + + If #rowduals_ exists, it is assumed that dual solution information should + be updated and that #rcosts_ also exists. + */ + double *rowduals_; + /*! \brief Vector of constraint left-hand-side values (row activity) + + Produced by evaluating constraints according to #sol_. Updated iff + #sol_ exists. + */ + double *acts_; + /*! \brief Vector of reduced costs + + Produced by evaluating dual constraints according to #rowduals_. Updated + iff #rowduals_ exists. + */ + double *rcosts_; + + /*! \brief Status of primal variables + + Coded with CoinPrePostSolveMatrix::Status, one code per char. colstat_ and + #rowstat_ <b>MUST</b> be allocated as a single vector. This is to maintain + compatibility with ClpPresolve and OsiPresolve, which do it this way. + */ + unsigned char *colstat_; + + /*! \brief Status of constraints + + More accurately, the status of the logical variable associated with the + constraint. Coded with CoinPrePostSolveMatrix::Status, one code per char. + Note that this must be allocated as a single vector with #colstat_. + */ + unsigned char *rowstat_; + //@} + + /*! \name Message handling + + Uses the standard COIN approach: a default handler is installed, and the + CoinPrePostsolveMatrix object takes responsibility for it. If the client + replaces the handler with one of their own, it becomes their + responsibility. + */ + //@{ + /// Message handler + CoinMessageHandler *handler_; + /// Indicates if the current #handler_ is default (true) or not (false). + bool defaultHandler_; + /// Standard COIN messages + CoinMessage messages_; + //@} + +}; + +/*! \relates CoinPrePostsolveMatrix + \brief Generate a print string for a status code. +*/ +const char *statusName (CoinPrePostsolveMatrix::Status status) ; + + +/*! \class presolvehlink + \brief Links to aid in packed matrix modification + + Currently, the matrices held by the CoinPrePostsolveMatrix and + CoinPresolveMatrix objects are represented in the same way as a + CoinPackedMatrix. In the course of presolve and postsolve transforms, it + will happen that a major-dimension vector needs to increase in size. In + order to check whether there is enough room to add another coefficient in + place, it helps to know the next vector (in memory order) in the bulk + storage area. To do that, a linked list of major-dimension vectors is + maintained; the "pre" and "suc" fields give the previous and next vector, + in memory order (that is, the vector whose mcstrt_ or mrstrt_ entry is + next smaller or larger). + + Consider a column-major matrix with ncols columns. By definition, + presolvehlink[ncols].pre points to the column in the last occupied + position of the bulk storage arrays. There is no easy way to find the + column which occupies the first position (there is no presolvehlink[-1] to + consult). If the column that initially occupies the first position is + moved for expansion, there is no way to reclaim the space until the bulk + storage is compacted. The same holds for the last and first rows of a + row-major matrix, of course. +*/ + +class presolvehlink +{ public: + int pre, suc; +} ; + +#define NO_LINK -66666666 + +/*! \relates presolvehlink + \brief unlink vector i + + Remove vector i from the ordering. +*/ +inline void PRESOLVE_REMOVE_LINK(presolvehlink *link, int i) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = isuc; + } + if (isuc >= 0) { + link[isuc].pre = ipre; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + +/*! \relates presolvehlink + \brief insert vector i after vector j + + Insert vector i between j and j.suc. +*/ +inline void PRESOLVE_INSERT_LINK(presolvehlink *link, int i, int j) +{ + int isuc = link[j].suc; + link[j].suc = i; + link[i].pre = j; + if (isuc >= 0) { + link[isuc].pre = i; + } + link[i].suc = isuc; +} + +/*! \relates presolvehlink + \brief relink vector j in place of vector i + + Replace vector i in the ordering with vector j. This is equivalent to + <pre> + int pre = link[i].pre; + PRESOLVE_REMOVE_LINK(link,i); + PRESOLVE_INSERT_LINK(link,j,pre); + </pre> + But, this routine will work even if i happens to be first in the order. +*/ +inline void PRESOLVE_MOVE_LINK(presolvehlink *link, int i, int j) +{ + int ipre = link[i].pre; + int isuc = link[i].suc; + if (ipre >= 0) { + link[ipre].suc = j; + } + if (isuc >= 0) { + link[isuc].pre = j; + } + link[i].pre = NO_LINK, link[i].suc = NO_LINK; +} + + +/*! \class CoinPresolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during presolve. + + For problem manipulation, this class adds a row-major matrix + representation, linked lists that allow for easy manipulation of the matrix + when applying presolve transforms, and vectors to track row and column + processing status (changed, needs further processing, change prohibited) + + For problem representation, this class adds information about variable type + (integer or continuous), an objective offset, and a feasibility tolerance. + + <b>NOTE</b> that the #anyInteger_ and #anyProhibited_ flags are independent + of the vectors used to track this information for individual variables + (#integerType_ and #rowChanged_ and #colChanged_, respectively). + + <b>NOTE</b> also that at the end of presolve the column-major and row-major + matrix representations are loosely packed (<i>i.e.</i>, there may be gaps + between columns in the bulk storage arrays). + + <b>NOTE</b> that while you might think that CoinPresolve is prepared to + handle minimisation or maximisation, it's unlikely that this still works. + This is a good thing: better to convert objective coefficients and duals + once, before starting presolve, rather than doing it over and over in + each transform that considers dual variables. + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ + +class CoinPresolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPresolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + + ClpSimplex * si, + + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + double bulkRatio); + + /*! \brief Update the model held by a Clp OSI */ + void update_model(ClpSimplex * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPresolveMatrix(int ncols0, + double maxmin, + // end prepost members + OsiSolverInterface * si, + // rowrep + int nrows, + CoinBigIndex nelems, + bool doStatus, + double nonLinearVariable, + const char * prohibited, + const char * rowProhibited=NULL); + + /*! \brief Update the model held by a generic OSI */ + void update_model(OsiSolverInterface * si, + int nrows0, + int ncols0, + CoinBigIndex nelems0); + + /// Destructor + ~CoinPresolveMatrix(); + + /*! \brief Initialize a CoinPostsolveMatrix object, destroying the + CoinPresolveMatrix object. + + See CoinPostsolveMatrix::assignPresolveToPostsolve. + */ + friend void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /*! \name Functions to load the problem representation + */ + //@{ + /*! \brief Load the cofficient matrix. + + Load the coefficient matrix before loading the other vectors (bounds, + objective, variable type) required to define the problem. + */ + void setMatrix(const CoinPackedMatrix *mtx) ; + + /// Count number of empty rows + inline int countEmptyRows() + { int empty = 0 ; + for (int i = 0 ; i < nrows_ ; i++) if (hinrow_[i] == 0) empty++ ; + return (empty) ; } + + /*! \brief Set variable type information for a single variable + + Set \p variableType to 0 for continous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + inline void setVariableType(int i, int variableType) + { if (integerType_ == 0) integerType_ = new unsigned char [ncols0_] ; + integerType_[i] = static_cast<unsigned char>(variableType) ; } + + /*! \brief Set variable type information for all variables + + Set \p variableType[i] to 0 for continuous, 1 for integer. + Does not manipulate the #anyInteger_ flag. + */ + void setVariableType(const unsigned char *variableType, int lenParam) ; + + /*! \brief Set the type of all variables + + allIntegers should be true to set the type to integer, false to set the + type to continuous. + */ + void setVariableType (bool allIntegers, int lenParam) ; + + /// Set a flag for presence (true) or absence (false) of integer variables + inline void setAnyInteger (bool anyInteger = true) + { anyInteger_ = anyInteger ; } + //@} + + /*! \name Functions to retrieve problem information + */ + //@{ + + /// Get row start vector for row-major packed matrix + inline const CoinBigIndex *getRowStarts() const + { return (mrstrt_) ; } + /// Get vector of column indices for row-major packed matrix + inline const int *getColIndicesByRow() const + { return (hcol_) ; } + /// Get vector of elements for row-major packed matrix + inline const double *getElementsByRow() const + { return (rowels_) ; } + + /*! \brief Check for integrality of the specified variable. + + Consults the #integerType_ vector if present; fallback is the + #anyInteger_ flag. + */ + inline bool isInteger (int i) const + { if (integerType_ == 0) + { return (anyInteger_) ; } + else + if (integerType_[i] == 1) + { return (true) ; } + else + { return (false) ; } } + + /*! \brief Check if there are any integer variables + + Consults the #anyInteger_ flag + */ + inline bool anyInteger () const + { return (anyInteger_) ; } + /// Picks up any special options + inline int presolveOptions() const + { return presolveOptions_;} + /// Sets any special options (see #presolveOptions_) + inline void setPresolveOptions(int value) + { presolveOptions_=value;} + //@} + + /*! \name Matrix storage management links + + Linked lists, modelled after the linked lists used in OSL + factorization. They are used for management of the bulk coefficient + and minor index storage areas. + */ + //@{ + /// Linked list for the column-major representation. + presolvehlink *clink_; + /// Linked list for the row-major representation. + presolvehlink *rlink_; + //@} + + /// Objective function offset introduced during presolve + double dobias_ ; + + /// Adjust objective function constant offset + inline void change_bias(double change_amount) + { + dobias_ += change_amount ; + # if PRESOLVE_DEBUG > 2 + assert(fabs(change_amount)<1.0e50) ; + if (change_amount) + PRESOLVE_STMT(printf("changing bias by %g to %g\n", + change_amount, dobias_)) ; + # endif + } + + /*! \name Row-major representation + + Common row-major format: A pair of vectors with positional + correspondence to hold coefficients and column indices, and a second pair + of vectors giving the starting position and length of each row in + the first pair. + */ + //@{ + /// Vector of row start positions in #hcol, #rowels_ + CoinBigIndex *mrstrt_; + /// Vector of row lengths + int *hinrow_; + /// Coefficients (positional correspondence with #hcol_) + double *rowels_; + /// Column indices (positional correspondence with #rowels_) + int *hcol_; + //@} + + /// Tracks integrality of columns (1 for integer, 0 for continuous) + unsigned char *integerType_; + /*! \brief Flag to say if any variables are integer + + Note that this flag is <i>not</i> manipulated by the various + \c setVariableType routines. + */ + bool anyInteger_ ; + /// Print statistics for tuning + bool tuning_; + /// Say we want statistics - also set time + void statistics(); + /// Start time of presolve + double startTime_; + + /// Bounds can be moved by this to retain feasibility + double feasibilityTolerance_; + /// Return feasibility tolerance + inline double feasibilityTolerance() + { return (feasibilityTolerance_) ; } + /// Set feasibility tolerance + inline void setFeasibilityTolerance (double val) + { feasibilityTolerance_ = val ; } + + /*! \brief Output status: 0 = feasible, 1 = infeasible, 2 = unbounded + + Actually implemented as single bit flags: 1^0 = infeasible, 1^1 = + unbounded. + */ + int status_; + /// Returns problem status (0 = feasible, 1 = infeasible, 2 = unbounded) + inline int status() + { return (status_) ; } + /// Set problem status + inline void setStatus(int status) + { status_ = (status&0x3) ; } + + /*! \brief Presolve pass number + + Should be incremented externally by the method controlling application of + presolve transforms. + Used to control the execution of testRedundant (evoked by the + implied_free transform). + */ + int pass_; + /// Set pass number + inline void setPass (int pass = 0) + { pass_ = pass ; } + + /*! \brief Maximum substitution level + + Used to control the execution of subst from implied_free + */ + int maxSubstLevel_; + /// Set Maximum substitution level (normally 3) + inline void setMaximumSubstitutionLevel (int level) + { maxSubstLevel_ = level ; } + + + /*! \name Row and column processing status + + Information used to determine if rows or columns can be changed and + if they require further processing due to changes. + + There are four major lists: the [row,col]ToDo list, and the + [row,col]NextToDo list. In general, a transform processes entries from + the ToDo list and adds entries to the NextToDo list. + + There are two vectors, [row,col]Changed, which track the status of + individual rows and columns. + */ + //@{ + /*! \brief Column change status information + + Coded using the following bits: + <ul> + <li> 0x01: Column has changed + <li> 0x02: preprocessing prohibited + <li> 0x04: Column has been used + <li> 0x08: Column originally had infinite ub + </ul> + */ + unsigned char * colChanged_; + /// Input list of columns to process + int * colsToDo_; + /// Length of #colsToDo_ + int numberColsToDo_; + /// Output list of columns to process next + int * nextColsToDo_; + /// Length of #nextColsToDo_ + int numberNextColsToDo_; + + /*! \brief Row change status information + + Coded using the following bits: + <ul> + <li> 0x01: Row has changed + <li> 0x02: preprocessing prohibited + <li> 0x04: Row has been used + </ul> + */ + unsigned char * rowChanged_; + /// Input list of rows to process + int * rowsToDo_; + /// Length of #rowsToDo_ + int numberRowsToDo_; + /// Output list of rows to process next + int * nextRowsToDo_; + /// Length of #nextRowsToDo_ + int numberNextRowsToDo_; + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column tests for integer variables + - 0x02 not used + - 0x04 set to inhibit x+y+z=1 mods + - 0x08 not used + - 0x10 set to allow stuff which won't unroll easily (overlapping + duplicate rows; opportunistic fixing of variables from bound + propagation). + - 0x04000 allow presolve transforms to arbitrarily ignore infeasibility + and set arbitrary feasible bounds. + - 0x10000 instructs implied_free_action to be `more lightweight'; will + return without doing anything after 15 presolve passes. + - 0x(2,4,6)0000 instructs implied_free_action to remove small created elements + - 0x80000000 set by presolve to say dupcol_action compressed columns + */ + int presolveOptions_; + /*! Flag to say if any rows or columns are marked as prohibited + + Note that this flag is <i>not</i> manipulated by any of the + various \c set*Prohibited routines. + */ + bool anyProhibited_; + //@} + + /*! \name Scratch work arrays + + Preallocated work arrays are useful to avoid having to allocate and free + work arrays in individual presolve methods. + + All are allocated from #setMatrix by #initializeStuff, freed from + #~CoinPresolveMatrix. You can use #deleteStuff followed by + #initializeStuff to remove and recreate them. + */ + //@{ + /// Preallocated scratch work array, 3*nrows_ + int *usefulRowInt_ ; + /// Preallocated scratch work array, 2*nrows_ + double *usefulRowDouble_ ; + /// Preallocated scratch work array, 2*ncols_ + int *usefulColumnInt_ ; + /// Preallocated scratch work array, ncols_ + double *usefulColumnDouble_ ; + /// Array of random numbers (max row,column) + double *randomNumber_ ; + + /// Work array for count of infinite contributions to row lhs upper bound + int *infiniteUp_ ; + /// Work array for sum of finite contributions to row lhs upper bound + double *sumUp_ ; + /// Work array for count of infinite contributions to row lhs lower bound + int *infiniteDown_ ; + /// Work array for sum of finite contributions to row lhs lower bound + double *sumDown_ ; + //@} + + /*! \brief Recompute row lhs bounds + + Calculate finite contributions to row lhs upper and lower bounds + and count infinite contributions. Returns the number of rows found + to be infeasible. + + If \p whichRow < 0, bounds are recomputed for all rows. + + As of 110611, this seems to be a work in progress in the sense that it's + barely used by the existing presolve code. + */ + int recomputeSums(int whichRow) ; + + /// Allocate scratch arrays + void initializeStuff() ; + /// Free scratch arrays + void deleteStuff() ; + + /*! \name Functions to manipulate row and column processing status */ + //@{ + + /*! \brief Initialise the column ToDo lists + + Places all columns in the #colsToDo_ list except for columns marked + as prohibited (<i>viz.</i> #colChanged_). + */ + void initColsToDo () ; + + /*! \brief Step column ToDo lists + + Moves columns on the #nextColsToDo_ list to the #colsToDo_ list, emptying + #nextColsToDo_. Returns the number of columns transferred. + */ + int stepColsToDo () ; + + /// Return the number of columns on the #colsToDo_ list + inline int numberColsToDo() + { return (numberColsToDo_) ; } + + /// Has column been changed? + inline bool colChanged(int i) const { + return (colChanged_[i]&1)!=0; + } + /// Mark column as not changed + inline void unsetColChanged(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~1)) ; + } + /// Mark column as changed. + inline void setColChanged(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; + } + /// Mark column as changed and add to list of columns to process next + inline void addCol(int i) { + if ((colChanged_[i]&1)==0) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (1)) ; + nextColsToDo_[numberNextColsToDo_++] = i; + } + } + /// Test if column is eligible for preprocessing + inline bool colProhibited(int i) const { + return (colChanged_[i]&2)!=0; + } + /*! \brief Test if column is eligible for preprocessing + + The difference between this method and #colProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified column. + */ + inline bool colProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (colChanged_[i]&2)!=0; + } + /// Mark column as ineligible for preprocessing + inline void setColProhibited(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (2)) ; + } + /*! \brief Test if column is marked as used + + This is for doing faster lookups to see where two columns have entries + in common. + */ + inline bool colUsed(int i) const { + return (colChanged_[i]&4)!=0; + } + /// Mark column as used + inline void setColUsed(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (4)) ; + } + /// Mark column as unused + inline void unsetColUsed(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~4)) ; + } + /// Has column infinite ub (originally) + inline bool colInfinite(int i) const { + return (colChanged_[i]&8)!=0; + } + /// Mark column as not infinite ub (originally) + inline void unsetColInfinite(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] & (~8)) ; + } + /// Mark column as infinite ub (originally) + inline void setColInfinite(int i) { + colChanged_[i] = static_cast<unsigned char>(colChanged_[i] | (8)) ; + } + + /*! \brief Initialise the row ToDo lists + + Places all rows in the #rowsToDo_ list except for rows marked + as prohibited (<i>viz.</i> #rowChanged_). + */ + void initRowsToDo () ; + + /*! \brief Step row ToDo lists + + Moves rows on the #nextRowsToDo_ list to the #rowsToDo_ list, emptying + #nextRowsToDo_. Returns the number of rows transferred. + */ + int stepRowsToDo () ; + + /// Return the number of rows on the #rowsToDo_ list + inline int numberRowsToDo() + { return (numberRowsToDo_) ; } + + /// Has row been changed? + inline bool rowChanged(int i) const { + return (rowChanged_[i]&1)!=0; + } + /// Mark row as not changed + inline void unsetRowChanged(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~1)) ; + } + /// Mark row as changed + inline void setRowChanged(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; + } + /// Mark row as changed and add to list of rows to process next + inline void addRow(int i) { + if ((rowChanged_[i]&1)==0) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (1)) ; + nextRowsToDo_[numberNextRowsToDo_++] = i; + } + } + /// Test if row is eligible for preprocessing + inline bool rowProhibited(int i) const { + return (rowChanged_[i]&2)!=0; + } + /*! \brief Test if row is eligible for preprocessing + + The difference between this method and #rowProhibited() is that this + method first tests #anyProhibited_ before examining the specific entry + for the specified row. + */ + inline bool rowProhibited2(int i) const { + if (!anyProhibited_) + return false; + else + return (rowChanged_[i]&2)!=0; + } + /// Mark row as ineligible for preprocessing + inline void setRowProhibited(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (2)) ; + } + /*! \brief Test if row is marked as used + + This is for doing faster lookups to see where two rows have entries + in common. It can be used anywhere as long as it ends up zeroed out. + */ + inline bool rowUsed(int i) const { + return (rowChanged_[i]&4)!=0; + } + /// Mark row as used + inline void setRowUsed(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] | (4)) ; + } + /// Mark row as unused + inline void unsetRowUsed(int i) { + rowChanged_[i] = static_cast<unsigned char>(rowChanged_[i] & (~4)) ; + } + + + /// Check if there are any prohibited rows or columns + inline bool anyProhibited() const + { return anyProhibited_;} + /// Set a flag for presence of prohibited rows or columns + inline void setAnyProhibited(bool val = true) + { anyProhibited_ = val ; } + //@} + +}; + +/*! \class CoinPostsolveMatrix + \brief Augments CoinPrePostsolveMatrix with information about the problem + that is only needed during postsolve. + + The notable point is that the matrix representation is threaded. The + representation is column-major and starts with the standard two pairs of + arrays: one pair to hold the row indices and coefficients, the second pair + to hold the column starting positions and lengths. But the row indices and + coefficients for a column do not necessarily occupy a contiguous block in + their respective arrays. Instead, a link array gives the position of the + next (row index,coefficient) pair. If the row index and value of a + coefficient a<p,j> occupy position kp in their arrays, then the position of + the next coefficient a<q,j> is found as kq = link[kp]. + + This threaded representation allows for efficient expansion of columns as + rows are reintroduced during postsolve transformations. The basic packed + structures are allocated to the expected size of the postsolved matrix, + and as new coefficients are added, their location is simply added to the + thread for the column. + + There is no provision to convert the threaded representation to a packed + representation. In the context of postsolve, it's not required. (You did + keep a copy of the original matrix, eh?) + + The constructors that take an OSI or ClpSimplex as a parameter really should + not be here, but for historical reasons they will likely remain for the + forseeable future. -- lh, 111202 -- +*/ +class CoinPostsolveMatrix : public CoinPrePostsolveMatrix +{ + public: + + /*! \brief `Native' constructor + + This constructor creates an empty object which must then be loaded. + On the other hand, it doesn't assume that the client is an + OsiSolverInterface. + */ + CoinPostsolveMatrix(int ncols_alloc, int nrows_alloc, + CoinBigIndex nelems_alloc) ; + + + /*! \brief Clp OSI constructor + + See Clp code for the definition. + */ + CoinPostsolveMatrix(ClpSimplex * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Generic OSI constructor + + See OSI code for the definition. + */ + CoinPostsolveMatrix(OsiSolverInterface * si, + + int ncols0, + int nrows0, + CoinBigIndex nelems0, + + double maxmin_, + // end prepost members + + double *sol, + double *acts, + + unsigned char *colstat, + unsigned char *rowstat); + + /*! \brief Load an empty CoinPostsolveMatrix from a CoinPresolveMatrix + + This routine transfers the contents of the CoinPrePostsolveMatrix + object from the CoinPresolveMatrix object to the CoinPostsolveMatrix + object and completes initialisation of the CoinPostsolveMatrix object. + The empty shell of the CoinPresolveMatrix object is destroyed. + + The routine expects an empty CoinPostsolveMatrix object. If handed a loaded + object, a lot of memory will leak. + */ + void assignPresolveToPostsolve (CoinPresolveMatrix *&preObj) ; + + /// Destructor + ~CoinPostsolveMatrix(); + + /*! \name Column thread structures + + As mentioned in the class documentation, the entries for a given column + do not necessarily occupy a contiguous block of space. The #link_ array + is used to maintain the threading. There is one thread for each column, + and a single thread for all free entries in #hrow_ and #colels_. + + The allocated size of #link_ must be at least as large as the allocated + size of #hrow_ and #colels_. + */ + //@{ + + /*! \brief First entry in free entries thread */ + CoinBigIndex free_list_; + /// Allocated size of #link_ + int maxlink_; + /*! \brief Thread array + + Within a thread, link_[k] points to the next entry in the thread. + */ + CoinBigIndex *link_; + + //@} + + /*! \name Debugging aids + + These arrays are allocated only when CoinPresolve is compiled with + PRESOLVE_DEBUG defined. They hold codes which track the reason that + a column or row is added to the problem during postsolve. + */ + //@{ + char *cdone_; + char *rdone_; + //@} + + /// debug + void check_nbasic(); + +}; + + +/*! \defgroup MtxManip Presolve Matrix Manipulation Functions + + Functions to work with the loosely packed and threaded packed matrix + structures used during presolve and postsolve. +*/ +//@{ + +/*! \relates CoinPrePostsolveMatrix + \brief Initialise linked list for major vector order in bulk storage +*/ + +void presolve_make_memlists(/*CoinBigIndex *starts,*/ int *lengths, + presolvehlink *link, int n); + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a major-dimension vector k has room for one more + coefficient. + + You can use this directly, or use the inline wrappers presolve_expand_col + and presolve_expand_row +*/ +bool presolve_expand_major(CoinBigIndex *majstrts, double *majels, + int *minndxs, int *majlens, + presolvehlink *majlinks, int nmaj, int k) ; + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a column (colx) in a column-major matrix has room for + one more coefficient +*/ + +inline bool presolve_expand_col(CoinBigIndex *mcstrt, double *colels, + int *hrow, int *hincol, + presolvehlink *clink, int ncols, int colx) +{ return presolve_expand_major(mcstrt,colels, + hrow,hincol,clink,ncols,colx) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Make sure a row (rowx) in a row-major matrix has room for one + more coefficient +*/ + +inline bool presolve_expand_row(CoinBigIndex *mrstrt, double *rowels, + int *hcol, int *hinrow, + presolvehlink *rlink, int nrows, int rowx) +{ return presolve_expand_major(mrstrt,rowels, + hcol,hinrow,rlink,nrows,rowx) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrappers presolve_find_row and + presolve_find_col. +*/ +inline CoinBigIndex presolve_find_minor(int tgt, + CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs) +{ CoinBigIndex k ; + for (k = ks ; k < ke ; k++) +#ifndef NDEBUG + { if (minndxs[k] == tgt) + return (k) ; } + DIE("FIND_MINOR") ; + + abort () ; return -1; +#else + { if (minndxs[k] == tgt) + break ; } + return (k) ; +#endif +} + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor(row,kcs,kce,hrow) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor(col,krs,kre,hcol) ; } + + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a minor index in a major vector. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. A return value of \p ke means the entry does not + exist. Can be used directly or via the inline wrappers + presolve_find_row1 and presolve_find_col1. +*/ +CoinBigIndex presolve_find_minor1(int tgt, CoinBigIndex ks, CoinBigIndex ke, + const int *minndxs); + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a row in a column in a column-major matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + A return value of \p kce means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row1(int row, CoinBigIndex kcs, + CoinBigIndex kce, const int *hrow) +{ return presolve_find_minor1(row,kcs,kce,hrow) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Find position of a column in a row in a row-major matrix. + + The routine returns the position \c k in \p hcol for the specified \p col. + A return value of \p kre means the entry does not exist. +*/ +inline CoinBigIndex presolve_find_col1(int col, CoinBigIndex krs, + CoinBigIndex kre, const int *hcol) +{ return presolve_find_minor1(col,krs,kre,hcol) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will abort if the entry does not exist. Can be + used directly or via the inline wrapper presolve_find_row2. +*/ +CoinBigIndex presolve_find_minor2(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will abort if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row2(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor2(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPostsolveMatrix + \brief Find position of a minor index in a major vector in a threaded + matrix. + + The routine returns the position \c k in \p minndxs for the specified + minor index \p tgt. It will return -1 if the entry does not exist. + Can be used directly or via the inline wrappers presolve_find_row3. +*/ +CoinBigIndex presolve_find_minor3(int tgt, CoinBigIndex ks, int majlen, + const int *minndxs, + const CoinBigIndex *majlinks) ; + +/*! \relates CoinPostsolveMatrix + \brief Find position of a row in a column in a column-major threaded + matrix. + + The routine returns the position \c k in \p hrow for the specified \p row. + It will return -1 if the entry does not exist. +*/ +inline CoinBigIndex presolve_find_row3(int row, CoinBigIndex kcs, int collen, + const int *hrow, + const CoinBigIndex *clinks) +{ return presolve_find_minor3(row,kcs,collen,hrow,clinks) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for a minor index from a major vector. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index + (\p minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_major(int majndx, int minndx, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + + const CoinBigIndex kmi = presolve_find_minor(minndx,ks,ke,minndxs) ; + + minndxs[kmi] = minndxs[ke-1] ; + els[kmi] = els[ke-1] ; + majlens[majndx]-- ; + + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete marked entries + + Removes the entries specified in \p marked, compressing the major vector + to maintain loose packing. \p marked is cleared in the process. +*/ +inline void presolve_delete_many_from_major(int majndx, char *marked, + const CoinBigIndex *majstrts, + int *majlens, int *minndxs, double *els) +{ + const CoinBigIndex ks = majstrts[majndx] ; + const CoinBigIndex ke = ks+majlens[majndx] ; + CoinBigIndex put = ks ; + for (CoinBigIndex k = ks ; k < ke ; k++) { + int iMinor = minndxs[k] ; + if (!marked[iMinor]) { + minndxs[put] = iMinor ; + els[put++] = els[k] ; + } else { + marked[iMinor] = 0 ; + } + } + majlens[majndx] = put-ks ; + return ; +} + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. Loose packing is maintained by swapping the last + entry in the row into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_col(int row, int col, + const CoinBigIndex *mcstrt, + int *hincol, int *hrow, double *colels) +{ presolve_delete_from_major(col,row,mcstrt,hincol,hrow,colels) ; } + +/*! \relates CoinPrePostsolveMatrix + \brief Delete the entry for column \p col from row \p row in a + row-major matrix + + Deletes the entry for \p col from the major vector for \p row. + Specifically, the relevant entries are removed from the column index (\p + hcol) and coefficient (\p rowels) arrays and the vector length (\p + hinrow) is decremented. Loose packing is maintained by swapping the last + entry in the column into the position occupied by the deleted entry. +*/ +inline void presolve_delete_from_row(int row, int col, + const CoinBigIndex *mrstrt, + int *hinrow, int *hcol, double *rowels) +{ presolve_delete_from_major(row,col,mrstrt,hinrow,hcol,rowels) ; } + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for a minor index from a major vector in a + threaded matrix. + + Deletes the entry for \p minndx from the major vector \p majndx. + Specifically, the relevant entries are removed from the minor index (\p + minndxs) and coefficient (\p els) arrays and the vector length (\p + majlens) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +void presolve_delete_from_major2 (int majndx, int minndx, + CoinBigIndex *majstrts, int *majlens, + int *minndxs, int *majlinks, + CoinBigIndex *free_listp) ; + +/*! \relates CoinPostsolveMatrix + \brief Delete the entry for row \p row from column \p col in a + column-major threaded matrix + + Deletes the entry for \p row from the major vector for \p col. + Specifically, the relevant entries are removed from the row index (\p + hrow) and coefficient (\p colels) arrays and the vector length (\p + hincol) is decremented. The thread for the major vector is relinked + around the deleted entry and the space is returned to the free list. +*/ +inline void presolve_delete_from_col2(int row, int col, CoinBigIndex *mcstrt, + int *hincol, int *hrow, + int *clinks, CoinBigIndex *free_listp) +{ presolve_delete_from_major2(col,row,mcstrt,hincol,hrow,clinks,free_listp) ; } + +//@} + +/*! \defgroup PresolveUtilities Presolve Utility Functions + + Utilities used by multiple presolve transform objects. +*/ +//@{ + +/*! \brief Duplicate a major-dimension vector; optionally omit the entry + with minor index \p tgt. + + Designed to copy a major-dimension vector from the paired coefficient + (\p elems) and minor index (\p indices) arrays used in the standard + packed matrix representation. Copies \p length entries starting at + \p offset. + + If \p tgt is specified, the entry with minor index == \p tgt is + omitted from the copy. +*/ +double *presolve_dupmajor(const double *elems, const int *indices, + int length, CoinBigIndex offset, int tgt = -1); + +/// Initialize a vector with random numbers +void coin_init_random_vec(double *work, int n); + +//@} + + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveMonitor.hpp b/thirdparty/linux/include/coin1/CoinPresolveMonitor.hpp new file mode 100644 index 0000000..cef7a41 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveMonitor.hpp @@ -0,0 +1,105 @@ + +#ifndef CoinPresolveMonitor_H +#define CoinPresolveMonitor_H + +/*! + \brief Monitor a row or column for modification + + The purpose of this class is to monitor a row or column for modifications + during presolve and postsolve. Each object can monitor one row or + column. The initial copy of the row or column is loaded by the constructor. + Each subsequent call to checkAndTell() compares the current state of the row + or column with the stored state and reports any modifications. + + Internally the row or column is held as a CoinPackedVector so that it's + possible to follow a row or column through presolve (CoinPresolveMatrix) + and postsolve (CoinPostsolveMatrix). + + Do not underestimate the amount of work required here. Extracting a row from + the CoinPostsolve matrix requires a scan of every element in the matrix. + That's one scan by the constructor and one scan with every call to modify. + But that's precisely why it's virtually impossible to debug presolve without + aids. + + Parameter overloads for CoinPresolveMatrix and CoinPostsolveMatrix are a + little clumsy, but not a problem in use. The alternative is to add methods + to the CoinPresolveMatrix and CoinPostsolveMatrix classes that will only be + used for debugging. That's not too attractive either. +*/ +class CoinPresolveMonitor +{ + public: + + /*! \brief Default constructor + + Creates an empty monitor. + */ + CoinPresolveMonitor() ; + + /*! \brief Initialise from a CoinPresolveMatrix + + Load the initial row or column from a CoinPresolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPresolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Initialise from a CoinPostsolveMatrix + + Load the initial row or column from a CoinPostsolveMatrix. Set \p isRow + true for a row, false for a column. + */ + CoinPresolveMonitor(const CoinPostsolveMatrix *mtx, bool isRow, int k) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPresolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPresolveMatrix *mtx) ; + + /*! \brief Compare the present row or column against the stored copy and + report differences. + + Load the current row or column from a CoinPostsolveMatrix and compare. + Differences are printed to std::cout. + */ + void checkAndTell(const CoinPostsolveMatrix *mtx) ; + + private: + + /// Extract a row from a CoinPresolveMatrix + CoinPackedVector *extractRow(int i, const CoinPresolveMatrix *mtx) const ; + + /// Extract a column from a CoinPresolveMatrix + CoinPackedVector *extractCol(int j, const CoinPresolveMatrix *mtx) const ; + + /// Extract a row from a CoinPostsolveMatrix + CoinPackedVector *extractRow(int i, const CoinPostsolveMatrix *mtx) const ; + + /// Extract a column from a CoinPostsolveMatrix + CoinPackedVector *extractCol(int j, const CoinPostsolveMatrix *mtx) const ; + + /// Worker method underlying the public checkAndTell methods. + void checkAndTell(CoinPackedVector *curVec, double lb, double ub) ; + + /// True to monitor a row, false to monitor a column + bool isRow_ ; + + /// Row or column index + int ndx_ ; + + /*! The original row or column + + Sorted in increasing order of indices. + */ + CoinPackedVector *origVec_ ; + + /// Original row or column lower bound + double lb_ ; + + /// Original row or column upper bound + double ub_ ; +} ; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolvePsdebug.hpp b/thirdparty/linux/include/coin1/CoinPresolvePsdebug.hpp new file mode 100644 index 0000000..d72479a --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolvePsdebug.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinPresolvePsdebug.hpp 1560 2012-11-24 00:29:01Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolvePsdebug_H +#define CoinPresolvePsdebug_H + +/* + The current idea of the relation between PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY is that PRESOLVE_CONSISTENCY triggers the consistency + checks and PRESOLVE_DEBUG triggers consistency checks and output. + This isn't always true in the code, but that's the goal. Really, + the whole compile-time scheme should be replaced with something more + user-friendly (control variables that can be changed during the run). + + Also floating about are PRESOLVE_SUMMARY and COIN_PRESOLVE_TUNING. + -- lh, 111208 -- +*/ +/*! \defgroup PresolveDebugFunctions Presolve Debug Functions + + These functions implement consistency checks on data structures involved + in presolve and postsolve and on the components of the lp solution. + + To use these functions, include CoinPresolvePsdebug.hpp in your file and + define the compile-time constants PRESOLVE_SUMMARY, PRESOLVE_DEBUG, and + PRESOLVE_CONSISTENCY. A value is needed (<i>i.e.</i>, PRESOLVE_DEBUG=1). + In a few places, higher values will get you a bit more output. + + ******** + + Define the symbols PRESOLVE_DEBUG and PRESOLVE_CONSISTENCY on the configure + command line (use ADD_CXXFLAGS), in a Makefile, or similar and do a full + rebuild (including any presolve driver code). If the symbols are not + consistently nonzero across *all* presolve code, you'll get something + between garbage and a core dump! Debugging adds messages to CoinMessage + and allocates and maintains arrays that hold debug information. + + That said, given that you've configured and built with PRESOLVE_DEBUG and + PRESOLVE_CONSISTENCY nonzero everywhere, it's safe to adjust PRESOLVE_DEBUG + to values in the range 1..n in individual files to increase or decrease the + amount of output. + + The suggested approach for PRESOLVE_DEBUG is to define it to 1 in the build + and then increase it in individual presolve code files to get more detail. + + ******** +*/ +//@{ + +/*! \relates CoinPresolveMatrix + \brief Check column-major and/or row-major matrices for duplicate + entries in the major vectors. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_dups(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check the links which track storage order for major vectors in + the bulk storage area. + + By default, scans both the column- and row-major matrix. Set doCol = false to + suppress the column-major scan. Set doRow = false to suppres the row-major + scan. +*/ +void presolve_links_ok(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Check for explicit zeros in the column- and/or row-major matrices. + + By default, scans both the column- and row-major matrices. Set doCol (doRow) + to false to suppress the column (row) scan. +*/ +void presolve_no_zeros(const CoinPresolveMatrix *preObj, + bool doCol = true, bool doRow = true) ; + +/*! \relates CoinPresolveMatrix + \brief Checks for equivalence of the column- and row-major matrices. + + Normally the routine will test for coefficient presence and value. Set + \p chkvals to false to suppress the check for equal value. +*/ +void presolve_consistent(const CoinPresolveMatrix *preObj, + bool chkvals = true) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks that column threads agree with column lengths +*/ +void presolve_check_threads(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Checks the free list + + Scans the thread of free locations in the bulk store and checks that all + entries are reasonable (0 <= index < bulk0_). If chkElemCnt is true, it + also checks that the total number of entries in the matrix plus the + locations on the free list total to the size of the bulk store. Postsolve + routines do not maintain an accurate element count, but this is useful + for checking a newly constructed postsolve matrix. +*/ +void presolve_check_free_list(const CoinPostsolveMatrix *obj, + bool chkElemCnt = false) ; + +/*! \relates CoinPostsolveMatrix + \brief Check stored reduced costs for accuracy and consistency with + variable status. + + The routine will check the value of the reduced costs for architectural + variables (CoinPrePostsolveMatrix::rcosts_). It performs an accuracy check + by recalculating the reduced cost from scratch. It will also check the + value for consistency with the status information in + CoinPrePostsolveMatrix::colstat_. +*/ +void presolve_check_reduced_costs(const CoinPostsolveMatrix *obj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check the dual variables for consistency with row activity. + + The routine checks that the value of the dual variable is consistent + with the state of the constraint (loose, tight at lower bound, or tight at + upper bound). +*/ +void presolve_check_duals(const CoinPostsolveMatrix *postObj) ; + +/*! \relates CoinPresolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. By default, row activity is not checked (presolve is + sloppy about maintaining it). See the definitions in + CoinPresolvePsdebug.cpp for more information. +*/ +void presolve_check_sol(const CoinPresolveMatrix *preObj, + int chkColSol = 2, int chkRowAct = 1, + int chkStatus = 1) ; + +/*! \relates CoinPostsolveMatrix + \brief Check primal solution and architectural variable status. + + The architectural variables can be checked for bogus values, feasibility, + and valid status. The row activity is checked for bogus values, accuracy, + and feasibility. See the definitions in CoinPresolvePsdebug.cpp for more + information. +*/ +void presolve_check_sol(const CoinPostsolveMatrix *postObj, + int chkColSol = 2, int chkRowAct = 2, + int chkStatus = 1) ; + +/*! \relates CoinPresolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPresolveMatrix *preObj) ; + +/*! \relates CoinPostsolveMatrix + \brief Check for the proper number of basic variables. +*/ +void presolve_check_nbasic(const CoinPostsolveMatrix *postObj) ; + +//@} + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveSingleton.hpp b/thirdparty/linux/include/coin1/CoinPresolveSingleton.hpp new file mode 100644 index 0000000..10bc1cc --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveSingleton.hpp @@ -0,0 +1,112 @@ +/* $Id: CoinPresolveSingleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSingleton_H +#define CoinPresolveSingleton_H +#define SLACK_DOUBLETON 2 +#define SLACK_SINGLETON 8 + +/*! + \file +*/ + +//const int MAX_SLACK_DOUBLETONS = 1000; + +/*! \class slack_doubleton_action + \brief Convert an explicit bound constraint to a column bound + + This transform looks for explicit bound constraints for a variable and + transfers the bound to the appropriate column bound array. + The constraint is removed from the constraint system. +*/ +class slack_doubleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_doubleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_doubleton_action"); } + + /*! \brief Convert explicit bound constraints to column bounds. + + Not now There is a hard limit (#MAX_SLACK_DOUBLETONS) on the number of + constraints processed in a given call. \p notFinished is set to true + if candidates remain. + */ + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + bool ¬Finished); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_doubleton_action() { deleteAction(actions_,action*); } +}; +/*! \class slack_singleton_action + \brief For variables with one entry + + If we have a variable with one entry and no cost then we can + transform the row from E to G etc. + If there is a row objective region then we may be able to do + this even with a cost. +*/ +class slack_singleton_action : public CoinPresolveAction { + struct action { + double clo; + double cup; + + double rlo; + double rup; + + double coeff; + + int col; + int row; + }; + + const int nactions_; + const action *const actions_; + + slack_singleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), + actions_(actions) +{} + + public: + const char *name() const { return ("slack_singleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next, + double * rowObjective); + + void postsolve(CoinPostsolveMatrix *prob) const; + + + virtual ~slack_singleton_action() { deleteAction(actions_,action*); } +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveSubst.hpp b/thirdparty/linux/include/coin1/CoinPresolveSubst.hpp new file mode 100644 index 0000000..93822a5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveSubst.hpp @@ -0,0 +1,101 @@ +/* $Id: CoinPresolveSubst.hpp 1562 2012-11-24 00:36:15Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveSubst_H +#define CoinPresolveSubst_H + +/*! + \file +*/ + +#define SUBST_ROW 21 + +#include "CoinPresolveMatrix.hpp" + +/*! \class subst_constraint_action + \brief Detect and process implied free variables + + Consider a variable x. Suppose that we can find an equality such that the + bound on the equality, combined with + the bounds on the other variables involved in the equality, are such that + even the worst case values of the other variables still imply bounds for x + which are tighter than the variable's original bounds. Since x can never + reach its upper or lower bounds, it is an implied free variable. By solving + the equality for x and substituting for x in every other constraint + entangled with x, we can make x into a column singleton. Now x is an implied + free column singleton and both x and the equality can be removed. + + A similar transform for the case where the variable is a natural column + singleton is handled by #implied_free_action. In the current presolve + architecture, #implied_free_action is responsible for detecting implied free + variables that are natural column singletons or can be reduced to column + singletons. #implied_free_action calls subst_constraint_action to process + variables that must be reduced to column singletons. +*/ +class subst_constraint_action : public CoinPresolveAction { +private: + subst_constraint_action(); + subst_constraint_action(const subst_constraint_action& rhs); + subst_constraint_action& operator=(const subst_constraint_action& rhs); + + struct action { + double *rlos; + double *rups; + + double *coeffxs; + int *rows; + + int *ninrowxs; + int *rowcolsxs; + double *rowelsxs; + + const double *costsx; + int col; + int rowy; + + int nincol; + }; + + const int nactions_; + // actions_ is owned by the class and must be deleted at destruction + const action *const actions_; + + subst_constraint_action(int nactions, + action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *implied_free, + const int * which, + int numberFree, + const CoinPresolveAction *next, + int fill_level); + static const CoinPresolveAction *presolveX(CoinPresolveMatrix * prob, + const CoinPresolveAction *next, + int fillLevel); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~subst_constraint_action(); +}; + + + + + +/*static*/ void implied_bounds(const double *els, + const double *clo, const double *cup, + const int *hcol, + CoinBigIndex krs, CoinBigIndex kre, + double *maxupp, double *maxdownp, + int jcol, + double rlo, double rup, + double *iclb, double *icub); +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveTighten.hpp b/thirdparty/linux/include/coin1/CoinPresolveTighten.hpp new file mode 100644 index 0000000..3a5319b --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveTighten.hpp @@ -0,0 +1,55 @@ +/* $Id: CoinPresolveTighten.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTighten_H +#define CoinPresolveTighten_H + +#include "CoinPresolveMatrix.hpp" + +// This action has no separate class; +// instead, it decides which columns can be made fixed +// and calls make_fixed_action::presolve. +const CoinPresolveAction *tighten_zero_cost(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#define DO_TIGHTEN 30 + +class do_tighten_action : public CoinPresolveAction { + do_tighten_action(); + do_tighten_action(const do_tighten_action& rhs); + do_tighten_action& operator=(const do_tighten_action& rhs); + + struct action { + int *rows; + double *lbound; + double *ubound; + int col; + int nrows; + int direction; // just for assertions + }; + + const int nactions_; + const action *const actions_; + + do_tighten_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) {} + + public: + const char *name() const; + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~do_tighten_action(); + +}; +#endif + + diff --git a/thirdparty/linux/include/coin1/CoinPresolveTripleton.hpp b/thirdparty/linux/include/coin1/CoinPresolveTripleton.hpp new file mode 100644 index 0000000..eaa79c5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveTripleton.hpp @@ -0,0 +1,66 @@ +/* $Id: CoinPresolveTripleton.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveTripleton_H +#define CoinPresolveTripleton_H +#define TRIPLETON 11 +/** We are only going to do this if it does not increase number of elements?. + It could be generalized to more than three but it seems unlikely it would + help. + + As it is adapted from doubleton icoly is one dropped. + */ +class tripleton_action : public CoinPresolveAction { + public: + struct action { + int icolx; + int icolz; + int row; + + int icoly; + double cloy; + double cupy; + double costy; + double clox; + double cupx; + double costx; + + double rlo; + double rup; + + double coeffx; + double coeffy; + double coeffz; + + double *colel; + + int ncolx; + int ncoly; + }; + + const int nactions_; + const action *const actions_; + + private: + tripleton_action(int nactions, + const action *actions, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nactions_(nactions), actions_(actions) +{} + + public: + const char *name() const { return ("tripleton_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~tripleton_action(); +}; +#endif + + diff --git a/thirdparty/linux/include/coin1/CoinPresolveUseless.hpp b/thirdparty/linux/include/coin1/CoinPresolveUseless.hpp new file mode 100644 index 0000000..624a373 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveUseless.hpp @@ -0,0 +1,63 @@ +/* $Id: CoinPresolveUseless.hpp 1566 2012-11-29 19:33:56Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveUseless_H +#define CoinPresolveUseless_H +#define USELESS 20 + +class useless_constraint_action : public CoinPresolveAction { + struct action { + double rlo; + double rup; + const int *rowcols; + const double *rowels; + int row; + int ninrow; + }; + + const int nactions_; + const action *const actions_; + + useless_constraint_action(int nactions, + const action *actions, + const CoinPresolveAction *next); + + public: + const char *name() const; + + // These rows are asserted to be useless, + // that is, given a solution the row activity + // must be in range. + static const CoinPresolveAction *presolve(CoinPresolveMatrix * prob, + const int *useless_rows, + int nuseless_rows, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~useless_constraint_action(); + +}; + +/*! \relates useless_constraint_action + \brief Scan constraints looking for useless constraints + + A front end to identify useless constraints and hand them to + useless_constraint_action::presolve() for processing. + + In a bit more detail, the routine implements a greedy algorithm that + identifies a set of necessary constraints. A constraint is necessary if it + implies a tighter bound on a variable than the original column bound. These + tighter column bounds are then used to calculate row activity and identify + constraints that are useless given the presence of the necessary + constraints. +*/ + +const CoinPresolveAction *testRedundant(CoinPresolveMatrix *prob, + const CoinPresolveAction *next) ; + + + +#endif diff --git a/thirdparty/linux/include/coin1/CoinPresolveZeros.hpp b/thirdparty/linux/include/coin1/CoinPresolveZeros.hpp new file mode 100644 index 0000000..219e613 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinPresolveZeros.hpp @@ -0,0 +1,60 @@ +/* $Id: CoinPresolveZeros.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinPresolveZeros_H +#define CoinPresolveZeros_H + +/*! \file + + Drop/reintroduce explicit zeros. +*/ + +#define DROP_ZERO 8 + +/*! \brief Tracking information for an explicit zero coefficient + + \todo Why isn't this a nested class in drop_zero_coefficients_action? + That would match the structure of other presolve classes. +*/ + +struct dropped_zero { + int row; + int col; +}; + +/*! \brief Removal of explicit zeros + + The presolve action for this class removes explicit zeros from the constraint + matrix. The postsolve action puts them back. +*/ +class drop_zero_coefficients_action : public CoinPresolveAction { + + const int nzeros_; + const dropped_zero *const zeros_; + + drop_zero_coefficients_action(int nzeros, + const dropped_zero *zeros, + const CoinPresolveAction *next) : + CoinPresolveAction(next), + nzeros_(nzeros), zeros_(zeros) +{} + + public: + const char *name() const { return ("drop_zero_coefficients_action"); } + + static const CoinPresolveAction *presolve(CoinPresolveMatrix *prob, + int *checkcols, + int ncheckcols, + const CoinPresolveAction *next); + + void postsolve(CoinPostsolveMatrix *prob) const; + + virtual ~drop_zero_coefficients_action() { deleteAction(zeros_,dropped_zero*); } +}; + +const CoinPresolveAction *drop_zero_coefficients(CoinPresolveMatrix *prob, + const CoinPresolveAction *next); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinRational.hpp b/thirdparty/linux/include/coin1/CoinRational.hpp new file mode 100644 index 0000000..bfbfa5f --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinRational.hpp @@ -0,0 +1,44 @@ +// Authors: Matthew Saltzman and Ted Ralphs +// Copyright 2015, Matthew Saltzman and Ted Ralphs +// Licensed under the Eclipse Public License 1.0 + +#ifndef CoinRational_H +#define CoinRational_H + +#include <cmath> + +//Small class for rational numbers +class CoinRational +{ + +public : + long getDenominator() { return denominator_; } + long getNumerator() { return numerator_; } + + CoinRational(): + numerator_(0), + denominator_(1) + {}; + + CoinRational(long n, long d): + numerator_(n), + denominator_(d) + {}; + + CoinRational(double val, double maxdelta, long maxdnom) + { + if (!nearestRational_(val, maxdelta, maxdnom)){ + numerator_ = 0; + denominator_ = 1; + } + }; + +private : + + long numerator_; + long denominator_; + + bool nearestRational_(double val, double maxdelta, long maxdnom); +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinSearchTree.hpp b/thirdparty/linux/include/coin1/CoinSearchTree.hpp new file mode 100644 index 0000000..a0ce8e3 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSearchTree.hpp @@ -0,0 +1,465 @@ +/* $Id: CoinSearchTree.hpp 1685 2014-01-27 03:05:07Z tkr $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSearchTree_H +#define CoinSearchTree_H + +#include <vector> +#include <algorithm> +#include <cmath> +#include <string> + +#include "CoinFinite.hpp" +#include "CoinHelperFunctions.hpp" + +// #define DEBUG_PRINT + +//############################################################################# + +class BitVector128 { + friend bool operator<(const BitVector128& b0, const BitVector128& b1); +private: + unsigned int bits_[4]; +public: + BitVector128(); + BitVector128(unsigned int bits[4]); + ~BitVector128() {} + void set(unsigned int bits[4]); + void setBit(int i); + void clearBit(int i); + std::string str() const; +}; + +bool operator<(const BitVector128& b0, const BitVector128& b1); + +//############################################################################# + +/** A class from which the real tree nodes should be derived from. Some of the + data that undoubtedly exist in the real tree node is replicated here for + fast access. This class is used in the various comparison functions. */ +class CoinTreeNode { +protected: + CoinTreeNode() : + depth_(-1), + fractionality_(-1), + quality_(-COIN_DBL_MAX), + true_lower_bound_(-COIN_DBL_MAX), + preferred_() {} + CoinTreeNode(int d, + int f = -1, + double q = -COIN_DBL_MAX, + double tlb = -COIN_DBL_MAX, + BitVector128 p = BitVector128()) : + depth_(d), + fractionality_(f), + quality_(q), + true_lower_bound_(tlb), + preferred_(p) {} + CoinTreeNode(const CoinTreeNode& x) : + depth_(x.depth_), + fractionality_(x.fractionality_), + quality_(x.quality_), + true_lower_bound_(x.true_lower_bound_), + preferred_(x.preferred_) {} + CoinTreeNode& operator=(const CoinTreeNode& x) { + if (this != &x) { + depth_ = x.depth_; + fractionality_ = x.fractionality_; + quality_ = x.quality_; + true_lower_bound_ = x.true_lower_bound_; + preferred_ = x.preferred_; + } + return *this; + } +private: + /// The depth of the node in the tree + int depth_; + /** A measure of fractionality, e.g., the number of unsatisfied + integrality requirements */ + int fractionality_; + /** Some quality for the node. For normal branch-and-cut problems the LP + relaxation value will do just fine. It is probably an OK approximation + even if column generation is done. */ + double quality_; + /** A true lower bound on the node. May be -infinity. For normal + branch-and-cut problems the LP relaxation value is OK. It is different + when column generation is done. */ + double true_lower_bound_; + /** */ + BitVector128 preferred_; +public: + virtual ~CoinTreeNode() {} + + inline int getDepth() const { return depth_; } + inline int getFractionality() const { return fractionality_; } + inline double getQuality() const { return quality_; } + inline double getTrueLB() const { return true_lower_bound_; } + inline BitVector128 getPreferred() const { return preferred_; } + + inline void setDepth(int d) { depth_ = d; } + inline void setFractionality(int f) { fractionality_ = f; } + inline void setQuality(double q) { quality_ = q; } + inline void setTrueLB(double tlb) { true_lower_bound_ = tlb; } + inline void setPreferred(BitVector128 p) { preferred_ = p; } +}; + +//============================================================================== + +class CoinTreeSiblings { +private: + CoinTreeSiblings(); + CoinTreeSiblings& operator=(const CoinTreeSiblings&); +private: + int current_; + int numSiblings_; + CoinTreeNode** siblings_; +public: + CoinTreeSiblings(const int n, CoinTreeNode** nodes) : + current_(0), numSiblings_(n), siblings_(new CoinTreeNode*[n]) + { + CoinDisjointCopyN(nodes, n, siblings_); + } + CoinTreeSiblings(const CoinTreeSiblings& s) : + current_(s.current_), + numSiblings_(s.numSiblings_), + siblings_(new CoinTreeNode*[s.numSiblings_]) + { + CoinDisjointCopyN(s.siblings_, s.numSiblings_, siblings_); + } + ~CoinTreeSiblings() { delete[] siblings_; } + inline CoinTreeNode* currentNode() const { return siblings_[current_]; } + /** returns false if cannot be advanced */ + inline bool advanceNode() { return ++current_ != numSiblings_; } + inline int toProcess() const { return numSiblings_ - current_; } + inline int size() const { return numSiblings_; } + inline void printPref() const { + for (int i = 0; i < numSiblings_; ++i) { + std::string pref = siblings_[i]->getPreferred().str(); + printf("prefs of sibligs: sibling[%i]: %s\n", i, pref.c_str()); + } + } +}; + +//############################################################################# + +/** Function objects to compare search tree nodes. The comparison function + must return true if the first argument is "better" than the second one, + i.e., it should be processed first. */ +/*@{*/ +/** Depth First Search. */ +struct CoinSearchTreeComparePreferred { + static inline const char* name() { return "CoinSearchTreeComparePreferred"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + register const CoinTreeNode* xNode = x->currentNode(); + register const CoinTreeNode* yNode = y->currentNode(); + const BitVector128 xPref = xNode->getPreferred(); + const BitVector128 yPref = yNode->getPreferred(); + bool retval = true; + if (xPref < yPref) { + retval = true; + } else if (yPref < xPref) { + retval = false; + } else { + retval = xNode->getQuality() < yNode->getQuality(); + } +#ifdef DEBUG_PRINT + printf("Comparing xpref (%s) and ypref (%s) : %s\n", + xpref.str().c_str(), ypref.str().c_str(), retval ? "T" : "F"); +#endif + return retval; + } +}; + +//----------------------------------------------------------------------------- +/** Depth First Search. */ +struct CoinSearchTreeCompareDepth { + static inline const char* name() { return "CoinSearchTreeCompareDepth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { +#if 1 + return x->currentNode()->getDepth() >= y->currentNode()->getDepth(); +#else + if(x->currentNode()->getDepth() > y->currentNode()->getDepth()) + return 1; + if(x->currentNode()->getDepth() == y->currentNode()->getDepth() && + x->currentNode()->getQuality() <= y->currentNode()->getQuality()) + return 1; + return 0; +#endif + } +}; + +//----------------------------------------------------------------------------- +/* Breadth First Search */ +struct CoinSearchTreeCompareBreadth { + static inline const char* name() { return "CoinSearchTreeCompareBreadth"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getDepth() < y->currentNode()->getDepth(); + } +}; + +//----------------------------------------------------------------------------- +/** Best first search */ +struct CoinSearchTreeCompareBest { + static inline const char* name() { return "CoinSearchTreeCompareBest"; } + inline bool operator()(const CoinTreeSiblings* x, + const CoinTreeSiblings* y) const { + return x->currentNode()->getQuality() < y->currentNode()->getQuality(); + } +}; + +//############################################################################# + +class CoinSearchTreeBase +{ +private: + CoinSearchTreeBase(const CoinSearchTreeBase&); + CoinSearchTreeBase& operator=(const CoinSearchTreeBase&); + +protected: + std::vector<CoinTreeSiblings*> candidateList_; + int numInserted_; + int size_; + +protected: + CoinSearchTreeBase() : candidateList_(), numInserted_(0), size_(0) {} + + virtual void realpop() = 0; + virtual void realpush(CoinTreeSiblings* s) = 0; + virtual void fixTop() = 0; + +public: + virtual ~CoinSearchTreeBase() {} + virtual const char* compName() const = 0; + + inline const std::vector<CoinTreeSiblings*>& getCandidates() const { + return candidateList_; + } + inline bool empty() const { return candidateList_.empty(); } + inline int size() const { return size_; } + inline int numInserted() const { return numInserted_; } + inline CoinTreeNode* top() const { + if (size_ == 0) + return NULL; +#ifdef DEBUG_PRINT + char output[44]; + output[43] = 0; + candidateList_.front()->currentNode()->getPreferred().print(output); + printf("top's pref: %s\n", output); +#endif + return candidateList_.front()->currentNode(); + } + /** pop will advance the \c next pointer among the siblings on the top and + then moves the top to its correct position. #realpop is the method + that actually removes the element from the heap */ + inline void pop() { + CoinTreeSiblings* s = candidateList_.front(); + if (!s->advanceNode()) { + realpop(); + delete s; + } else { + fixTop(); + } + --size_; + } + inline void push(int numNodes, CoinTreeNode** nodes, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(numNodes, nodes); + realpush(s); + if (incrInserted) { + numInserted_ += numNodes; + } + size_ += numNodes; + } + inline void push(const CoinTreeSiblings& sib, + const bool incrInserted = true) { + CoinTreeSiblings* s = new CoinTreeSiblings(sib); +#ifdef DEBUG_PRINT + s->printPref(); +#endif + realpush(s); + if (incrInserted) { + numInserted_ += sib.toProcess(); + } + size_ += sib.toProcess(); + } +}; + +//############################################################################# + +// #define CAN_TRUST_STL_HEAP +#ifdef CAN_TRUST_STL_HEAP + +template <class Comp> +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; +protected: + virtual void realpop() { + candidateList_.pop_back(); + } + virtual void fixTop() { + CoinTreeSiblings* s = top(); + realpop(); + push(s, false); + } + virtual void realpush(CoinTreeSiblings* s) { + nodes_.push_back(s); + std::push_heap(candidateList_.begin(), candidateList_.end(), comp_); + } +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::make_heap(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted_; + size_ = t.size_; + } + ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#else + +template <class Comp> +class CoinSearchTree : public CoinSearchTreeBase +{ +private: + Comp comp_; + +protected: + virtual void realpop() { + candidateList_[0] = candidateList_.back(); + candidateList_.pop_back(); + fixTop(); + } + /** After changing data in the top node, fix the heap */ + virtual void fixTop() { + const size_t size = candidateList_.size(); + if (size > 1) { + CoinTreeSiblings** candidates = &candidateList_[0]; + CoinTreeSiblings* s = candidates[0]; + --candidates; + size_t pos = 1; + size_t ch; + for (ch = 2; ch < size; pos = ch, ch *= 2) { + if (comp_(candidates[ch+1], candidates[ch])) + ++ch; + if (comp_(s, candidates[ch])) + break; + candidates[pos] = candidates[ch]; + } + if (ch == size) { + if (comp_(candidates[ch], s)) { + candidates[pos] = candidates[ch]; + pos = ch; + } + } + candidates[pos] = s; + } + } + virtual void realpush(CoinTreeSiblings* s) { + candidateList_.push_back(s); + CoinTreeSiblings** candidates = &candidateList_[0]; + --candidates; + size_t pos = candidateList_.size(); + size_t ch; + for (ch = pos/2; ch != 0; pos = ch, ch /= 2) { + if (comp_(candidates[ch], s)) + break; + candidates[pos] = candidates[ch]; + } + candidates[pos] = s; + } + +public: + CoinSearchTree() : CoinSearchTreeBase(), comp_() {} + CoinSearchTree(const CoinSearchTreeBase& t) : + CoinSearchTreeBase(), comp_() { + candidateList_ = t.getCandidates(); + std::sort(candidateList_.begin(), candidateList_.end(), comp_); + numInserted_ = t.numInserted(); + size_ = t.size(); + } + virtual ~CoinSearchTree() {} + const char* compName() const { return Comp::name(); } +}; + +#endif + +//############################################################################# + +enum CoinNodeAction { + CoinAddNodeToCandidates, + CoinTestNodeForDiving, + CoinDiveIntoNode +}; + +class CoinSearchTreeManager +{ +private: + CoinSearchTreeManager(const CoinSearchTreeManager&); + CoinSearchTreeManager& operator=(const CoinSearchTreeManager&); +private: + CoinSearchTreeBase* candidates_; + int numSolution; + /** Whether there is an upper bound or not. The upper bound may have come + as input, not necessarily from a solution */ + bool hasUB_; + + /** variable used to test whether we need to reevaluate search strategy */ + bool recentlyReevaluatedSearchStrategy_; + +public: + CoinSearchTreeManager() : + candidates_(NULL), + numSolution(0), + recentlyReevaluatedSearchStrategy_(true) + {} + virtual ~CoinSearchTreeManager() { + delete candidates_; + } + + inline void setTree(CoinSearchTreeBase* t) { + delete candidates_; + candidates_ = t; + } + inline CoinSearchTreeBase* getTree() const { + return candidates_; + } + + inline bool empty() const { return candidates_->empty(); } + inline size_t size() const { return candidates_->size(); } + inline size_t numInserted() const { return candidates_->numInserted(); } + inline CoinTreeNode* top() const { return candidates_->top(); } + inline void pop() { candidates_->pop(); } + inline void push(CoinTreeNode* node, const bool incrInserted = true) { + candidates_->push(1, &node, incrInserted); + } + inline void push(const CoinTreeSiblings& s, const bool incrInserted=true) { + candidates_->push(s, incrInserted); + } + inline void push(const int n, CoinTreeNode** nodes, + const bool incrInserted = true) { + candidates_->push(n, nodes, incrInserted); + } + + inline CoinTreeNode* bestQualityCandidate() const { + return candidates_->top(); + } + inline double bestQuality() const { + return candidates_->top()->getQuality(); + } + void newSolution(double solValue); + void reevaluateSearchStrategy(); +}; + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin1/CoinShallowPackedVector.hpp b/thirdparty/linux/include/coin1/CoinShallowPackedVector.hpp new file mode 100644 index 0000000..07c1870 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinShallowPackedVector.hpp @@ -0,0 +1,148 @@ +/* $Id: CoinShallowPackedVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinShallowPackedVector_H +#define CoinShallowPackedVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include "CoinError.hpp" +#include "CoinPackedVectorBase.hpp" + +/** Shallow Sparse Vector + +This class is for sparse vectors where the indices and +elements are stored elsewhere. This class only maintains +pointers to the indices and elements. Since this class +does not own the index and element data it provides +read only access to to the data. An CoinSparsePackedVector +must be used when the sparse vector's data will be altered. + +This class stores pointers to the vectors. +It does not actually contain the vectors. + +Here is a sample usage: +@verbatim + const int ne = 4; + int inx[ne] = { 1, 4, 0, 2 }; + double el[ne] = { 10., 40., 1., 50. }; + + // Create vector and set its value + CoinShallowPackedVector r(ne,inx,el); + + // access each index and element + assert( r.indices ()[0]== 1 ); + assert( r.elements()[0]==10. ); + assert( r.indices ()[1]== 4 ); + assert( r.elements()[1]==40. ); + assert( r.indices ()[2]== 0 ); + assert( r.elements()[2]== 1. ); + assert( r.indices ()[3]== 2 ); + assert( r.elements()[3]==50. ); + + // access as a full storage vector + assert( r[ 0]==1. ); + assert( r[ 1]==10.); + assert( r[ 2]==50.); + assert( r[ 3]==0. ); + assert( r[ 4]==40.); + + // Tests for equality and equivalence + CoinShallowPackedVector r1; + r1=r; + assert( r==r1 ); + r.sort(CoinIncrElementOrdered()); + assert( r!=r1 ); + + // Add packed vectors. + // Similarly for subtraction, multiplication, + // and division. + CoinPackedVector add = r + r1; + assert( add[0] == 1.+ 1. ); + assert( add[1] == 10.+10. ); + assert( add[2] == 50.+50. ); + assert( add[3] == 0.+ 0. ); + assert( add[4] == 40.+40. ); + assert( r.sum() == 10.+40.+1.+50. ); +@endverbatim +*/ +class CoinShallowPackedVector : public CoinPackedVectorBase { + friend void CoinShallowPackedVectorUnitTest(); + +public: + + /**@name Get methods */ + //@{ + /// Get length of indices and elements vectors + virtual int getNumElements() const { return nElements_; } + /// Get indices of elements + virtual const int * getIndices() const { return indices_; } + /// Get element values + virtual const double * getElements() const { return elements_; } + //@} + + /**@name Set methods */ + //@{ + /// Reset the vector (as if were just created an empty vector) + void clear(); + /** Assignment operator. */ + CoinShallowPackedVector& operator=(const CoinShallowPackedVector & x); + /** Assignment operator from a CoinPackedVectorBase. */ + CoinShallowPackedVector& operator=(const CoinPackedVectorBase & x); + /** just like the explicit constructor */ + void setVector(int size, const int * indices, const double * elements, + bool testForDuplicateIndex = true); + //@} + + /**@name Methods to create, set and destroy */ + //@{ + /** Default constructor. */ + CoinShallowPackedVector(bool testForDuplicateIndex = true); + /** Explicit Constructor. + Set vector size, indices, and elements. Size is the length of both the + indices and elements vectors. The indices and elements vectors are not + copied into this class instance. The ShallowPackedVector only maintains + the pointers to the indices and elements vectors. <br> + The last argument specifies whether the creator of the object knows in + advance that there are no duplicate indices. + */ + CoinShallowPackedVector(int size, + const int * indices, const double * elements, + bool testForDuplicateIndex = true); + /** Copy constructor from the base class. */ + CoinShallowPackedVector(const CoinPackedVectorBase &); + /** Copy constructor. */ + CoinShallowPackedVector(const CoinShallowPackedVector &); + /** Destructor. */ + virtual ~CoinShallowPackedVector() {} + /// Print vector information. + void print(); + //@} + +private: + /**@name Private member data */ + //@{ + /// Vector indices + const int * indices_; + ///Vector elements + const double * elements_; + /// Size of indices and elements vectors + int nElements_; + //@} +}; + +//############################################################################# +/** A function that tests the methods in the CoinShallowPackedVector class. The + only reason for it not to be a member method is that this way it doesn't + have to be compiled into the library. And that's a gain, because the + library should be compiled with optimization on, but this method should be + compiled with debugging. */ +void +CoinShallowPackedVectorUnitTest(); + +#endif diff --git a/thirdparty/linux/include/coin1/CoinSignal.hpp b/thirdparty/linux/include/coin1/CoinSignal.hpp new file mode 100644 index 0000000..2bbf0d0 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSignal.hpp @@ -0,0 +1,117 @@ +/* $Id: CoinSignal.hpp 1810 2015-03-13 20:16:34Z tkr $ */ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinSignal_hpp +#define _CoinSignal_hpp + +// This file is fully docified. +// There's nothing to docify... + +//############################################################################# + +#include <csignal> + +//############################################################################# + +#if defined(_MSC_VER) + typedef void (__cdecl *CoinSighandler_t) (int); +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if (defined(__GNUC__) && defined(__linux__)) + typedef sighandler_t CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MINGW32__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__FreeBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(__NetBSD__) && defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//----------------------------------------------------------------------------- + +#if defined(_AIX) +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined (__hpux) +# define CoinSighandler_t_defined +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# else + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__sun) +# if defined(__SUNPRO_CC) +# include <signal.h> + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +# define CoinSighandler_t_defined +# endif +# if defined(__GNUC__) + typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +# endif +#endif + +//----------------------------------------------------------------------------- + +#if defined(__MACH__) && defined(__GNUC__) +typedef __decltype(SIG_DFL) CoinSighandler_t; +# define CoinSighandler_t_defined +#endif + +//############################################################################# + +#ifndef CoinSighandler_t_defined +# warning("OS and/or compiler is not recognized. Defaulting to:"); +# warning("extern 'C' {") +# warning(" typedef void (*CoinSighandler_t) (int);") +# warning("}") + extern "C" { + typedef void (*CoinSighandler_t) (int); + } +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin1/CoinSimpFactorization.hpp b/thirdparty/linux/include/coin1/CoinSimpFactorization.hpp new file mode 100644 index 0000000..242b6cd --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSimpFactorization.hpp @@ -0,0 +1,431 @@ +/* $Id: CoinSimpFactorization.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/* + This is a simple factorization of the LP Basis + */ +#ifndef CoinSimpFactorization_H +#define CoinSimpFactorization_H + +#include <iostream> +#include <string> +#include <cassert> +#include "CoinTypes.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinDenseFactorization.hpp" +class CoinPackedMatrix; + + +/// pointers used during factorization +class FactorPointers{ +public: + double *rowMax; + int *firstRowKnonzeros; + int *prevRow; + int *nextRow; + int *firstColKnonzeros; + int *prevColumn; + int *nextColumn; + int *newCols; + //constructor + FactorPointers( int numRows, int numCols, int *UrowLengths_, int *UcolLengths_ ); + // destructor + ~ FactorPointers(); +}; + +class CoinSimpFactorization : public CoinOtherFactorization { + friend void CoinSimpFactorizationUnitTest( const std::string & mpsDir ); + +public: + + /**@name Constructors and destructor and copy */ + //@{ + /// Default constructor + CoinSimpFactorization ( ); + /// Copy constructor + CoinSimpFactorization ( const CoinSimpFactorization &other); + + /// Destructor + virtual ~CoinSimpFactorization ( ); + /// = copy + CoinSimpFactorization & operator = ( const CoinSimpFactorization & other ); + /// Clone + virtual CoinOtherFactorization * clone() const ; + //@} + + /**@name Do factorization - public */ + //@{ + /// Gets space for a factorization + virtual void getAreas ( int numberRows, + int numberColumns, + CoinBigIndex maximumL, + CoinBigIndex maximumU ); + + /// PreProcesses column ordered copy of basis + virtual void preProcess ( ); + /** Does most of factorization returning status + 0 - OK + -99 - needs more memory + -1 - singular - use numberGoodColumns and redo + */ + virtual int factor ( ); + /// Does post processing on valid factorization - putting variables on correct rows + virtual void postProcess(const int * sequence, int * pivotVariable); + /// Makes a non-singular basis by replacing variables + virtual void makeNonSingular(int * sequence, int numberColumns); + //@} + + /**@name general stuff such as status */ + //@{ + /// Total number of elements in factorization + virtual inline int numberElements ( ) const { + return numberRows_*(numberColumns_+numberPivots_); + } + /// Returns maximum absolute value in factorization + double maximumCoefficient() const; + //@} + + /**@name rank one updates which do exist */ + //@{ + + /** Replaces one Column to basis, + returns 0=OK, 1=Probably OK, 2=singular, 3=no room + If checkBeforeModifying is true will do all accuracy checks + before modifying factorization. Whether to set this depends on + speed considerations. You could just do this on first iteration + after factorization and thereafter re-factorize + partial update already in U */ + virtual int replaceColumn ( CoinIndexedVector * regionSparse, + int pivotRow, + double pivotCheck , + bool checkBeforeModifying=false, + double acceptablePivot=1.0e-8); + //@} + + /**@name various uses of factorization (return code number elements) + which user may want to know about */ + //@{ + /** Updates one column (FTRAN) from regionSparse2 + Tries to do FT update + number returned is negative if no room + regionSparse starts as zero and is zero at end. + Note - if regionSparse2 packed on input - will be packed on output + */ + + virtual int updateColumnFT ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false); + + /** This version has same effect as above with FTUpdate==false + so number returned is always >=0 */ + virtual int updateColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false) const; + /// does FTRAN on two columns + virtual int updateTwoColumnsFT(CoinIndexedVector * regionSparse1, + CoinIndexedVector * regionSparse2, + CoinIndexedVector * regionSparse3, + bool noPermute=false); + /// does updatecolumn if save==true keeps column for replace column + int upColumn ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2, + bool noPermute=false, bool save=false) const; + /** Updates one column (BTRAN) from regionSparse2 + regionSparse starts as zero and is zero at end + Note - if regionSparse2 packed on input - will be packed on output + */ + virtual int updateColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + /// does updateColumnTranspose, the other is a wrapper + int upColumnTranspose ( CoinIndexedVector * regionSparse, + CoinIndexedVector * regionSparse2) const; + //@} + /// *** Below this user may not want to know about + + /**@name various uses of factorization + which user may not want to know about (left over from my LP code) */ + //@{ + /// Get rid of all memory + inline void clearArrays() + { gutsOfDestructor();} + /// Returns array to put basis indices in + inline int * indices() const + { return reinterpret_cast<int *> (elements_+numberRows_*numberRows_);} + /// Returns permute in + virtual inline int * permute() const + { return pivotRow_;} + //@} + + /// The real work of destructor + void gutsOfDestructor(); + /// The real work of constructor + void gutsOfInitialize(); + /// The real work of copy + void gutsOfCopy(const CoinSimpFactorization &other); + + + /// calls factorization + void factorize(int numberOfRows, + int numberOfColumns, + const int colStarts[], + const int indicesRow[], + const double elements[]); + /// main loop of factorization + int mainLoopFactor (FactorPointers &pointers ); + /// copies L by rows + void copyLbyRows(); + /// copies U by columns + void copyUbyColumns(); + /// finds a pivot element using Markowitz count + int findPivot(FactorPointers &pointers, int &r, int &s, bool &ifSlack); + /// finds a pivot in a shortest column + int findPivotShCol(FactorPointers &pointers, int &r, int &s); + /// finds a pivot in the first column available + int findPivotSimp(FactorPointers &pointers, int &r, int &s); + /// does Gauss elimination + void GaussEliminate(FactorPointers &pointers, int &r, int &s); + /// finds short row that intersects a given column + int findShortRow(const int column, const int length, int &minRow, + int &minRowLength, FactorPointers &pointers); + /// finds short column that intersects a given row + int findShortColumn(const int row, const int length, int &minCol, + int &minColLength, FactorPointers &pointers); + /// finds maximum absolute value in a row + double findMaxInRrow(const int row, FactorPointers &pointers); + /// does pivoting + void pivoting(const int pivotRow, const int pivotColumn, + const double invPivot, FactorPointers &pointers); + /// part of pivoting + void updateCurrentRow(const int pivotRow, const int row, + const double multiplier, FactorPointers &pointers, + int &newNonZeros); + /// allocates more space for L + void increaseLsize(); + /// allocates more space for a row of U + void increaseRowSize(const int row, const int newSize); + /// allocates more space for a column of U + void increaseColSize(const int column, const int newSize, const bool b); + /// allocates more space for rows of U + void enlargeUrow(const int numNewElements); + /// allocates more space for columns of U + void enlargeUcol(const int numNewElements, const bool b); + /// finds a given row in a column + int findInRow(const int row, const int column); + /// finds a given column in a row + int findInColumn(const int column, const int row); + /// declares a row inactive + void removeRowFromActSet(const int row, FactorPointers &pointers); + /// declares a column inactive + void removeColumnFromActSet(const int column, FactorPointers &pointers); + /// allocates space for U + void allocateSpaceForU(); + /// allocates several working arrays + void allocateSomeArrays(); + /// initializes some numbers + void initialSomeNumbers(); + /// solves L x = b + void Lxeqb(double *b) const; + /// same as above but with two rhs + void Lxeqb2(double *b1, double *b2) const; + /// solves U x = b + void Uxeqb(double *b, double *sol) const; + /// same as above but with two rhs + void Uxeqb2(double *b1, double *sol1, double *sol2, double *b2) const; + /// solves x L = b + void xLeqb(double *b) const; + /// solves x U = b + void xUeqb(double *b, double *sol) const; + /// updates factorization after a Simplex iteration + int LUupdate(int newBasicCol); + /// creates a new eta vector + void newEta(int row, int numNewElements); + /// makes a copy of row permutations + void copyRowPermutations(); + /// solves H x = b, where H is a product of eta matrices + void Hxeqb(double *b) const; + /// same as above but with two rhs + void Hxeqb2(double *b1, double *b2) const; + /// solves x H = b + void xHeqb(double *b) const; + /// does FTRAN + void ftran(double *b, double *sol, bool save) const; + /// same as above but with two columns + void ftran2(double *b1, double *sol1, double *b2, double *sol2) const; + /// does BTRAN + void btran(double *b, double *sol) const; + ///--------------------------------------- + + + + //@} +protected: + /** Returns accuracy status of replaceColumn + returns 0=OK, 1=Probably OK, 2=singular */ + int checkPivot(double saveFromU, double oldPivot) const; +////////////////// data ////////////////// +protected: + + /**@name data */ + //@{ + /// work array (should be initialized to zero) + double *denseVector_; + /// work array + double *workArea2_; + /// work array + double *workArea3_; + /// array of labels (should be initialized to zero) + int *vecLabels_; + /// array of indices + int *indVector_; + + /// auxiliary vector + double *auxVector_; + /// auxiliary vector + int *auxInd_; + + /// vector to keep for LUupdate + double *vecKeep_; + /// indices of this vector + int *indKeep_; + /// number of nonzeros + mutable int keepSize_; + + + + /// Starts of the rows of L + int *LrowStarts_; + /// Lengths of the rows of L + int *LrowLengths_; + /// L by rows + double *Lrows_; + /// indices in the rows of L + int *LrowInd_; + /// Size of Lrows_; + int LrowSize_; + /// Capacity of Lrows_ + int LrowCap_; + + /// Starts of the columns of L + int *LcolStarts_; + /// Lengths of the columns of L + int *LcolLengths_; + /// L by columns + double *Lcolumns_; + /// indices in the columns of L + int *LcolInd_; + /// numbers of elements in L + int LcolSize_; + /// maximum capacity of L + int LcolCap_; + + + /// Starts of the rows of U + int *UrowStarts_; + /// Lengths of the rows of U + int *UrowLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the rows of U + int *UrowCapacities_; +#endif + /// U by rows + double *Urows_; + /// Indices in the rows of U + int *UrowInd_; + /// maximum capacity of Urows + int UrowMaxCap_; + /// number of used places in Urows + int UrowEnd_; + /// first row in U + int firstRowInU_; + /// last row in U + int lastRowInU_; + /// previous row in U + int *prevRowInU_; + /// next row in U + int *nextRowInU_; + + /// Starts of the columns of U + int *UcolStarts_; + /// Lengths of the columns of U + int *UcolLengths_; +#ifdef COIN_SIMP_CAPACITY + /// Capacities of the columns of U + int *UcolCapacities_; +#endif + /// U by columns + double *Ucolumns_; + /// Indices in the columns of U + int *UcolInd_; + /// previous column in U + int *prevColInU_; + /// next column in U + int *nextColInU_; + /// first column in U + int firstColInU_; + /// last column in U + int lastColInU_; + /// maximum capacity of Ucolumns_ + int UcolMaxCap_; + /// last used position in Ucolumns_ + int UcolEnd_; + /// indicator of slack variables + int *colSlack_; + + /// inverse values of the elements of diagonal of U + double *invOfPivots_; + + /// permutation of columns + int *colOfU_; + /// position of column after permutation + int *colPosition_; + /// permutations of rows + int *rowOfU_; + /// position of row after permutation + int *rowPosition_; + /// permutations of rows during LUupdate + int *secRowOfU_; + /// position of row after permutation during LUupdate + int *secRowPosition_; + + /// position of Eta vector + int *EtaPosition_; + /// Starts of eta vectors + int *EtaStarts_; + /// Lengths of eta vectors + int *EtaLengths_; + /// columns of eta vectors + int *EtaInd_; + /// elements of eta vectors + double *Eta_; + /// number of elements in Eta_ + int EtaSize_; + /// last eta row + int lastEtaRow_; + /// maximum number of eta vectors + int maxEtaRows_; + /// Capacity of Eta_ + int EtaMaxCap_; + + /// minimum storage increase + int minIncrease_; + /// maximum size for the diagonal of U after update + double updateTol_; + /// do Shul heuristic + bool doSuhlHeuristic_; + /// maximum of U + double maxU_; + /// bound on the growth rate + double maxGrowth_; + /// maximum of A + double maxA_; + /// maximum number of candidates for pivot + int pivotCandLimit_; + /// number of slacks in basis + int numberSlacks_; + /// number of slacks in irst basis + int firstNumberSlacks_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinSmartPtr.hpp b/thirdparty/linux/include/coin1/CoinSmartPtr.hpp new file mode 100644 index 0000000..93366a2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSmartPtr.hpp @@ -0,0 +1,528 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: CoinSmartPtr.hpp 1520 2012-01-29 00:43:31Z tkr $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +// Removed lots of debugging stuff and reformatted: Laszlo Ladanyi, IBM +#ifndef CoinSmartPtr_hpp +#define CoinSmartPtr_hpp + +#include <list> +#include <cassert> +#include <cstddef> +#include <cstring> + +namespace Coin { + + //######################################################################### + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * Coin::SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point + * to A and B, but A and B also point to each other (i.e. A has a + * SmartPtr to B and B has a SmartPtr to A). In this scenario, when the + * higher level object is finished with A and B, their reference counts + * will never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject { + public: + ReferencedObject() : reference_count_(0) {} + virtual ~ReferencedObject() { assert(reference_count_ == 0); } + inline int ReferenceCount() const { return reference_count_; } + inline void AddRef() const { ++reference_count_; } + inline void ReleaseRef() const { --reference_count_; } + + private: + mutable int reference_count_; + }; + + //######################################################################### + + +//#define IP_DEBUG_SMARTPTR +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifdef IP_DEBUG_SMARTPTR +# include "IpDebug.hpp" +#endif + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "CoinSmartPtr.hpp" + * + * class MyClass : public Coin::ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * + * In my_usage.cpp... + * + * #include "CoinSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template <class T> + class SmartPtr { + public: + /** Returns the raw pointer contained. Use to get the value of the + * raw ptr (i.e. to pass to other methods/functions, etc.) Note: This + * method does NOT copy, therefore, modifications using this value + * modify the underlying object contained by the SmartPtr, NEVER + * delete this returned value. + */ + T* GetRawPtr() const { return ptr_; } + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + bool IsValid() const { return ptr_ != NULL; } + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + bool IsNull() const { return ptr_ == NULL; } + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Release the currently referenced object. */ + void ReleasePointer_() { + if (ptr_) { + ptr_->ReleaseRef(); + if (ptr_->ReferenceCount() == 0) { + delete ptr_; + } + ptr_ = NULL; + } + } + + /** Set the value of the internal raw pointer from another raw + * pointer, releasing the previously referenced object if necessary. */ + SmartPtr<T>& SetFromRawPtr_(T* rhs){ + ReleasePointer_(); // Release any old pointer + if (rhs != NULL) { + rhs->AddRef(); + ptr_ = rhs; + } + return *this; + } + + /** Set the value of the internal raw pointer from a SmartPtr, + * releasing the previously referenced object if necessary. */ + inline SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs) { + SetFromRawPtr_(rhs.GetRawPtr()); + return (*this); + } + + //@} + + public: +#define dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr() : ptr_(NULL) {} + + /** Copy constructor, initialized from copy */ + SmartPtr(const SmartPtr<T>& copy) : ptr_(NULL) { + (void) SetFromSmartPtr_(copy); + } + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr) : ptr_(NULL) { + (void) SetFromRawPtr_(ptr); + } + + /** Destructor, automatically decrements the reference count, deletes + * the object if necessary.*/ + ~SmartPtr() { + ReleasePointer_(); + } + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const { +#if COIN_COINUTILS_CHECKLEVEL > 0 + assert(ptr_); +#endif + return ptr_; + } + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const { +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + return *ptr_; + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr<T>& operator=(T* rhs) { + return SetFromRawPtr_(rhs); + } + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr<T>& operator=(const SmartPtr<T>& rhs) { + return SetFromSmartPtr_(rhs); + } + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template <class U1, class U2> + friend + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + //@} + + }; + + template <class U1, class U2> + bool ComparePointers(const U1* lhs, const U2* rhs) { + if (lhs == rhs) { + return true; + } + // If lhs and rhs point to the same object with different interfaces + // U1 and U2, we cannot guarantee that the value of the pointers will + // be equivalent. We can guarantee this if we convert to void*. + return static_cast<const void*>(lhs) == static_cast<const void*>(rhs); + } + +} // namespace Coin + +//############################################################################# + +/**@name SmartPtr friends that are overloaded operators, so they are not in + the Coin namespace. */ +//@{ +template <class U1, class U2> +bool operator==(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), rhs.GetRawPtr()); +} + +template <class U1, class U2> +bool operator==(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { + return Coin::ComparePointers(lhs.GetRawPtr(), raw_rhs); +} + +template <class U1, class U2> +bool operator==(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { + return Coin::ComparePointers(raw_lhs, rhs.GetRawPtr()); +} + +template <class U1, class U2> +bool operator!=(const Coin::SmartPtr<U1>& lhs, const Coin::SmartPtr<U2>& rhs) { + return ! operator==(lhs, rhs); +} + +template <class U1, class U2> +bool operator!=(const Coin::SmartPtr<U1>& lhs, U2* raw_rhs) { + return ! operator==(lhs, raw_rhs); +} + +template <class U1, class U2> +bool operator!=(U1* raw_lhs, const Coin::SmartPtr<U2>& rhs) { + return ! operator==(raw_lhs, rhs); +} +//@} + +#define CoinReferencedObject Coin::ReferencedObject +#define CoinSmartPtr Coin::SmartPtr +#define CoinComparePointers Coin::ComparePointers + +#endif diff --git a/thirdparty/linux/include/coin1/CoinSnapshot.hpp b/thirdparty/linux/include/coin1/CoinSnapshot.hpp new file mode 100644 index 0000000..e928026 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSnapshot.hpp @@ -0,0 +1,476 @@ +/* $Id: CoinSnapshot.hpp 1416 2011-04-17 09:57:29Z stefan $ */ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSnapshot_H +#define CoinSnapshot_H + +class CoinPackedMatrix; +#include "CoinTypes.hpp" + +//############################################################################# + +/** NON Abstract Base Class for interfacing with cut generators or branching code or .. + It is designed to be snapshot of a problem at a node in tree + + The class may or may not own the arrays - see owned_ + + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return arrays. +*/ + +class CoinSnapshot { + +public: + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + The Matrix pointers may be NULL + */ + //@{ + /// Get number of columns + inline int getNumCols() const + { return numCols_;} + + /// Get number of rows + inline int getNumRows() const + { return numRows_;} + + /// Get number of nonzero elements + inline int getNumElements() const + { return numElements_;} + + /// Get number of integer variables + inline int getNumIntegers() const + { return numIntegers_;} + + /// Get pointer to array[getNumCols()] of column lower bounds + inline const double * getColLower() const + { return colLower_;} + + /// Get pointer to array[getNumCols()] of column upper bounds + inline const double * getColUpper() const + { return colUpper_;} + + /// Get pointer to array[getNumRows()] of row lower bounds + inline const double * getRowLower() const + { return rowLower_;} + + /// Get pointer to array[getNumRows()] of row upper bounds + inline const double * getRowUpper() const + { return rowUpper_;} + + /** Get pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + inline const double * getRightHandSide() const + { return rightHandSide_;} + + /// Get pointer to array[getNumCols()] of objective function coefficients + inline const double * getObjCoefficients() const + { return objCoefficients_;} + + /// Get objective function sense (1 for min (default), -1 for max) + inline double getObjSense() const + { return objSense_;} + + /// Return true if variable is continuous + inline bool isContinuous(int colIndex) const + { return colType_[colIndex]=='C';} + + /// Return true if variable is binary + inline bool isBinary(int colIndex) const + { return colType_[colIndex]=='B';} + + /// Return true if column is integer. + inline bool isInteger(int colIndex) const + { return colType_[colIndex]=='B'||colType_[colIndex]=='I';} + + /// Return true if variable is general integer + inline bool isIntegerNonBinary(int colIndex) const + { return colType_[colIndex]=='I';} + + /// Return true if variable is binary and not fixed at either bound + inline bool isFreeBinary(int colIndex) const + { return colType_[colIndex]=='B'&&colUpper_[colIndex]>colLower_[colIndex];} + + /// Get colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + inline const char * getColType() const + { return colType_;} + + /// Get pointer to row-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByRow() const + { return matrixByRow_;} + + /// Get pointer to column-wise copy of current matrix + inline const CoinPackedMatrix * getMatrixByCol() const + { return matrixByCol_;} + + /// Get pointer to row-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByRow() const + { return originalMatrixByRow_;} + + /// Get pointer to column-wise copy of "original" matrix + inline const CoinPackedMatrix * getOriginalMatrixByCol() const + { return originalMatrixByCol_;} + //@} + + /**@name Solution query methods */ + //@{ + /// Get pointer to array[getNumCols()] of primal variable values + inline const double * getColSolution() const + { return colSolution_;} + + /// Get pointer to array[getNumRows()] of dual variable values + inline const double * getRowPrice() const + { return rowPrice_;} + + /// Get a pointer to array[getNumCols()] of reduced costs + inline const double * getReducedCost() const + { return reducedCost_;} + + /// Get pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + inline const double * getRowActivity() const + { return rowActivity_;} + + /// Get pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + inline const double * getDoNotSeparateThis() const + { return doNotSeparateThis_;} + //@} + + /**@name Other scalar get methods */ + //@{ + /// Get solver's value for infinity + inline double getInfinity() const + { return infinity_;} + + /** Get objective function value - includinbg any offset i.e. + sum c sub j * x subj - objValue = objOffset */ + inline double getObjValue() const + { return objValue_;} + + /// Get objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline double getObjOffset() const + { return objOffset_;} + + /// Get dual tolerance + inline double getDualTolerance() const + { return dualTolerance_;} + + /// Get primal tolerance + inline double getPrimalTolerance() const + { return primalTolerance_;} + + /// Get integer tolerance + inline double getIntegerTolerance() const + { return integerTolerance_;} + + /// Get integer upper bound i.e. best solution * getObjSense + inline double getIntegerUpperBound() const + { return integerUpperBound_;} + + /// Get integer lower bound i.e. best possible solution * getObjSense + inline double getIntegerLowerBound() const + { return integerLowerBound_;} + //@} + + //--------------------------------------------------------------------------- + + /**@name Method to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + All solution type arrays will be deleted + */ + void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub, + bool makeRowCopy=false); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods to set data */ + //@{ + /// Set number of columns + inline void setNumCols(int value) + { numCols_ = value;} + + /// Set number of rows + inline void setNumRows(int value) + { numRows_ = value;} + + /// Set number of nonzero elements + inline void setNumElements(int value) + { numElements_ = value;} + + /// Set number of integer variables + inline void setNumIntegers(int value) + { numIntegers_ = value;} + + /// Set pointer to array[getNumCols()] of column lower bounds + void setColLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of column upper bounds + void setColUpper(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row lower bounds + void setRowLower(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row upper bounds + void setRowUpper(const double * array, bool copyIn=true); + + /** Set pointer to array[getNumRows()] of row right-hand sides + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void setRightHandSide(const double * array, bool copyIn=true); + + /** Create array[getNumRows()] of row right-hand sides + using existing information + This gives same results as OsiSolverInterface for useful cases + If getRowUpper()[i] != infinity then + getRightHandSide()[i] == getRowUpper()[i] + else + getRightHandSide()[i] == getRowLower()[i] + */ + void createRightHandSide(); + + /// Set pointer to array[getNumCols()] of objective function coefficients + void setObjCoefficients(const double * array, bool copyIn=true); + + /// Set objective function sense (1 for min (default), -1 for max) + inline void setObjSense(double value) + { objSense_ = value;} + + /// Set colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + void setColType(const char *array, bool copyIn=true); + + /// Set pointer to row-wise copy of current matrix + void setMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Create row-wise copy from MatrixByCol + void createMatrixByRow(); + + /// Set pointer to column-wise copy of current matrix + void setMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to row-wise copy of "original" matrix + void setOriginalMatrixByRow(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to column-wise copy of "original" matrix + void setOriginalMatrixByCol(const CoinPackedMatrix * matrix, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values + void setColSolution(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of dual variable values + void setRowPrice(const double * array, bool copyIn=true); + + /// Set a pointer to array[getNumCols()] of reduced costs + void setReducedCost(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + void setRowActivity(const double * array, bool copyIn=true); + + /// Set pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + void setDoNotSeparateThis(const double * array, bool copyIn=true); + + /// Set solver's value for infinity + inline void setInfinity(double value) + { infinity_ = value;} + + /// Set objective function value (including any rhs offset) + inline void setObjValue(double value) + { objValue_ = value;} + + /// Set objective offset i.e. sum c sub j * x subj -objValue = objOffset + inline void setObjOffset(double value) + { objOffset_ = value;} + + /// Set dual tolerance + inline void setDualTolerance(double value) + { dualTolerance_ = value;} + + /// Set primal tolerance + inline void setPrimalTolerance(double value) + { primalTolerance_ = value;} + + /// Set integer tolerance + inline void setIntegerTolerance(double value) + { integerTolerance_ = value;} + + /// Set integer upper bound i.e. best solution * getObjSense + inline void setIntegerUpperBound(double value) + { integerUpperBound_ = value;} + + /// Set integer lower bound i.e. best possible solution * getObjSense + inline void setIntegerLowerBound(double value) + { integerLowerBound_ = value;} + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + CoinSnapshot(); + + /// Copy constructor + CoinSnapshot(const CoinSnapshot &); + + /// Assignment operator + CoinSnapshot & operator=(const CoinSnapshot& rhs); + + /// Destructor + virtual ~CoinSnapshot (); + + //@} + +private: + ///@name private functions + //@{ + /** Does main work of destructor - type (or'ed) + 1 - NULLify pointers + 2 - delete pointers + 4 - initialize scalars (tolerances etc) + 8 - initialize scalars (objValue etc0 + */ + void gutsOfDestructor(int type); + /// Does main work of copy + void gutsOfCopy(const CoinSnapshot & rhs); + //@} + + ///@name Private member data + + /// objective function sense (1 for min (default), -1 for max) + double objSense_; + + /// solver's value for infinity + double infinity_; + + /// objective function value (including any rhs offset) + double objValue_; + + /// objective offset i.e. sum c sub j * x subj -objValue = objOffset + double objOffset_; + + /// dual tolerance + double dualTolerance_; + + /// primal tolerance + double primalTolerance_; + + /// integer tolerance + double integerTolerance_; + + /// integer upper bound i.e. best solution * getObjSense + double integerUpperBound_; + + /// integer lower bound i.e. best possible solution * getObjSense + double integerLowerBound_; + + /// pointer to array[getNumCols()] of column lower bounds + const double * colLower_; + + /// pointer to array[getNumCols()] of column upper bounds + const double * colUpper_; + + /// pointer to array[getNumRows()] of row lower bounds + const double * rowLower_; + + /// pointer to array[getNumRows()] of row upper bounds + const double * rowUpper_; + + /// pointer to array[getNumRows()] of rhs side values + const double * rightHandSide_; + + /// pointer to array[getNumCols()] of objective function coefficients + const double * objCoefficients_; + + /// colType array ('B', 'I', or 'C' for Binary, Integer and Continuous) + const char * colType_; + + /// pointer to row-wise copy of current matrix + const CoinPackedMatrix * matrixByRow_; + + /// pointer to column-wise copy of current matrix + const CoinPackedMatrix * matrixByCol_; + + /// pointer to row-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByRow_; + + /// pointer to column-wise copy of "original" matrix + const CoinPackedMatrix * originalMatrixByCol_; + + /// pointer to array[getNumCols()] of primal variable values + const double * colSolution_; + + /// pointer to array[getNumRows()] of dual variable values + const double * rowPrice_; + + /// a pointer to array[getNumCols()] of reduced costs + const double * reducedCost_; + + /// pointer to array[getNumRows()] of row activity levels (constraint matrix times the solution vector). + const double * rowActivity_; + + /// pointer to array[getNumCols()] of primal variable values which should not be separated (for debug) + const double * doNotSeparateThis_; + + /// number of columns + int numCols_; + + /// number of rows + int numRows_; + + /// number of nonzero elements + int numElements_; + + /// number of integer variables + int numIntegers_; + + /// To say whether arrays etc are owned by CoinSnapshot + typedef struct { + unsigned int colLower:1; + unsigned int colUpper:1; + unsigned int rowLower:1; + unsigned int rowUpper:1; + unsigned int rightHandSide:1; + unsigned int objCoefficients:1; + unsigned int colType:1; + unsigned int matrixByRow:1; + unsigned int matrixByCol:1; + unsigned int originalMatrixByRow:1; + unsigned int originalMatrixByCol:1; + unsigned int colSolution:1; + unsigned int rowPrice:1; + unsigned int reducedCost:1; + unsigned int rowActivity:1; + unsigned int doNotSeparateThis:1; + } coinOwned; + coinOwned owned_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinSort.hpp b/thirdparty/linux/include/coin1/CoinSort.hpp new file mode 100644 index 0000000..259fb35 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinSort.hpp @@ -0,0 +1,678 @@ +/* $Id: CoinSort.hpp 1594 2013-04-19 14:33:00Z forrest $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinSort_H +#define CoinSort_H + +#include <functional> +#include <new> +#include <algorithm> +#include "CoinDistance.hpp" + +// Uncomment the next three lines to get thorough initialisation of memory. +// #ifndef ZEROFAULT +// #define ZEROFAULT +// #endif + +#ifdef COIN_FAST_CODE +#ifndef COIN_USE_EKK_SORT +#define COIN_USE_EKK_SORT +#endif +#endif + +//############################################################################# + +/** An ordered pair. It's the same as std::pair, just this way it'll have the + same look as the triple sorting. */ +template <class S, class T> +struct CoinPair { +public: + /// First member of pair + S first; + /// Second member of pair + T second; +public: + /// Construct from ordered pair + CoinPair(const S& s, const T& t) : first(s), second(t) {} +}; + +//############################################################################# + +/**@name Comparisons on first element of two ordered pairs */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T> +class CoinFirstLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T> +class CoinFirstGreater_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return t1.first > t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T> +class CoinFirstAbsLess_2 { +public: + /// Compare function + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T> +class CoinFirstAbsGreater_2 { +public: + /// Compare function + inline bool operator()(CoinPair<S,T> t1, CoinPair<S,T> t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstLess_2 { +private: + CoinExternalVectorFirstLess_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_2(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class V> +class CoinExternalVectorFirstGreater_2 { +private: + CoinExternalVectorFirstGreater_2(); +private: + const V* vec_; +public: + inline bool operator()(const CoinPair<S,T>& t1, + const CoinPair<S,T>& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_2(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/** Sort a pair of containers.<br> + + Iter_S - iterator for first container<br> + Iter_T - iterator for 2nd container<br> + CoinCompare2 - class comparing CoinPairs<br> +*/ + +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template <class Iter_S, class Iter_T, class CoinCompare2> void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst, const CoinCompare2& pc) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair<S,T> ST_pair; + ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x.begin(), x.end(), pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class Iter_S, class Iter_T> void +CoinSort_2(Iter_S sfirst, Iter_S slast, Iter_T tfirst) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} + +#else //======================================================================= + +template <class S, class T, class CoinCompare2> void +CoinSort_2(S* sfirst, S* slast, T* tfirst, const CoinCompare2& pc) +{ + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinPair<S,T> ST_pair; + ST_pair* x = static_cast<ST_pair*>(::operator new(len * sizeof(ST_pair))); +# ifdef ZEROFAULT + // Can show RUI errors on some systems due to copy of ST_pair with gaps. + // E.g., <int, double> has 4 byte alignment gap on Solaris/SUNWspro. + memset(x,0,(len*sizeof(ST_pair))) ; +# endif + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + while (scurrent != slast) { + new (x+i++) ST_pair(*scurrent++, *tcurrent++); + } + + std::sort(x, x + len, pc); + + scurrent = sfirst; + tcurrent = tfirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + } + + ::operator delete(x); +} +template <class S, class T> void +// This Always uses std::sort +CoinSort_2Std(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} +#ifndef COIN_USE_EKK_SORT +//----------------------------------------------------------------------------- +template <class S, class T> void +CoinSort_2(S* sfirst, S* slast, T* tfirst) +{ + CoinSort_2(sfirst, slast, tfirst, CoinFirstLess_2<S,T>()); +} +#else +//----------------------------------------------------------------------------- +extern int boundary_sort; +extern int boundary_sort2; +extern int boundary_sort3; +/// Sort without new and delete +template <class S, class T> void +CoinSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 1) { + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } +#if 0 + if (number==boundary_sort3) { + printf("before sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + } +#endif + int minsize=10; + int n = static_cast<int>(number); + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + int j; + /*check already sorted */ + S last=key[0]; + for (j=1;j<n;j++) { + if (key[j]>=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +#if 0 + if (number==boundary_sort3) { + printf("after sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + CoinSort_2Many(key, lastKey, array2); + printf("after2 sort %d entries\n",number); + for (int j=0;j<number;j++) { + std::cout<<" ( "<<key[j]<<","<<array2[j]<<")"; + } + std::cout<<std::endl; + } +#endif +} +#endif +#endif +/// Sort without new and delete +template <class S, class T> void +CoinShortSort_2(S* key, S* lastKey, T* array2) +{ + const size_t number = coinDistance(key, lastKey); + if (number <= 2) { + if (number == 2 && key[0] > key[1]) { + S tempS = key[0]; + T tempT = array2[0]; + key[0] = key[1]; + array2[0] = array2[1]; + key[1] = tempS; + array2[1] = tempT; + } + return; + } else if (number>10000) { + CoinSort_2Std(key, lastKey, array2); + return; + } + int minsize=10; + size_t n = number; + int sp; + S *v = key; + S *m, t; + S * ls[32] , * rs[32]; + S *l , *r , c; + T it; + size_t j; + /*check already sorted */ + S last=key[0]; + for (j=1;j<n;j++) { + if (key[j]>=last) { + last=key[j]; + } else { + break; + } /* endif */ + } /* endfor */ + if (j==n) { + return; + } /* endif */ + sp = 0 ; ls[sp] = v ; rs[sp] = v + (n-1) ; + while( sp >= 0 ) + { + if ( rs[sp] - ls[sp] > minsize ) + { + l = ls[sp] ; r = rs[sp] ; m = l + (r-l)/2 ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + if ( *m > *r ) + { + t = *m ; *m = *r ; *r = t ; + it = array2[m-v] ; array2[m-v] = array2[r-v] ; array2[r-v] = it ; + if ( *l > *m ) + { + t = *l ; *l = *m ; *m = t ; + it = array2[l-v] ; array2[l-v] = array2[m-v] ; array2[m-v] = it ; + } + } + c = *m ; + while ( r - l > 1 ) + { + while ( *(++l) < c ) ; + while ( *(--r) > c ) ; + t = *l ; *l = *r ; *r = t ; + it = array2[l-v] ; array2[l-v] = array2[r-v] ; array2[r-v] = it ; + } + l = r - 1 ; + if ( l < m ) + { ls[sp+1] = ls[sp] ; + rs[sp+1] = l ; + ls[sp ] = r ; + } + else + { ls[sp+1] = r ; + rs[sp+1] = rs[sp] ; + rs[sp ] = l ; + } + sp++ ; + } + else sp-- ; + } + for ( l = v , m = v + (n-1) ; l < m ; l++ ) + { if ( *l > *(l+1) ) + { + c = *(l+1) ; + it = array2[(l-v)+1] ; + for ( r = l ; r >= v && *r > c ; r-- ) + { + *(r+1) = *r ; + array2[(r-v)+1] = array2[(r-v)] ; + } + *(r+1) = c ; + array2[(r-v)+1] = it ; + } + } +} +//############################################################################# +//############################################################################# + +/**@name Ordered Triple Struct */ +template <class S, class T, class U> +class CoinTriple { +public: + /// First member of triple + S first; + /// Second member of triple + T second; + /// Third member of triple + U third; +public: + /// Construct from ordered triple + CoinTriple(const S& s, const T& t, const U& u):first(s),second(t),third(u) {} +}; + +//############################################################################# +/**@name Comparisons on first element of two ordered triples */ +//@{ +/** Function operator. + Returns true if t1.first < t2.first (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return t1.first < t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if t1.first > t2.first (i.e, decreasing). */ +template < class S, class T, class U > +class CoinFirstGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return t1.first>t2.first; } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) < abs(t2.first) (i.e., increasing). */ +template < class S, class T, class U > +class CoinFirstAbsLess_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs < t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Returns true if abs(t1.first) > abs(t2.first) (i.e., decreasing). */ +template < class S, class T, class U > +class CoinFirstAbsGreater_3 { +public: + /// Compare function + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { + const T t1Abs = t1.first < static_cast<T>(0) ? -t1.first : t1.first; + const T t2Abs = t2.first < static_cast<T>(0) ? -t2.first : t2.first; + return t1Abs > t2Abs; + } +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first < vec[t2.first] (i.e., increasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstLess_3 { +private: + CoinExternalVectorFirstLess_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return vec_[t1.first] < vec_[t2.first]; } + CoinExternalVectorFirstLess_3(const V* v) : vec_(v) {} +}; +//----------------------------------------------------------------------------- +/** Function operator. + Compare based on the entries of an external vector, i.e., returns true if + vec[t1.first > vec[t2.first] (i.e., decreasing wrt. vec). Note that to + use this comparison operator .first must be a data type automatically + convertible to int. */ +template < class S, class T, class U, class V> +class CoinExternalVectorFirstGreater_3 { +private: + CoinExternalVectorFirstGreater_3(); +private: + const V* vec_; +public: + inline bool operator()(const CoinTriple<S,T,U>& t1, + const CoinTriple<S,T,U>& t2) const + { return vec_[t1.first] > vec_[t2.first]; } + CoinExternalVectorFirstGreater_3(const V* v) : vec_(v) {} +}; +//@} + +//############################################################################# + +/**@name Typedefs for sorting the entries of a packed vector based on an + external vector. */ +//@{ +/// Sort packed vector in increasing order of the external vector +typedef CoinExternalVectorFirstLess_3<int, int, double, double> +CoinIncrSolutionOrdered; +/// Sort packed vector in decreasing order of the external vector +typedef CoinExternalVectorFirstGreater_3<int, int, double, double> +CoinDecrSolutionOrdered; +//@} + +//############################################################################# + +/** Sort a triple of containers.<br> + + Iter_S - iterator for first container<br> + Iter_T - iterator for 2nd container<br> + Iter_U - iterator for 3rd container<br> + CoinCompare3 - class comparing CoinTriples<br> +*/ +#ifdef COIN_SORT_ARBITRARY_CONTAINERS +template <class Iter_S, class Iter_T, class Iter_U, class CoinCompare3> void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst, + const CoinCompare3& tc) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + typedef typename std::iterator_traits<Iter_U>::value_type U; + const size_t len = coinDistance(sfirst, slast); + if (len <= 1) + return; + + typedef CoinTriple<S,T,U> STU_triple; + STU_triple* x = + static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple))); + + int i = 0; + Iter_S scurrent = sfirst; + Iter_T tcurrent = tfirst; + Iter_U ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class Iter_S, class Iter_T, class Iter_U> void +CoinSort_3(Iter_S sfirst, Iter_S slast, Iter_T tfirst, Iter_U, ufirst) +{ + typedef typename std::iterator_traits<Iter_S>::value_type S; + typedef typename std::iterator_traits<Iter_T>::value_type T; + typedef typename std::iterator_traits<Iter_U>::value_type U; + CoinSort_3(sfirts, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>()); +} + +#else //======================================================================= + +template <class S, class T, class U, class CoinCompare3> void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst, const CoinCompare3& tc) +{ + const size_t len = coinDistance(sfirst,slast); + if (len <= 1) + return; + + typedef CoinTriple<S,T,U> STU_triple; + STU_triple* x = + static_cast<STU_triple*>(::operator new(len * sizeof(STU_triple))); + + size_t i = 0; + S* scurrent = sfirst; + T* tcurrent = tfirst; + U* ucurrent = ufirst; + while (scurrent != slast) { + new (x+i++) STU_triple(*scurrent++, *tcurrent++, *ucurrent++); + } + + std::sort(x, x+len, tc); + + scurrent = sfirst; + tcurrent = tfirst; + ucurrent = ufirst; + for (i = 0; i < len; ++i) { + *scurrent++ = x[i].first; + *tcurrent++ = x[i].second; + *ucurrent++ = x[i].third; + } + + ::operator delete(x); +} +//----------------------------------------------------------------------------- +template <class S, class T, class U> void +CoinSort_3(S* sfirst, S* slast, T* tfirst, U* ufirst) +{ + CoinSort_3(sfirst, slast, tfirst, ufirst, CoinFirstLess_3<S,T,U>()); +} + +#endif + +//############################################################################# + +#endif diff --git a/thirdparty/linux/include/coin1/CoinStructuredModel.hpp b/thirdparty/linux/include/coin1/CoinStructuredModel.hpp new file mode 100644 index 0000000..19659b8 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinStructuredModel.hpp @@ -0,0 +1,247 @@ +/* $Id: CoinStructuredModel.hpp 1691 2014-03-19 12:43:56Z forrest $ */ +// Copyright (C) 2008, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinStructuredModel_H +#define CoinStructuredModel_H + +#include "CoinModel.hpp" +#include <vector> + +/** + This is a model which is made up of Coin(Structured)Model blocks. +*/ + typedef struct CoinModelInfo2 { + int rowBlock; // Which row block + int columnBlock; // Which column block + char matrix; // nonzero if matrix exists + char rhs; // nonzero if non default rhs exists + char rowName; // nonzero if row names exists + char integer; // nonzero if integer information exists + char bounds; // nonzero if non default bounds/objective exists + char columnName; // nonzero if column names exists + CoinModelInfo2() : + rowBlock(0), + columnBlock(0), + matrix(0), + rhs(0), + rowName(0), + integer(0), + bounds(0), + columnName(0) + {} +} CoinModelBlockInfo; + +class CoinStructuredModel : public CoinBaseModel { + +public: + /**@name Useful methods for building model */ + //@{ + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinBaseModel & block); + /** add a block from a CoinModel with names in model + returns number of errors (e.g. both have objectives but not same) + */ + int addBlock(const CoinBaseModel & block); + /** add a block from a CoinModel using names given as parameters + returns number of errors (e.g. both have objectives but not same) + This passes in block - structured model takes ownership + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + CoinBaseModel * block); + /** add a block using names + */ + int addBlock(const std::string & rowBlock, + const std::string & columnBlock, + const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective); + + /** Write the problem in MPS format to a file with the given filename. + + \param compression can be set to three values to indicate what kind + of file should be written + <ul> + <li> 0: plain text (default) + <li> 1: gzip compressed (.gz is appended to \c filename) + <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) + </ul> + If the library was not compiled with the requested compression then + writeMps falls back to writing a plain text file. + + \param formatType specifies the precision to used for values in the + MPS file + <ul> + <li> 0: normal precision (default) + <li> 1: extra accuracy + <li> 2: IEEE hex + </ul> + + \param numberAcross specifies whether 1 or 2 (default) values should be + specified on every data line in the MPS file. + + not const as may change model e.g. fill in default bounds + */ + int writeMps(const char *filename, int compression = 0, + int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; + /// Read SMPS model + int readSmps(const char *filename, + bool keepNames = false, + bool ignoreErrors = false); + + /** Decompose a CoinModel + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinModel &model,int type, + int maxBlocks=50, const char ** starts=NULL); + /** Decompose a model specified as arrays + CoinPackedMatrix + 1 - try D-W + 2 - try Benders + 3 - try Staircase + Returns number of blocks or zero if no structure + */ + int decompose(const CoinPackedMatrix & matrix, + const double * rowLower, const double * rowUpper, + const double * columnLower, const double * columnUpper, + const double * objective, int type,int maxBlocks=50, + int * starts=NULL, + double objectiveOffset=0.0); + + //@} + + + /**@name For getting information */ + //@{ + /// Return number of row blocks + inline int numberRowBlocks() const + { return numberRowBlocks_;} + /// Return number of column blocks + inline int numberColumnBlocks() const + { return numberColumnBlocks_;} + /// Return number of elementBlocks + inline CoinBigIndex numberElementBlocks() const + { return numberElementBlocks_;} + /// Return number of elements + CoinBigIndex numberElements() const; + /// Return the i'th row block name + inline const std::string & getRowBlock(int i) const + { return rowBlockNames_[i];} + /// Set i'th row block name + inline void setRowBlock(int i,const std::string &name) + { rowBlockNames_[i] = name;} + /// Add or check a row block name and number of rows + int addRowBlock(int numberRows,const std::string &name) ; + /// Return a row block index given a row block name + int rowBlock(const std::string &name) const; + /// Return i'th the column block name + inline const std::string & getColumnBlock(int i) const + { return columnBlockNames_[i];} + /// Set i'th column block name + inline void setColumnBlock(int i,const std::string &name) + { columnBlockNames_[i] = name;} + /// Add or check a column block name and number of columns + int addColumnBlock(int numberColumns,const std::string &name) ; + /// Return a column block index given a column block name + int columnBlock(const std::string &name) const; + /// Return i'th block type + inline const CoinModelBlockInfo & blockType(int i) const + { return blockType_[i];} + /// Return i'th block + inline CoinBaseModel * block(int i) const + { return blocks_[i];} + /// Return block corresponding to row and column + const CoinBaseModel * block(int row,int column) const; + /// Return i'th block as CoinModel (or NULL) + CoinModel * coinBlock(int i) const; + /// Return block corresponding to row and column as CoinModel + const CoinBaseModel * coinBlock(int row,int column) const; + /// Return block number corresponding to row and column + int blockIndex(int row,int column) const; + /** Return model as a CoinModel block + and fill in info structure and update counts + */ + CoinModel * coinModelBlock(CoinModelBlockInfo & info) ; + /// Sets given block into coinModelBlocks_ + void setCoinModel(CoinModel * block, int iBlock); + /// Refresh info in blockType_ + void refresh(int iBlock); + /** Fill pointers corresponding to row and column */ + + CoinModelBlockInfo block(int row,int column, + const double * & rowLower, const double * & rowUpper, + const double * & columnLower, const double * & columnUpper, + const double * & objective) const; + /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline double optimizationDirection() const { + return optimizationDirection_; + } + /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore + inline void setOptimizationDirection(double value) + { optimizationDirection_=value;} + //@} + + /**@name Constructors, destructor */ + //@{ + /** Default constructor. */ + CoinStructuredModel(); + /** Read a problem in MPS format from the given filename. + May try and decompose + */ + CoinStructuredModel(const char *fileName,int decompose=0, + int maxBlocks=50); + /** Destructor */ + virtual ~CoinStructuredModel(); + //@} + + /**@name Copy method */ + //@{ + /** The copy constructor. */ + CoinStructuredModel(const CoinStructuredModel&); + /// = + CoinStructuredModel& operator=(const CoinStructuredModel&); + /// Clone + virtual CoinBaseModel * clone() const; + //@} + +private: + + /** Fill in info structure and update counts + Returns number of inconsistencies on border + */ + int fillInfo(CoinModelBlockInfo & info,const CoinModel * block); + /** Fill in info structure and update counts + */ + void fillInfo(CoinModelBlockInfo & info,const CoinStructuredModel * block); + /**@name Data members */ + //@{ + /// Current number of row blocks + int numberRowBlocks_; + /// Current number of column blocks + int numberColumnBlocks_; + /// Current number of element blocks + int numberElementBlocks_; + /// Maximum number of element blocks + int maximumElementBlocks_; + /// Rowblock name + std::vector<std::string> rowBlockNames_; + /// Columnblock name + std::vector<std::string> columnBlockNames_; + /// Blocks + CoinBaseModel ** blocks_; + /// CoinModel copies of blocks or NULL if original CoinModel + CoinModel ** coinModelBlocks_; + /// Which parts of model are set in block + CoinModelBlockInfo * blockType_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/CoinTime.hpp b/thirdparty/linux/include/coin1/CoinTime.hpp new file mode 100644 index 0000000..49e8507 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinTime.hpp @@ -0,0 +1,310 @@ +/* $Id: CoinTime.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTime_hpp +#define _CoinTime_hpp + +// Uncomment the next three lines for thorough memory initialisation. +// #ifndef ZEROFAULT +// # define ZEROFAULT +// #endif + +//############################################################################# + +#include <ctime> +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#else +// MacOS-X and FreeBSD needs sys/time.h +#if defined(__MACH__) || defined (__FreeBSD__) +#include <sys/time.h> +#endif +#if !defined(__MSVCRT__) +#include <sys/resource.h> +#endif +#endif + +//############################################################################# + +#if defined(_MSC_VER) + +#if 0 // change this to 1 if want to use the win32 API +#include <windows.h> +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#define DELTA_EPOCH_IN_SECS 11644473600.0 +inline double CoinGetTimeOfDay() +{ + FILETIME ft; + + GetSystemTimeAsFileTime(&ft); + double t = ft.dwHighDateTime * TWO_TO_THE_THIRTYTWO + ft.dwLowDateTime; + t = t/10000000.0 - DELTA_EPOCH_IN_SECS; + return t; +} +#else +#include <sys/types.h> +#include <sys/timeb.h> +inline double CoinGetTimeOfDay() +{ + struct _timeb timebuffer; +#pragma warning(disable:4996) + _ftime( &timebuffer ); // C4996 +#pragma warning(default:4996) + return timebuffer.time + timebuffer.millitm/1000.0; +} +#endif + +#else + +#include <sys/time.h> + +inline double CoinGetTimeOfDay() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return static_cast<double>(tv.tv_sec) + static_cast<int>(tv.tv_usec)/1000000.0; +} + +#endif // _MSC_VER + +/** + Query the elapsed wallclock time since the first call to this function. If + a positive argument is passed to the function then the time of the first + call is set to that value (this kind of argument is allowed only at the + first call!). If a negative argument is passed to the function then it + returns the time when it was set. +*/ + +inline double CoinWallclockTime(double callType = 0) +{ + double callTime = CoinGetTimeOfDay(); + static const double firstCall = callType > 0 ? callType : callTime; + return callType < 0 ? firstCall : callTime - firstCall; +} + +//############################################################################# + +//#define HAVE_SDK // if SDK under Win32 is installed, for CPU instead of elapsed time under Win +#ifdef HAVE_SDK +#include <windows.h> +#ifdef small +/* for some unfathomable reason (to me) rpcndr.h (pulled in by windows.h) does a + '#define small char' */ +#undef small +#endif +#define TWO_TO_THE_THIRTYTWO 4294967296.0 +#endif + +static inline double CoinCpuTime() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) +#ifdef HAVE_SDK + FILETIME creation; + FILETIME exit; + FILETIME kernel; + FILETIME user; + GetProcessTimes(GetCurrentProcess(), &creation, &exit, &kernel, &user); + double t = user.dwHighDateTime * TWO_TO_THE_THIRTYTWO + user.dwLowDateTime; + return t/10000000.0; +#else + unsigned int ticksnow; /* clock_t is same as int */ + ticksnow = (unsigned int)clock(); + cpu_temp = (double)((double)ticksnow/CLOCKS_PER_SEC); +#endif + +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + cpu_temp = static_cast<double>(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast<double> (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} + +//############################################################################# + + + +static inline double CoinSysTime() +{ + double sys_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + sys_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_SELF,&usage); + sys_temp = static_cast<double>(usage.ru_stime.tv_sec); + sys_temp += 1.0e-6*(static_cast<double> (usage.ru_stime.tv_usec)); +#endif + return sys_temp; +} + +//############################################################################# +// On most systems SELF seems to include children threads, This is for when it doesn't +static inline double CoinCpuTimeJustChildren() +{ + double cpu_temp; +#if defined(_MSC_VER) || defined(__MSVCRT__) + cpu_temp = 0.0; +#else + struct rusage usage; +# ifdef ZEROFAULT + usage.ru_utime.tv_sec = 0 ; + usage.ru_utime.tv_usec = 0 ; +# endif + getrusage(RUSAGE_CHILDREN,&usage); + cpu_temp = static_cast<double>(usage.ru_utime.tv_sec); + cpu_temp += 1.0e-6*(static_cast<double> (usage.ru_utime.tv_usec)); +#endif + return cpu_temp; +} +//############################################################################# + +#include <fstream> + +/** + This class implements a timer that also implements a tracing functionality. + + The timer stores the start time of the timer, for how much time it was set to + and when does it expire (start + limit = end). Queries can be made that tell + whether the timer is expired, is past an absolute time, is past a percentage + of the length of the timer. All times are given in seconds, but as double + numbers, so there can be fractional values. + + The timer can also be initialized with a stream and a specification whether + to write to or read from the stream. In the former case the result of every + query is written into the stream, in the latter case timing is not tested at + all, rather the supposed result is read out from the stream. This makes it + possible to exactly retrace time sensitive program execution. +*/ +class CoinTimer +{ +private: + /// When the timer was initialized/reset/restarted + double start; + /// + double limit; + double end; +#ifdef COIN_COMPILE_WITH_TRACING + std::fstream* stream; + bool write_stream; +#endif + +private: +#ifdef COIN_COMPILE_WITH_TRACING + inline bool evaluate(bool b_tmp) const { + int i_tmp = b_tmp; + if (stream) { + if (write_stream) + (*stream) << i_tmp << "\n"; + else + (*stream) >> i_tmp; + } + return i_tmp; + } + inline double evaluate(double d_tmp) const { + if (stream) { + if (write_stream) + (*stream) << d_tmp << "\n"; + else + (*stream) >> d_tmp; + } + return d_tmp; + } +#else + inline bool evaluate(const bool b_tmp) const { + return b_tmp; + } + inline double evaluate(const double d_tmp) const { + return d_tmp; + } +#endif + +public: + /// Default constructor creates a timer with no time limit and no tracing + CoinTimer() : + start(0), limit(1e100), end(1e100) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + + /// Create a timer with the given time limit and with no tracing + CoinTimer(double lim) : + start(CoinCpuTime()), limit(lim), end(start+lim) +#ifdef COIN_COMPILE_WITH_TRACING + , stream(0), write_stream(true) +#endif + {} + +#ifdef COIN_COMPILE_WITH_TRACING + /** Create a timer with no time limit and with writing/reading the trace + to/from the given stream, depending on the argument \c write. */ + CoinTimer(std::fstream* s, bool write) : + start(0), limit(1e100), end(1e100), + stream(s), write_stream(write) {} + + /** Create a timer with the given time limit and with writing/reading the + trace to/from the given stream, depending on the argument \c write. */ + CoinTimer(double lim, std::fstream* s, bool w) : + start(CoinCpuTime()), limit(lim), end(start+lim), + stream(s), write_stream(w) {} +#endif + + /// Restart the timer (keeping the same time limit) + inline void restart() { start=CoinCpuTime(); end=start+limit; } + /// An alternate name for \c restart() + inline void reset() { restart(); } + /// Reset (and restart) the timer and change its time limit + inline void reset(double lim) { limit=lim; restart(); } + + /** Return whether the given percentage of the time limit has elapsed since + the timer was started */ + inline bool isPastPercent(double pct) const { + return evaluate(start + limit * pct < CoinCpuTime()); + } + /** Return whether the given amount of time has elapsed since the timer was + started */ + inline bool isPast(double lim) const { + return evaluate(start + lim < CoinCpuTime()); + } + /** Return whether the originally specified time limit has passed since the + timer was started */ + inline bool isExpired() const { + return evaluate(end < CoinCpuTime()); + } + + /** Return how much time is left on the timer */ + inline double timeLeft() const { + return evaluate(end - CoinCpuTime()); + } + + /** Return how much time has elapsed */ + inline double timeElapsed() const { + return evaluate(CoinCpuTime() - start); + } + + inline void setLimit(double l) { + limit = l; + return; + } +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinTypes.hpp b/thirdparty/linux/include/coin1/CoinTypes.hpp new file mode 100644 index 0000000..3adee2e --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinTypes.hpp @@ -0,0 +1,64 @@ +/* $Id: CoinTypes.hpp 1762 2014-12-29 20:37:12Z tkr $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef _CoinTypes_hpp +#define _CoinTypes_hpp + +#include "CoinUtilsConfig.h" +/* On some systems, we require stdint.h to have the 64bit integer type defined. */ +#ifdef COINUTILS_HAS_STDINT_H +#include <stdint.h> +#endif +#ifdef COINUTILS_HAS_CSTDINT +#include <cstdint> +#endif + +#define CoinInt64 COIN_INT64_T +#define CoinUInt64 COIN_UINT64_T +#define CoinIntPtr COIN_INTPTR_T + +//============================================================================= +#ifndef COIN_BIG_INDEX +#define COIN_BIG_INDEX 0 +#endif + +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif + +//============================================================================= +#ifndef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#endif + +// See if we want the ability to have long double work arrays +#if COIN_BIG_DOUBLE==2 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 0 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#elif COIN_BIG_DOUBLE==3 +#undef COIN_BIG_DOUBLE +#define COIN_BIG_DOUBLE 1 +#define COIN_LONG_WORK 1 +typedef long double CoinWorkDouble; +#else +#define COIN_LONG_WORK 0 +typedef double CoinWorkDouble; +#endif + +#if COIN_BIG_DOUBLE==0 +typedef double CoinFactorizationDouble; +#elif COIN_BIG_DOUBLE==1 +typedef long double CoinFactorizationDouble; +#else +typedef double CoinFactorizationDouble; +#endif + +#endif diff --git a/thirdparty/linux/include/coin1/CoinUtility.hpp b/thirdparty/linux/include/coin1/CoinUtility.hpp new file mode 100644 index 0000000..49a30e2 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinUtility.hpp @@ -0,0 +1,19 @@ +/* $Id: CoinUtility.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2004, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinUtility_h_ +#define CoinUtility_h_ + +#include "CoinSort.hpp" + +template <typename S, typename T> +CoinPair<S,T> CoinMakePair(const S& s, const T& t) +{ return CoinPair<S,T>(s, t); } + +template <typename S, typename T, typename U> +CoinTriple<S,T,U> CoinMakeTriple(const S& s, const T& t, const U& u) +{ return CoinTriple<S,T,U>(s, t, u); } + +#endif diff --git a/thirdparty/linux/include/coin1/CoinUtilsConfig.h b/thirdparty/linux/include/coin1/CoinUtilsConfig.h new file mode 100644 index 0000000..8d656d5 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinUtilsConfig.h @@ -0,0 +1,34 @@ +/* src/config_coinutils.h. Generated by configure. */ +/* inc/config_coinutils.h.in. */ + +#ifndef __CONFIG_COINUTILS_H__ +#define __CONFIG_COINUTILS_H__ + +/* Define to 1 if stdint.h is available for CoinUtils */ +#define COINUTILS_HAS_STDINT_H 1 + +/* Define to 1 if stdint.h is available for CoinUtils */ +/* #undef COINUTILS_HAS_CSTDINT */ + +/* Version number of project */ +#define COINUTILS_VERSION "2.10.6" + +/* Major Version number of project */ +#define COINUTILS_VERSION_MAJOR 2 + +/* Minor Version number of project */ +#define COINUTILS_VERSION_MINOR 10 + +/* Release Version number of project */ +#define COINUTILS_VERSION_RELEASE 6 + +/* Define to 64bit integer type */ +#define COIN_INT64_T int64_t + +/* Define to integer type capturing pointer */ +#define COIN_INTPTR_T intptr_t + +/* Define to 64bit unsigned integer type */ +#define COIN_UINT64_T int64_t + +#endif diff --git a/thirdparty/linux/include/coin1/CoinWarmStart.hpp b/thirdparty/linux/include/coin1/CoinWarmStart.hpp new file mode 100644 index 0000000..a7e28c8 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinWarmStart.hpp @@ -0,0 +1,58 @@ +/* $Id: CoinWarmStart.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStart_H +#define CoinWarmStart_H + +//############################################################################# + +class CoinWarmStartDiff; + +/** Abstract base class for warm start information. + + Really nothing can be generalized for warm start information --- all we + know is that it exists. Hence the abstract base class contains only a + virtual destructor and a virtual clone function (a virtual constructor), + so that derived classes can provide these functions. +*/ + +class CoinWarmStart { +public: + + /// Abstract destructor + virtual ~CoinWarmStart() {} + + /// `Virtual constructor' + virtual CoinWarmStart *clone() const = 0 ; + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const ) const { return 0; } + + + virtual void + applyDiff (const CoinWarmStartDiff *const ) {} + +}; + + +/*! \class CoinWarmStartDiff + \brief Abstract base class for warm start `diff' objects + + For those types of warm start objects where the notion of a `diff' makes + sense, this virtual base class is provided. As with CoinWarmStart, its sole + reason for existence is to make it possible to write solver-independent code. +*/ + +class CoinWarmStartDiff { +public: + + /// Abstract destructor + virtual ~CoinWarmStartDiff() {} + + /// `Virtual constructor' + virtual CoinWarmStartDiff *clone() const = 0 ; +}; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinWarmStartBasis.hpp b/thirdparty/linux/include/coin1/CoinWarmStartBasis.hpp new file mode 100644 index 0000000..272d393 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinWarmStartBasis.hpp @@ -0,0 +1,456 @@ +/* $Id: CoinWarmStartBasis.hpp 1515 2011-12-10 23:38:04Z lou $ */ +/*! \legal + Copyright (C) 2000 -- 2003, International Business Machines Corporation + and others. All Rights Reserved. + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ + +/*! \file CoinWarmStart.hpp + \brief Declaration of the generic simplex (basis-oriented) warm start + class. Also contains a basis diff class. +*/ + +#ifndef CoinWarmStartBasis_H +#define CoinWarmStartBasis_H + +#include <vector> + +#include "CoinSort.hpp" +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + +//############################################################################# + +/*! \class CoinWarmStartBasis + \brief The default COIN simplex (basis-oriented) warm start class + + CoinWarmStartBasis provides for a warm start object which contains the + status of each variable (structural and artificial). + + \todo Modify this class so that the number of status entries per byte + and bytes per status vector allocation unit are not hardcoded. + At the least, collect this into a couple of macros. + + \todo Consider separate fields for allocated capacity and actual basis + size. We could avoid some reallocation, at the price of retaining + more space than we need. Perhaps more important, we could do much + better sanity checks. +*/ + +class CoinWarmStartBasis : public virtual CoinWarmStart { +public: + + /*! \brief Enum for status of variables + + Matches CoinPrePostsolveMatrix::Status, without superBasic. Most code that + converts between CoinPrePostsolveMatrix::Status and + CoinWarmStartBasis::Status will break if this correspondence is broken. + + The status vectors are currently packed using two bits per status code, + four codes per byte. The location of the status information for + variable \c i is in byte <code>i>>2</code> and occupies bits 0:1 + if <code>i\%4 == 0</code>, bits 2:3 if <code>i\%4 == 1</code>, etc. + The non-member functions getStatus(const char*,int) and + setStatus(char*,int,CoinWarmStartBasis::Status) are provided to hide + details of the packing. + */ + enum Status { + isFree = 0x00, ///< Nonbasic free variable + basic = 0x01, ///< Basic variable + atUpperBound = 0x02, ///< Nonbasic at upper bound + atLowerBound = 0x03 ///< Nonbasic at lower bound + }; + + /** \brief Transfer vector entry for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef CoinTriple<int,int,int> XferEntry ; + + /** \brief Transfer vector for + mergeBasis(const CoinWarmStartBasis*,const XferVec*,const XferVec*) + */ + typedef std::vector<XferEntry> XferVec ; + +public: + +/*! \name Methods to get and set basis information. + + The status of variables is kept in a pair of arrays, one for structural + variables, and one for artificials (aka logicals and slacks). The status + is coded using the values of the Status enum. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. +*/ +//@{ + /// Return the number of structural variables + inline int getNumStructural() const { return numStructural_; } + + /// Return the number of artificial variables + inline int getNumArtificial() const { return numArtificial_; } + + /** Return the number of basic structurals + + A fast test for an all-slack basis. + */ + int numberBasicStructurals() const ; + + /// Return the status of the specified structural variable. + inline Status getStructStatus(int i) const { + const int st = (structuralStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); + } + + /// Set the status of the specified structural variable. + inline void setStructStatus(int i, Status st) { + char& st_byte = structuralStatus_[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; + } + + /** Return the status array for the structural variables + + The status information is stored using the codes defined in the + Status enum, 2 bits per variable, packed 4 variables per byte. + */ + inline char * getStructuralStatus() { return structuralStatus_; } + + /** \c const overload for + \link CoinWarmStartBasis::getStructuralStatus() + getStructuralStatus() + \endlink + */ + inline const char * getStructuralStatus() const { return structuralStatus_; } + + /** As for \link getStructuralStatus() getStructuralStatus \endlink, + but returns the status array for the artificial variables. + */ + inline char * getArtificialStatus() { return artificialStatus_; } + + /// Return the status of the specified artificial variable. + inline Status getArtifStatus(int i) const { + const int st = (artificialStatus_[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); + } + + /// Set the status of the specified artificial variable. + inline void setArtifStatus(int i, Status st) { + char& st_byte = artificialStatus_[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; + } + + /** \c const overload for + \link CoinWarmStartBasis::getArtificialStatus() + getArtificialStatus() + \endlink + */ + inline const char * getArtificialStatus() const { return artificialStatus_; } + +//@} + +/*! \name Basis `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start basis passed as + a parameter to the warm start basis specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this basis + + Update this basis by applying \p diff. It's assumed that the allocated + capacity of the basis is sufficiently large. + */ + + virtual void + applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +//@} + + +/*! \name Methods to modify the warm start object */ +//@{ + + /*! \brief Set basis capacity; existing basis is discarded. + + After execution of this routine, the warm start object does not describe + a valid basis: all structural and artificial variables have status isFree. + */ + virtual void setSize(int ns, int na) ; + + /*! \brief Set basis capacity; existing basis is maintained. + + After execution of this routine, the warm start object describes a valid + basis: the status of new structural variables (added columns) is set to + nonbasic at lower bound, and the status of new artificial variables + (added rows) is set to basic. (The basis can be invalid if new structural + variables do not have a finite lower bound.) + */ + virtual void resize (int newNumberRows, int newNumberColumns); + + /** \brief Delete a set of rows from the basis + + \warning + This routine assumes that the set of indices to be deleted is sorted in + ascending order and contains no duplicates. Use deleteRows() if this is + not the case. + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void compressRows (int tgtCnt, const int *tgts) ; + + /** \brief Delete a set of rows from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted + constraints are slack (hence the associated logicals are basic). + + Removal of a tight constraint with a nonbasic logical implies that + some basic variable must be made nonbasic. This correction is left to + the client. + */ + + virtual void deleteRows(int rawTgtCnt, const int *rawTgts) ; + + /** \brief Delete a set of columns from the basis + + \warning + The resulting basis is guaranteed valid only if all deleted variables + are nonbasic. + + Removal of a basic variable implies that some nonbasic variable must be + made basic. This correction is left to the client. + */ + + virtual void deleteColumns(int number, const int * which); + + /** \brief Merge entries from a source basis into this basis. + + \warning + It's the client's responsibility to ensure validity of the merged basis, + if that's important to the application. + + The vector xferCols (xferRows) specifies runs of entries to be taken from + the source basis and placed in this basis. Each entry is a CoinTriple, + with first specifying the starting source index of a run, second + specifying the starting destination index, and third specifying the run + length. + */ + virtual void mergeBasis(const CoinWarmStartBasis *src, + const XferVec *xferRows, + const XferVec *xferCols) ; + +//@} + +/*! \name Constructors, destructors, and related functions */ + +//@{ + + /** Default constructor + + Creates a warm start object representing an empty basis + (0 rows, 0 columns). + */ + CoinWarmStartBasis(); + + /** Constructs a warm start object with the specified status vectors. + + The parameters are copied. + Consider assignBasisStatus(int,int,char*&,char*&) if the object should + assume ownership. + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + CoinWarmStartBasis(int ns, int na, const char* sStat, const char* aStat) ; + + /** Copy constructor */ + CoinWarmStartBasis(const CoinWarmStartBasis& ws) ; + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const + { + return new CoinWarmStartBasis(*this); + } + + /** Destructor */ + virtual ~CoinWarmStartBasis(); + + /** Assignment */ + + virtual CoinWarmStartBasis& operator=(const CoinWarmStartBasis& rhs) ; + + /** Assign the status vectors to be the warm start information. + + In this method the CoinWarmStartBasis object assumes ownership of the + pointers and upon return the argument pointers will be NULL. + If copying is desirable, use the + \link CoinWarmStartBasis(int,int,const char*,const char*) + array constructor \endlink + or the + \link operator=(const CoinWarmStartBasis&) + assignment operator \endlink. + + \note + The pointers passed to this method will be + freed using delete[], so they must be created using new[]. + */ + virtual void assignBasisStatus(int ns, int na, char*& sStat, char*& aStat) ; +//@} + +/*! \name Miscellaneous methods */ +//@{ + + /// Prints in readable format (for debug) + virtual void print() const; + /// Returns true if full basis (for debug) + bool fullBasis() const; + /// Returns true if full basis and fixes up (for debug) + bool fixFullBasis(); + +//@} + +protected: + /** \name Protected data members + + \sa CoinWarmStartBasis::Status for a description of the packing used in + the status arrays. + */ + //@{ + /// The number of structural variables + int numStructural_; + /// The number of artificial variables + int numArtificial_; + /// The maximum sise (in ints - actually 4*char) (so resize does not need to do new) + int maxSize_; + /** The status of the structural variables. */ + char * structuralStatus_; + /** The status of the artificial variables. */ + char * artificialStatus_; + //@} +}; + + +/*! \relates CoinWarmStartBasis + \brief Get the status of the specified variable in the given status array. +*/ + +inline CoinWarmStartBasis::Status getStatus(const char *array, int i) { + const int st = (array[i>>2] >> ((i&3)<<1)) & 3; + return static_cast<CoinWarmStartBasis::Status>(st); +} + +/*! \relates CoinWarmStartBasis + \brief Set the status of the specified variable in the given status array. +*/ + +inline void setStatus(char * array, int i, CoinWarmStartBasis::Status st) { + char& st_byte = array[i>>2]; + st_byte = static_cast<char>(st_byte & ~(3 << ((i&3)<<1))) ; + st_byte = static_cast<char>(st_byte | (st << ((i&3)<<1))) ; +} + +/*! \relates CoinWarmStartBasis + \brief Generate a print string for a status code +*/ +const char *statusName(CoinWarmStartBasis::Status status) ; + + +/*! \class CoinWarmStartBasisDiff + \brief A `diff' between two CoinWarmStartBasis objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartBasis + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartBasis::generateDiff() and CoinWarmStartBasis::applyDiff(). + + The actual data structure is an unsigned int vector, #difference_ which + starts with indices of changed and then has values starting after #sze_ + + \todo This is a pretty generic structure, and vector diff is a pretty generic + activity. We should be able to convert this to a template. + + \todo Using unsigned int as the data type for the diff vectors might help + to contain the damage when this code is inevitably compiled for 64 bit + architectures. But the notion of int as 4 bytes is hardwired into + CoinWarmStartBasis, so changes are definitely required. +*/ + +class CoinWarmStartBasisDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { CoinWarmStartBasisDiff *cwsbd = new CoinWarmStartBasisDiff(*this) ; + return (dynamic_cast<CoinWarmStartDiff *>(cwsbd)) ; } + + /*! \brief Assignment */ + virtual + CoinWarmStartBasisDiff &operator= (const CoinWarmStartBasisDiff &rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartBasisDiff(); + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartBasisDiff () : sze_(0), difference_(0) { } + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartBasisDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartBasisDiff (const CoinWarmStartBasisDiff &cwsbd) ; + + /*! \brief Standard constructor */ + CoinWarmStartBasisDiff (int sze, const unsigned int *const diffNdxs, + const unsigned int *const diffVals) ; + + /*! \brief Constructor when full is smaller than diff!*/ + CoinWarmStartBasisDiff (const CoinWarmStartBasis * rhs); + + private: + + friend CoinWarmStartDiff* + CoinWarmStartBasis::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartBasis::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Number of entries (and allocated capacity), in units of \c int. */ + int sze_ ; + + /*! \brief Array of diff indices and diff values */ + + unsigned int *difference_ ; + +} ; + + +#endif diff --git a/thirdparty/linux/include/coin1/CoinWarmStartDual.hpp b/thirdparty/linux/include/coin1/CoinWarmStartDual.hpp new file mode 100644 index 0000000..3e60d11 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinWarmStartDual.hpp @@ -0,0 +1,166 @@ +/* $Id: CoinWarmStartDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartDual_H +#define CoinWarmStartDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int size() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /** Assign the dual vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return "dual" will + be a NULL pointer. If copying is desirable use the constructor. */ + inline void assignDual(int size, double *& dual) + { dual_.assignVector(size, dual); } + + CoinWarmStartDual() {} + + CoinWarmStartDual(int size, const double * dual) : dual_(size, dual) {} + + CoinWarmStartDual(const CoinWarmStartDual& rhs) : dual_(rhs.dual_) {} + + CoinWarmStartDual& operator=(const CoinWarmStartDual& rhs) { + if (this != &rhs) { + dual_ = rhs.dual_; + } + return *this; + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartDual(*this); + } + + virtual ~CoinWarmStartDual() {} + +/*! \name Dual warm start `diff' methods */ +//@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + +#if 0 +protected: + inline const CoinWarmStartVector<double>& warmStartVector() const { return dual_; } +#endif + +//@} + +private: + ///@name Private data members + CoinWarmStartVector<double> dual_; +}; + +//############################################################################# + +/*! \class CoinWarmStartDualDiff + \brief A `diff' between two CoinWarmStartDual objects + + This class exists in order to hide from the world the details of + calculating and representing a `diff' between two CoinWarmStartDual + objects. For convenience, assignment, cloning, and deletion are visible to + the world, and default and copy constructors are made available to derived + classes. Knowledge of the rest of this structure, and of generating and + applying diffs, is restricted to the friend functions + CoinWarmStartDual::generateDiff() and CoinWarmStartDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartDualDiff : public virtual CoinWarmStartDiff +{ public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartDualDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartDualDiff &operator= (const CoinWarmStartDualDiff &rhs) + { + if (this != &rhs) { + diff_ = rhs.diff_; + } + return *this; + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartDualDiff() {} + + protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartDualDiff () : diff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartDualDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartDualDiff (const CoinWarmStartDualDiff &rhs) : + diff_(rhs.diff_) {} + + private: + + friend CoinWarmStartDiff* + CoinWarmStartDual::generateDiff(const CoinWarmStart *const oldCWS) const ; + friend void + CoinWarmStartDual::applyDiff(const CoinWarmStartDiff *const diff) ; + + /*! \brief Standard constructor */ + CoinWarmStartDualDiff (int sze, const unsigned int *const diffNdxs, + const double *const diffVals) : + diff_(sze, diffNdxs, diffVals) {} + + /*! + \brief The difference in the dual vector is simply the difference in a + vector. + */ + CoinWarmStartVectorDiff<double> diff_; +}; + + +#endif + diff --git a/thirdparty/linux/include/coin1/CoinWarmStartPrimalDual.hpp b/thirdparty/linux/include/coin1/CoinWarmStartPrimalDual.hpp new file mode 100644 index 0000000..c98d423 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinWarmStartPrimalDual.hpp @@ -0,0 +1,211 @@ +/* $Id: CoinWarmStartPrimalDual.hpp 1372 2011-01-03 23:31:00Z lou $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartPrimalDual_H +#define CoinWarmStartPrimalDual_H + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" +#include "CoinWarmStartVector.hpp" + + +//############################################################################# + +/** WarmStart information that is only a dual vector */ + +class CoinWarmStartPrimalDual : public virtual CoinWarmStart { +public: + /// return the size of the dual vector + inline int dualSize() const { return dual_.size(); } + /// return a pointer to the array of duals + inline const double * dual() const { return dual_.values(); } + + /// return the size of the primal vector + inline int primalSize() const { return primal_.size(); } + /// return a pointer to the array of primals + inline const double * primal() const { return primal_.values(); } + + /** Assign the primal/dual vectors to be the warmstart information. In this + method the object assumes ownership of the pointers and upon return \c + primal and \c dual will be a NULL pointers. If copying is desirable use + the constructor. + + NOTE: \c primal and \c dual must have been allocated by new double[], + because they will be freed by delete[] upon the desructtion of this + object... + */ + void assign(int primalSize, int dualSize, double*& primal, double *& dual) { + primal_.assignVector(primalSize, primal); + dual_.assignVector(dualSize, dual); + } + + CoinWarmStartPrimalDual() : primal_(), dual_() {} + + CoinWarmStartPrimalDual(int primalSize, int dualSize, + const double* primal, const double * dual) : + primal_(primalSize, primal), dual_(dualSize, dual) {} + + CoinWarmStartPrimalDual(const CoinWarmStartPrimalDual& rhs) : + primal_(rhs.primal_), dual_(rhs.dual_) {} + + CoinWarmStartPrimalDual& operator=(const CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_ = rhs.primal_; + dual_ = rhs.dual_; + } + return *this; + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + primal_.clear(); + dual_.clear(); + } + + inline void swap(CoinWarmStartPrimalDual& rhs) { + if (this != &rhs) { + primal_.swap(rhs.primal_); + dual_.swap(rhs.dual_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartPrimalDual(*this); + } + + virtual ~CoinWarmStartPrimalDual() {} + + /*! \name PrimalDual warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +#if 0 +protected: + inline const CoinWarmStartVector<double>& primalWarmStartVector() const + { return primal_; } + inline const CoinWarmStartVector<double>& dualWarmStartVector() const + { return dual_; } +#endif + +private: + ///@name Private data members + //@{ + CoinWarmStartVector<double> primal_; + CoinWarmStartVector<double> dual_; + //@} +}; + +//############################################################################# + +/*! \class CoinWarmStartPrimalDualDiff + \brief A `diff' between two CoinWarmStartPrimalDual objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartPrimalDual objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartPrimalDual::generateDiff() and + CoinWarmStartPrimalDual::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +class CoinWarmStartPrimalDualDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartPrimalDual::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartPrimalDual::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor'. To be used when retaining polymorphism is + important */ + virtual CoinWarmStartDiff *clone() const + { + return new CoinWarmStartPrimalDualDiff(*this); + } + + /*! \brief Destructor */ + virtual ~CoinWarmStartPrimalDualDiff() {} + +protected: + + /*! \brief Default constructor + + This is protected (rather than private) so that derived classes can + see it when they make <i>their</i> default constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff () : primalDiff_(), dualDiff_() {} + + /*! \brief Copy constructor + + For convenience when copying objects containing + CoinWarmStartPrimalDualDiff objects. But consider whether you should be + using #clone() to retain polymorphism. + + This is protected (rather than private) so that derived classes can + see it when the make <i>their</i> copy constructor protected or + private. + */ + CoinWarmStartPrimalDualDiff (const CoinWarmStartPrimalDualDiff &rhs) : + primalDiff_(rhs.primalDiff_), dualDiff_(rhs.dualDiff_) {} + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + primalDiff_.clear(); + dualDiff_.clear(); + } + + inline void swap(CoinWarmStartPrimalDualDiff& rhs) { + if (this != &rhs) { + primalDiff_.swap(rhs.primalDiff_); + dualDiff_.swap(rhs.dualDiff_); + } + } + +private: + + /*! + \brief These two differences describe the differences in the primal and + in the dual vector. + */ + CoinWarmStartVectorDiff<double> primalDiff_; + CoinWarmStartVectorDiff<double> dualDiff_; +} ; + +#endif diff --git a/thirdparty/linux/include/coin1/CoinWarmStartVector.hpp b/thirdparty/linux/include/coin1/CoinWarmStartVector.hpp new file mode 100644 index 0000000..e43ea10 --- /dev/null +++ b/thirdparty/linux/include/coin1/CoinWarmStartVector.hpp @@ -0,0 +1,488 @@ +/* $Id: CoinWarmStartVector.hpp 1498 2011-11-02 15:25:35Z mjs $ */ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef CoinWarmStartVector_H +#define CoinWarmStartVector_H + +#if defined(_MSC_VER) +// Turn off compiler warning about long names +# pragma warning(disable:4786) +#endif + +#include <cassert> +#include <cmath> + +#include "CoinHelperFunctions.hpp" +#include "CoinWarmStart.hpp" + + +//############################################################################# + +/** WarmStart information that is only a vector */ + +template <typename T> +class CoinWarmStartVector : public virtual CoinWarmStart +{ +protected: + inline void gutsOfDestructor() { + delete[] values_; + } + inline void gutsOfCopy(const CoinWarmStartVector<T>& rhs) { + size_ = rhs.size_; + values_ = new T[size_]; + CoinDisjointCopyN(rhs.values_, size_, values_); + } + +public: + /// return the size of the vector + int size() const { return size_; } + /// return a pointer to the array of vectors + const T* values() const { return values_; } + + /** Assign the vector to be the warmstart information. In this method + the object assumes ownership of the pointer and upon return #vector will + be a NULL pointer. If copying is desirable use the constructor. */ + void assignVector(int size, T*& vec) { + size_ = size; + delete[] values_; + values_ = vec; + vec = NULL; + } + + CoinWarmStartVector() : size_(0), values_(NULL) {} + + CoinWarmStartVector(int size, const T* vec) : + size_(size), values_(new T[size]) { + CoinDisjointCopyN(vec, size, values_); + } + + CoinWarmStartVector(const CoinWarmStartVector& rhs) { + gutsOfCopy(rhs); + } + + CoinWarmStartVector& operator=(const CoinWarmStartVector& rhs) { + if (this != &rhs) { + gutsOfDestructor(); + gutsOfCopy(rhs); + } + return *this; + } + + inline void swap(CoinWarmStartVector& rhs) { + if (this != &rhs) { + std::swap(size_, rhs.size_); + std::swap(values_, rhs.values_); + } + } + + /** `Virtual constructor' */ + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVector(*this); + } + + virtual ~CoinWarmStartVector() { + gutsOfDestructor(); + } + + /*! \brief Clear the data + + Make it appear as if the warmstart was just created using the default + constructor. + */ + inline void clear() { + size_ = 0; + delete[] values_; + values_ = NULL; + } + + /*! \name Vector warm start `diff' methods */ + //@{ + + /*! \brief Generate a `diff' that can convert the warm start passed as a + parameter to the warm start specified by \c this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by \c this. + */ + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + /*! \brief Apply \p diff to this warm start. + + Update this warm start by applying \p diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. + */ + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; + + //@} + +private: + ///@name Private data members + //@{ + /// the size of the vector + int size_; + /// the vector itself + T* values_; + //@} +}; + +//============================================================================= + +/*! \class CoinWarmStartVectorDiff + \brief A `diff' between two CoinWarmStartVector objects + + This class exists in order to hide from the world the details of calculating + and representing a `diff' between two CoinWarmStartVector objects. For + convenience, assignment, cloning, and deletion are visible to the world, and + default and copy constructors are made available to derived classes. + Knowledge of the rest of this structure, and of generating and applying + diffs, is restricted to the friend functions + CoinWarmStartVector::generateDiff() and CoinWarmStartVector::applyDiff(). + + The actual data structure is a pair of vectors, #diffNdxs_ and #diffVals_. + +*/ + +template <typename T> +class CoinWarmStartVectorDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVector<T>::applyDiff(const CoinWarmStartDiff *const diff) ; + +public: + + /*! \brief `Virtual constructor' */ + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorDiff(*this) ; + } + + /*! \brief Assignment */ + virtual CoinWarmStartVectorDiff & + operator= (const CoinWarmStartVectorDiff<T>& rhs) ; + + /*! \brief Destructor */ + virtual ~CoinWarmStartVectorDiff() { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + + inline void swap(CoinWarmStartVectorDiff& rhs) { + if (this != &rhs) { + std::swap(sze_, rhs.sze_); + std::swap(diffNdxs_, rhs.diffNdxs_); + std::swap(diffVals_, rhs.diffVals_); + } + } + + /*! \brief Default constructor + */ + CoinWarmStartVectorDiff () : sze_(0), diffNdxs_(0), diffVals_(NULL) {} + + /*! \brief Copy constructor + + For convenience when copying objects containing CoinWarmStartVectorDiff + objects. But consider whether you should be using #clone() to retain + polymorphism. + */ + CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T>& rhs) ; + + /*! \brief Standard constructor */ + CoinWarmStartVectorDiff(int sze, const unsigned int* const diffNdxs, + const T* const diffVals) ; + + /*! \brief Clear the data + + Make it appear as if the diff was just created using the default + constructor. + */ + inline void clear() { + sze_ = 0; + delete[] diffNdxs_; diffNdxs_ = NULL; + delete[] diffVals_; diffVals_ = NULL; + } + +private: + + /*! + \brief Number of entries (and allocated capacity), in units of \c T. + */ + int sze_ ; + + /*! \brief Array of diff indices */ + + unsigned int* diffNdxs_ ; + + /*! \brief Array of diff values */ + + T* diffVals_ ; +}; + +//############################################################################## + +template <typename T, typename U> +class CoinWarmStartVectorPair : public virtual CoinWarmStart +{ +private: + CoinWarmStartVector<T> t_; + CoinWarmStartVector<U> u_; + +public: + inline int size0() const { return t_.size(); } + inline int size1() const { return u_.size(); } + inline const T* values0() const { return t_.values(); } + inline const U* values1() const { return u_.values(); } + + inline void assignVector0(int size, T*& vec) { t_.assignVector(size, vec); } + inline void assignVector1(int size, U*& vec) { u_.assignVector(size, vec); } + + CoinWarmStartVectorPair() {} + CoinWarmStartVectorPair(int s0, const T* v0, int s1, const U* v1) : + t_(s0, v0), u_(s1, v1) {} + + CoinWarmStartVectorPair(const CoinWarmStartVectorPair<T,U>& rhs) : + t_(rhs.t_), u_(rhs.u_) {} + CoinWarmStartVectorPair& operator=(const CoinWarmStartVectorPair<T,U>& rhs) { + if (this != &rhs) { + t_ = rhs.t_; + u_ = rhs.u_; + } + return *this; + } + + inline void swap(CoinWarmStartVectorPair<T,U>& rhs) { + t_.swap(rhs.t_); + u_.swap(rhs.u_); + } + + virtual CoinWarmStart *clone() const { + return new CoinWarmStartVectorPair(*this); + } + + virtual ~CoinWarmStartVectorPair() {} + + inline void clear() { + t_.clear(); + u_.clear(); + } + + virtual CoinWarmStartDiff* + generateDiff (const CoinWarmStart *const oldCWS) const ; + + virtual void applyDiff (const CoinWarmStartDiff *const cwsdDiff) ; +}; + +//============================================================================= + +template <typename T, typename U> +class CoinWarmStartVectorPairDiff : public virtual CoinWarmStartDiff +{ + friend CoinWarmStartDiff* + CoinWarmStartVectorPair<T,U>::generateDiff(const CoinWarmStart *const oldCWS) const; + friend void + CoinWarmStartVectorPair<T,U>::applyDiff(const CoinWarmStartDiff *const diff) ; + +private: + CoinWarmStartVectorDiff<T> tdiff_; + CoinWarmStartVectorDiff<U> udiff_; + +public: + CoinWarmStartVectorPairDiff() {} + CoinWarmStartVectorPairDiff(const CoinWarmStartVectorPairDiff<T,U>& rhs) : + tdiff_(rhs.tdiff_), udiff_(rhs.udiff_) {} + virtual ~CoinWarmStartVectorPairDiff() {} + + virtual CoinWarmStartVectorPairDiff& + operator=(const CoinWarmStartVectorPairDiff<T,U>& rhs) { + if (this != &rhs) { + tdiff_ = rhs.tdiff_; + udiff_ = rhs.udiff_; + } + return *this; + } + + virtual CoinWarmStartDiff * clone() const { + return new CoinWarmStartVectorPairDiff(*this) ; + } + + inline void swap(CoinWarmStartVectorPairDiff<T,U>& rhs) { + tdiff_.swap(rhs.tdiff_); + udiff_.swap(rhs.udiff_); + } + + inline void clear() { + tdiff_.clear(); + udiff_.clear(); + } +}; + +//############################################################################## +//############################################################################# + +/* + Generate a `diff' that can convert the warm start passed as a parameter to + the warm start specified by this. + + The capabilities are limited: the basis passed as a parameter can be no + larger than the basis pointed to by this. +*/ + +template <typename T> CoinWarmStartDiff* +CoinWarmStartVector<T>::generateDiff(const CoinWarmStart *const oldCWS) const +{ +/* + Make sure the parameter is CoinWarmStartVector or derived class. +*/ + const CoinWarmStartVector<T>* oldVector = + dynamic_cast<const CoinWarmStartVector<T>*>(oldCWS); + if (!oldVector) + { throw CoinError("Old warm start not derived from CoinWarmStartVector.", + "generateDiff","CoinWarmStartVector") ; } + const CoinWarmStartVector<T>* newVector = this ; + /* + Make sure newVector is equal or bigger than oldVector. Calculate the worst + case number of diffs and allocate vectors to hold them. + */ + const int oldCnt = oldVector->size() ; + const int newCnt = newVector->size() ; + + assert(newCnt >= oldCnt) ; + + unsigned int *diffNdx = new unsigned int [newCnt]; + T* diffVal = new T[newCnt]; + /* + Scan the vector vectors. For the portion of the vectors which overlap, + create diffs. Then add any additional entries from newVector. + */ + const T*oldVal = oldVector->values() ; + const T*newVal = newVector->values() ; + int numberChanged = 0 ; + int i ; + for (i = 0 ; i < oldCnt ; i++) { + if (oldVal[i] != newVal[i]) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + } + for ( ; i < newCnt ; i++) { + diffNdx[numberChanged] = i ; + diffVal[numberChanged++] = newVal[i] ; + } + /* + Create the object of our desire. + */ + CoinWarmStartVectorDiff<T> *diff = + new CoinWarmStartVectorDiff<T>(numberChanged,diffNdx,diffVal) ; + /* + Clean up and return. + */ + delete[] diffNdx ; + delete[] diffVal ; + + return diff; + // return (dynamic_cast<CoinWarmStartDiff<T>*>(diff)) ; +} + + +/* + Apply diff to this warm start. + + Update this warm start by applying diff. It's assumed that the + allocated capacity of the warm start is sufficiently large. +*/ + +template <typename T> void +CoinWarmStartVector<T>::applyDiff (const CoinWarmStartDiff *const cwsdDiff) +{ + /* + Make sure we have a CoinWarmStartVectorDiff + */ + const CoinWarmStartVectorDiff<T>* diff = + dynamic_cast<const CoinWarmStartVectorDiff<T>*>(cwsdDiff) ; + if (!diff) { + throw CoinError("Diff not derived from CoinWarmStartVectorDiff.", + "applyDiff","CoinWarmStartVector") ; + } + /* + Application is by straighforward replacement of words in the vector vector. + */ + const int numberChanges = diff->sze_ ; + const unsigned int *diffNdxs = diff->diffNdxs_ ; + const T* diffVals = diff->diffVals_ ; + T* vals = this->values_ ; + + for (int i = 0 ; i < numberChanges ; i++) { + unsigned int diffNdx = diffNdxs[i] ; + T diffVal = diffVals[i] ; + vals[diffNdx] = diffVal ; + } +} + +//############################################################################# + + +// Assignment + +template <typename T> CoinWarmStartVectorDiff<T>& +CoinWarmStartVectorDiff<T>::operator=(const CoinWarmStartVectorDiff<T> &rhs) +{ + if (this != &rhs) { + if (sze_ > 0) { + delete[] diffNdxs_ ; + delete[] diffVals_ ; + } + sze_ = rhs.sze_ ; + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } else { + diffNdxs_ = 0 ; + diffVals_ = 0 ; + } + } + + return (*this) ; +} + + +// Copy constructor + +template <typename T> +CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff(const CoinWarmStartVectorDiff<T> &rhs) + : sze_(rhs.sze_), + diffNdxs_(0), + diffVals_(0) +{ + if (sze_ > 0) { + diffNdxs_ = new unsigned int[sze_] ; + memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ; + diffVals_ = new T[sze_] ; + memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(T)) ; + } +} + +/// Standard constructor + +template <typename T> +CoinWarmStartVectorDiff<T>::CoinWarmStartVectorDiff +(int sze, const unsigned int *const diffNdxs, const T *const diffVals) + : sze_(sze), + diffNdxs_(0), + diffVals_(0) +{ + if (sze > 0) { + diffNdxs_ = new unsigned int[sze] ; + memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ; + diffVals_ = new T[sze] ; + memcpy(diffVals_,diffVals,sze*sizeof(T)) ; + } +} + +#endif diff --git a/thirdparty/linux/include/coin1/Coin_C_defines.h b/thirdparty/linux/include/coin1/Coin_C_defines.h new file mode 100644 index 0000000..5c43aaa --- /dev/null +++ b/thirdparty/linux/include/coin1/Coin_C_defines.h @@ -0,0 +1,115 @@ +/* $Id: Coin_C_defines.h 1690 2014-03-13 17:45:21Z mlubin $ */ +/* + Copyright (C) 2002, 2003 International Business Machines Corporation + and others. All Rights Reserved. + + This code is licensed under the terms of the Eclipse Public License (EPL). +*/ +#ifndef CoinCDefine_H +#define CoinCDefine_H + +/** This has #defines etc for the "C" interface to Coin. + If COIN_EXTERN_C defined then an extra extern C +*/ + +#if defined (CLP_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_SBB +#define COIN_NO_CBC +#endif +#if defined (SBB_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +#if defined (CBC_EXTERN_C) +#define COIN_EXTERN_C +#define COIN_NO_CLP +#endif +/* We need to allow for Microsoft */ +#ifndef COINLIBAPI + +#if defined(CBCCINTERFACEDLL_EXPORTS) || defined(CLPMSDLL) +#if defined (COIN_EXTERN_C) +# define COINLIBAPI __declspec(dllexport) +#else +# define COINLIBAPI __declspec(dllexport) +#endif +# define COINLINKAGE __stdcall +# define COINLINKAGE_CB __cdecl +#else +#if defined (COIN_EXTERN_C) +# define COINLIBAPI extern "C" +#else +# define COINLIBAPI +#endif +# define COINLINKAGE +# define COINLINKAGE_CB +#endif + +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (CLP_EXTERN_C) +/* Real typedef for structure */ +class CMessageHandler; +typedef struct { + ClpSimplex * model_; + CMessageHandler * handler_; +} Clp_Simplex; +#else +typedef void Clp_Simplex; +#endif + +#ifndef COIN_NO_CLP +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *clp_callback) (Clp_Simplex * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +/** User does not need to see structure of model but C++ code does */ +#if defined (SBB_EXTERN_C) +/* Real typedef for structure */ +class Sbb_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + SbbModel * model_; + Sbb_MessageHandler * handler_; + char * information_; +} Sbb_Model; +#else +typedef void Sbb_Model; +#endif +#if defined (CBC_EXTERN_C) +/* Real typedef for structure */ +class Cbc_MessageHandler; +typedef struct { + OsiClpSolverInterface * solver_; + CbcModel * model_; + Cbc_MessageHandler * handler_; + std::vector<std::string> cmdargs_; +} Cbc_Model; +#else +typedef void Cbc_Model; +#endif +#ifndef COIN_NO_SBB +/** typedef for user call back. + The cvec are constructed so don't need to be const*/ +typedef void (COINLINKAGE_CB *sbb_callback) (Sbb_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +typedef void (COINLINKAGE_CB *cbc_callback) (Cbc_Model * model,int msgno, int ndouble, + const double * dvec, int nint, const int * ivec, + int nchar, char ** cvec); +#endif +#if COIN_BIG_INDEX==0 +typedef int CoinBigIndex; +#elif COIN_BIG_INDEX==1 +typedef long CoinBigIndex; +#else +typedef long long CoinBigIndex; +#endif +/* just in case used somewhere */ +#undef COIN_NO_CLP +#undef COIN_NO_SBB +#undef COIN_NO_CBC +#endif diff --git a/thirdparty/linux/include/coin1/HSLLoader.h b/thirdparty/linux/include/coin1/HSLLoader.h new file mode 100644 index 0000000..c38915c --- /dev/null +++ b/thirdparty/linux/include/coin1/HSLLoader.h @@ -0,0 +1,378 @@ +/* Copyright (C) 2008, 2011 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: HSLLoader.h 2317 2013-06-01 13:16:07Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef HSLLOADER_H_ +#define HSLLOADER_H_ + +#include "IpoptConfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ma77_default_control +#define ma77_control ma77_control_d +#define ma77_info ma77_info_d +#define ma77_default_control ma77_default_control_d +#define ma77_open_nelt ma77_open_nelt_d +#define ma77_open ma77_open_d +#define ma77_input_vars ma77_input_vars_d +#define ma77_input_reals ma77_input_reals_d +#define ma77_analyse ma77_analyse_d +#define ma77_factor ma77_factor_d +#define ma77_factor_solve ma77_factor_solve_d +#define ma77_solve ma77_solve_d +#define ma77_resid ma77_resid_d +#define ma77_scale ma77_scale_d +#define ma77_enquire_posdef ma77_enquire_posdef_d +#define ma77_enquire_indef ma77_enquire_indef_d +#define ma77_alter ma77_alter_d +#define ma77_restart ma77_restart_d +#define ma77_finalise ma77_finalise_d +#endif + +struct ma77_control; +struct ma77_info; +typedef double ma77pkgtype_d_; + + +#ifndef ma86_default_control +#define ma86_control ma86_control_d +#define ma86_info ma86_info_d +#define ma86_default_control ma86_default_control_d +#define ma86_analyse ma86_analyse_d +#define ma86_factor ma86_factor_d +#define ma86_factor_solve ma86_factor_solve_d +#define ma86_solve ma86_solve_d +#define ma86_finalise ma86_finalise_d +#endif + +struct ma86_control; +struct ma86_info; +typedef double ma86pkgtype_d_; +typedef double ma86realtype_d_; + +#ifndef ma97_default_control +#define ma97_control ma97_control_d +#define ma97_info ma97_info_d +#define ma97_default_control ma97_default_control_d +#define ma97_analyse ma97_analyse_d +#define ma97_factor ma97_factor_d +#define ma97_factor_solve ma97_factor_solve_d +#define ma97_solve ma97_solve_d +#define ma97_finalise ma97_finalise_d +#define ma97_free_akeep ma97_free_akeep_d +#endif + +struct ma97_control; +struct ma97_info; +typedef double ma97pkgtype_d_; +typedef double ma97realtype_d_; + +struct mc68_control_i; +struct mc68_info_i; + +#ifndef __IPTYPES_HPP__ +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; +#endif + +typedef void (*ma27ad_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + ipfint *IW, ipfint* LIW, ipfint* IKEEP, ipfint *IW1, + ipfint* NSTEPS, ipfint* IFLAG, ipfint* ICNTL, + double* CNTL, ipfint *INFO, double* OPS); +typedef void (*ma27bd_t)(ipfint *N, ipfint *NZ, const ipfint *IRN, const ipfint* ICN, + double* A, ipfint* LA, ipfint* IW, ipfint* LIW, + ipfint* IKEEP, ipfint* NSTEPS, ipfint* MAXFRT, + ipfint* IW1, ipfint* ICNTL, double* CNTL, + ipfint* INFO); +typedef void (*ma27cd_t)(ipfint *N, double* A, ipfint* LA, ipfint* IW, + ipfint* LIW, double* W, ipfint* MAXFRT, + double* RHS, ipfint* IW1, ipfint* NSTEPS, + ipfint* ICNTL, double* CNTL); +typedef void (*ma27id_t)(ipfint* ICNTL, double* CNTL); + +typedef void (*ma28ad_t)(void* nsize, void* nz, void* rw, void* licn, void* iw, + void* lirn, void* iw2, void* pivtol, void* iw3, void* iw4, void* rw2, void* iflag); + +typedef void (*ma57ad_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + const ipfint *irn, /* Matrix nonzero row structure */ + const ipfint *jcn, /* Matrix nonzero column structure */ + ipfint *lkeep, /* Workspace for the pivot order of lenght 3*n */ + ipfint *keep, /* Workspace for the pivot order of lenght 3*n */ + /* Automatically iflag = 0; ikeep pivot order iflag = 1 */ + ipfint *iwork, /* Integer work space. */ + ipfint *icntl, /* Integer Control parameter of length 30*/ + ipfint *info, /* Statistical Information; Integer array of length 20 */ + double *rinfo); /* Double Control parameter of length 5 */ + +typedef void (*ma57bd_t) ( + ipfint *n, /* Order of matrix. */ + ipfint *ne, /* Number of entries. */ + double *a, /* Numerical values. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *lkeep, /* Length of array `keep'. */ + ipfint *keep, /* Integer array. */ + ipfint *iwork, /* Workspace of length `n'. */ + ipfint *icntl, /* Integer Control parameter of length 20. */ + double *cntl, /* Double Control parameter of length 5. */ + ipfint *info, /* Statistical Information; Integer array of length 40. */ + double *rinfo); /* Statistical Information; Real array of length 20. */ + +typedef void (*ma57cd_t) ( + ipfint *job, /* Solution job. Solve for... */ + ipfint *n, /* Order of matrix. */ + double *fact, /* Entries of factors. */ + ipfint *lfact, /* Length of array `fact'. */ + ipfint *ifact, /* Indexing info for factors. */ + ipfint *lifact, /* Length of array `ifact'. */ + ipfint *nrhs, /* Number of right hand sides. */ + double *rhs, /* Numerical Values. */ + ipfint *lrhs, /* Leading dimensions of `rhs'. */ + double *work, /* Real workspace. */ + ipfint *lwork, /* Length of `work', >= N*NRHS. */ + ipfint *iwork, /* Integer array of length `n'. */ + ipfint *icntl, /* Integer Control parameter array of length 20. */ + ipfint *info); /* Statistical Information; Integer array of length 40. */ + +typedef void (*ma57ed_t) ( + ipfint *n, + ipfint *ic, /* 0: copy real array. >=1: copy integer array. */ + ipfint *keep, + double *fact, + ipfint *lfact, + double *newfac, + ipfint *lnew, + ipfint *ifact, + ipfint *lifact, + ipfint *newifc, + ipfint *linew, + ipfint *info); + +typedef void (*ma57id_t) (double *cntl, ipfint *icntl); + +typedef void (*ma77_default_control_t)(struct ma77_control_d *control); +typedef void (*ma77_open_nelt_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const int nelt); +typedef void (*ma77_open_t)(const int n, const char* fname1, const char* fname2, + const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_vars_t)(const int idx, const int nvar, const int list[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_input_reals_t)(const int idx, const int length, + const double reals[], void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); +typedef void (*ma77_analyse_t)(const int order[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_factor_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_factor_solve_t)(const int posdef, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale, const int nrhs, const int lx, + double rhs[]); +typedef void (*ma77_solve_t)(const int job, const int nrhs, const int lx, double x[], + void **keep, const struct ma77_control_d *control, struct ma77_info_d *info, + const double *scale); +typedef void (*ma77_resid_t)(const int nrhs, const int lx, const double x[], + const int lresid, double resid[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm_bnd); +typedef void (*ma77_scale_t)(double scale[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info, + double *anorm); +typedef void (*ma77_enquire_posdef_t)(double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_enquire_indef_t)(int piv_order[], double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_alter_t)(const double d[], void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_restart_t)(const char *restart_file, const char *fname1, + const char *fname2, const char *fname3, const char *fname4, void **keep, + const struct ma77_control_d *control, struct ma77_info_d *info); +typedef void (*ma77_finalise_t)(void **keep, const struct ma77_control_d *control, + struct ma77_info_d *info); + +typedef void (*ma86_default_control_t)(struct ma86_control *control); +typedef void (*ma86_analyse_t)(const int n, const int ptr[], const int row[], + int order[], void **keep, const struct ma86_control *control, + struct ma86_info *info); +typedef void (*ma86_factor_t)(const int n, const int ptr[], const int row[], + const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_factor_solve_t)(const int n, const int ptr[], + const int row[], const ma86pkgtype_d_ val[], const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, const int nrhs, + const int ldx, ma86pkgtype_d_ x[], const ma86pkgtype_d_ scale[]); +typedef void (*ma86_solve_t)(const int job, const int nrhs, const int ldx, + ma86pkgtype_d_ *x, const int order[], void **keep, + const struct ma86_control *control, struct ma86_info *info, + const ma86pkgtype_d_ scale[]); +typedef void (*ma86_finalise_t)(void **keep, + const struct ma86_control *control); + +typedef void (*ma97_default_control_t)(struct ma97_control *control); +typedef void (*ma97_analyse_t)(const int check, const int n, const int ptr[], + const int row[], ma97pkgtype_d_ val[], void **akeep, + const struct ma97_control *control, struct ma97_info *info, int order[]); +typedef void (*ma97_factor_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_factor_solve_t)(const int matrix_type, const int ptr[], + const int row[], const ma97pkgtype_d_ val[], const int nrhs, + ma97pkgtype_d_ x[], const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info, + const ma97pkgtype_d_ scale[]); +typedef void (*ma97_solve_t)(const int job, const int nrhs, ma97pkgtype_d_ *x, + const int ldx, void **akeep, void **fkeep, + const struct ma97_control *control, struct ma97_info *info); +typedef void (*ma97_finalise_t)(void **akeep, void **fkeep); +typedef void (*ma97_free_akeep_t)(void **akeep); + +typedef void (*mc19ad_t)(ipfint *N, ipfint *NZ, double* A, ipfint *IRN, ipfint* ICN, float* R, float* C, float* W); + +typedef void (*mc68_default_control_t)(struct mc68_control_i *control); +typedef void (*mc68_order_t)(int ord, int n, const int ptr[], + const int row[], int perm[], const struct mc68_control_i *control, + struct mc68_info_i *info); + + /** Tries to load a dynamically linked library with HSL routines. + * Also tries to load symbols for those HSL routines that are not linked into Ipopt, i.e., HAVE_... is not defined. + * Return a failure if the library cannot be loaded, but not if a symbol is not found. + * @see LSL_isMA27available + * @see LSL_isMA28available + * @see LSL_isMA57available + * @see LSL_isMA77available + * @see LSL_isMA86available + * @see LSL_isMA97available + * @see LSL_isMC19available + * @param libname The name under which the HSL lib can be found, or NULL to use a default name (libhsl.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadHSL(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded HSL library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadHSL(); + + /** Indicates whether a HSL library has been loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isHSLLoaded(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA27 have been found. + * @return Zero if not available, nonzero if MA27 is available in the loaded library. + */ + int LSL_isMA27available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA28 have been found. + * @return Zero if not available, nonzero if MA28 is available in the loaded library. + */ + int LSL_isMA28available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MA57 is available in the loaded library. + */ + int LSL_isMA57available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA77 have been found. + * @return Zero if not available, nonzero if HSL_MA77 is available in the loaded library. + */ + int LSL_isMA77available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA86 have been found. + * @return Zero if not available, nonzero if HSL_MA86 is available in the loaded library. + */ + int LSL_isMA86available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MA97 have been found. + * @return Zero if not available, nonzero if HSL_MA97 is available in the loaded library. + */ + int LSL_isMA97available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use MA57 have been found. + * @return Zero if not available, nonzero if MC19 is available in the loaded library. + */ + int LSL_isMC19available(); + + /** Indicates whether a HSL library is loaded and all symbols necessary to use HSL_MC68 have been found. + * @return Zero if not available, nonzero if MC68 is available in the loaded library. + */ + int LSL_isMC68available(); + + /** Returns name of the shared library that should contain HSL */ + char* LSL_HSLLibraryName(); + + /** sets pointers to MA27 functions */ + void LSL_setMA27(ma27ad_t ma27ad, ma27bd_t ma27bd, ma27cd_t ma27cd, ma27id_t ma27id); + + /** sets pointers to MA28 functions */ + void LSL_setMA28(ma28ad_t ma28ad); + + /** sets pointers to MA57 functions */ + void LSL_setMA57(ma57ad_t ma57ad, ma57bd_t ma57bd, ma57cd_t ma57cd, ma57ed_t ma57ed, ma57id_t ma57id); + + /** sets pointers to MA77 functions */ + void LSL_setMA77(ma77_default_control_t ma77_default_control, + ma77_open_nelt_t ma77_open_nelt, + ma77_open_t ma77_open, + ma77_input_vars_t ma77_input_vars, + ma77_input_reals_t ma77_input_reals, + ma77_analyse_t ma77_analyse, + ma77_factor_t ma77_factor, + ma77_factor_solve_t ma77_factor_solve, + ma77_solve_t ma77_solve, + ma77_resid_t ma77_resid, + ma77_scale_t ma77_scale, + ma77_enquire_posdef_t ma77_enquire_posdef, + ma77_enquire_indef_t ma77_enquire_indef, + ma77_alter_t ma77_alter, + ma77_restart_t ma77_restart, + ma77_finalise_t ma77_finalise); + + /** sets pointers to MA86 functions */ + void LSL_setMA86(ma86_default_control_t ma86_default_control, + ma86_analyse_t ma86_analyse, + ma86_factor_t ma86_factor, + ma86_factor_solve_t ma86_factor_solve, + ma86_solve_t ma86_solve, + ma86_finalise_t ma86_finalise); + + /** sets pointers to MA97 functions */ + void LSL_setMA97(ma97_default_control_t ma97_default_control, + ma97_analyse_t ma97_analyse, + ma97_factor_t ma97_factor, + ma97_factor_solve_t ma97_factor_solve, + ma97_solve_t ma97_solve, + ma97_finalise_t ma97_finalise, + ma97_free_akeep_t ma97_free_akeep); + + /** sets pointer to MC19 function */ + void LSL_setMC19(mc19ad_t mc19ad); + + /** sets pointers to MC68 functions */ + void LSL_setMC68(mc68_default_control_t mc68_default_control, mc68_order_t mc68_order); + +#ifdef __cplusplus +} +#endif + +#endif /*HSLLOADER_H_*/ diff --git a/thirdparty/linux/include/coin1/Idiot.hpp b/thirdparty/linux/include/coin1/Idiot.hpp new file mode 100644 index 0000000..a3d7891 --- /dev/null +++ b/thirdparty/linux/include/coin1/Idiot.hpp @@ -0,0 +1,297 @@ +/* $Id: Idiot.hpp 2078 2015-01-05 12:39:49Z forrest $ */ +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +// "Idiot" as the name of this algorithm is copylefted. If you want to change +// the name then it should be something equally stupid (but not "Stupid") or +// even better something witty. + +#ifndef Idiot_H +#define Idiot_H +#ifndef OSI_IDIOT +#include "ClpSimplex.hpp" +#define OsiSolverInterface ClpSimplex +#else +#include "OsiSolverInterface.hpp" +typedef int CoinBigIndex; +#endif +class CoinMessageHandler; +class CoinMessages; +/// for use internally +typedef struct { + double infeas; + double objval; + double dropThis; + double weighted; + double sumSquared; + double djAtBeginning; + double djAtEnd; + int iteration; +} IdiotResult; +/** This class implements a very silly algorithm. It has no merit + apart from the fact that it gets an approximate solution to + some classes of problems. Better if vaguely homogeneous. + It works on problems where volume algorithm works and often + gets a better primal solution but it has no dual solution. + + It can also be used as a "crash" to get a problem started. This + is probably its most useful function. + + It is based on the idea that algorithms with terrible convergence + properties may be okay at first. Throw in some random dubious tricks + and the resulting code may be worth keeping as long as you don't + look at it. + +*/ + +class Idiot { + +public: + + /**@name Constructors and destructor + Just a pointer to model is kept + */ + //@{ + /// Default constructor + Idiot ( ); + /// Constructor with model + Idiot ( OsiSolverInterface & model ); + + /// Copy constructor. + Idiot(const Idiot &); + /// Assignment operator. This copies the data + Idiot & operator=(const Idiot & rhs); + /// Destructor + ~Idiot ( ); + //@} + + + /**@name Algorithmic calls + */ + //@{ + /// Get an approximate solution with the idiot code + void solve(); + /// Lightweight "crash" + void crash(int numberPass, CoinMessageHandler * handler, + const CoinMessages * messages, bool doCrossover = true); + /** Use simplex to get an optimal solution + mode is how many steps the simplex crossover should take to + arrive to an extreme point: + 0 - chosen,all ever used, all + 1 - chosen, all + 2 - all + 3 - do not do anything - maybe basis + + 16 do presolves + */ + void crossOver(int mode); + //@} + + + /**@name Gets and sets of most useful data + */ + //@{ + /** Starting weight - small emphasizes feasibility, + default 1.0e-4 */ + inline double getStartingWeight() const { + return mu_; + } + inline void setStartingWeight(double value) { + mu_ = value; + } + /** Weight factor - weight multiplied by this when changes, + default 0.333 */ + inline double getWeightFactor() const { + return muFactor_; + } + inline void setWeightFactor(double value) { + muFactor_ = value; + } + /** Feasibility tolerance - problem essentially feasible if + individual infeasibilities less than this. + default 0.1 */ + inline double getFeasibilityTolerance() const { + return smallInfeas_; + } + inline void setFeasibilityTolerance(double value) { + smallInfeas_ = value; + } + /** Reasonably feasible. Dubious method concentrates more on + objective when sum of infeasibilities less than this. + Very dubious default value of (Number of rows)/20 */ + inline double getReasonablyFeasible() const { + return reasonableInfeas_; + } + inline void setReasonablyFeasible(double value) { + reasonableInfeas_ = value; + } + /** Exit infeasibility - exit if sum of infeasibilities less than this. + Default -1.0 (i.e. switched off) */ + inline double getExitInfeasibility() const { + return exitFeasibility_; + } + inline void setExitInfeasibility(double value) { + exitFeasibility_ = value; + } + /** Major iterations. stop after this number. + Default 30. Use 2-5 for "crash" 50-100 for serious crunching */ + inline int getMajorIterations() const { + return majorIterations_; + } + inline void setMajorIterations(int value) { + majorIterations_ = value; + } + /** Minor iterations. Do this number of tiny steps before + deciding whether to change weights etc. + Default - dubious sqrt(Number of Rows). + Good numbers 105 to 405 say (5 is dubious method of making sure + idiot is not trying to be clever which it may do every 10 minor + iterations) */ + inline int getMinorIterations() const { + return maxIts2_; + } + inline void setMinorIterations(int value) { + maxIts2_ = value; + } + // minor iterations for first time + inline int getMinorIterations0() const { + return maxIts_; + } + inline void setMinorIterations0(int value) { + maxIts_ = value; + } + /** Reduce weight after this many major iterations. It may + get reduced before this but this is a maximum. + Default 3. 3-10 plausible. */ + inline int getReduceIterations() const { + return maxBigIts_; + } + inline void setReduceIterations(int value) { + maxBigIts_ = value; + } + /// Amount of information - default of 1 should be okay + inline int getLogLevel() const { + return logLevel_; + } + inline void setLogLevel(int value) { + logLevel_ = value; + } + /// How lightweight - 0 not, 1 yes, 2 very lightweight + inline int getLightweight() const { + return lightWeight_; + } + inline void setLightweight(int value) { + lightWeight_ = value; + } + /// strategy + inline int getStrategy() const { + return strategy_; + } + inline void setStrategy(int value) { + strategy_ = value; + } + /// Fine tuning - okay if feasibility drop this factor + inline double getDropEnoughFeasibility() const { + return dropEnoughFeasibility_; + } + inline void setDropEnoughFeasibility(double value) { + dropEnoughFeasibility_ = value; + } + /// Fine tuning - okay if weighted obj drop this factor + inline double getDropEnoughWeighted() const { + return dropEnoughWeighted_; + } + inline void setDropEnoughWeighted(double value) { + dropEnoughWeighted_ = value; + } + /// Set model + inline void setModel(OsiSolverInterface * model) { + model_ = model; + }; + //@} + + +/// Stuff for internal use +private: + + /// Does actual work + // allow public! +public: + void solve2(CoinMessageHandler * handler, const CoinMessages *messages); +private: + IdiotResult IdiSolve( + int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * origcost , + double * rowlower, + double * rowupper, const double * lower, + const double * upper, const double * element, + const int * row, const CoinBigIndex * colcc, + const int * length, double * lambda, + int maxIts, double mu, double drop, + double maxmin, double offset, + int strategy, double djTol, double djExit, double djFlag, + CoinThreadRandom * randomNumberGenerator); + int dropping(IdiotResult result, + double tolerance, + double small, + int *nbad); + IdiotResult objval(int nrows, int ncols, double * rowsol , double * colsol, + double * pi, double * djs, const double * cost , + const double * rowlower, + const double * rowupper, const double * lower, + const double * upper, const double * elemnt, + const int * row, const CoinBigIndex * columnStart, + const int * length, int extraBlock, int * rowExtra, + double * solExtra, double * elemExtra, double * upperExtra, + double * costExtra, double weight); + // Deals with whenUsed and slacks + int cleanIteration(int iteration, int ordinaryStart, int ordinaryEnd, + double * colsol, const double * lower, const double * upper, + const double * rowLower, const double * rowUpper, + const double * cost, const double * element, double fixTolerance, double & objChange, + double & infChange, double & maxInfeasibility); +private: + /// Underlying model + OsiSolverInterface * model_; + + double djTolerance_; + double mu_; /* starting mu */ + double drop_; /* exit if drop over 5 checks less than this */ + double muFactor_; /* reduce mu by this */ + double stopMu_; /* exit if mu gets smaller than this */ + double smallInfeas_; /* feasibility tolerance */ + double reasonableInfeas_; /* use lambdas if feasibility less than this */ + double exitDrop_; /* candidate for stopping after a major iteration */ + double muAtExit_; /* mu on exit */ + double exitFeasibility_; /* exit if infeasibility less than this */ + double dropEnoughFeasibility_; /* okay if feasibility drop this factor */ + double dropEnoughWeighted_; /* okay if weighted obj drop this factor */ + int * whenUsed_; /* array to say what was used */ + int maxBigIts_; /* always reduce mu after this */ + int maxIts_; /* do this many iterations on first go */ + int majorIterations_; + int logLevel_; + int logFreq_; + int checkFrequency_; /* can exit after 5 * this iterations (on drop) */ + int lambdaIterations_; /* do at least this many lambda iterations */ + int maxIts2_; /* do this many iterations on subsequent goes */ + int strategy_; /* 0 - default strategy + 1 - do accelerator step but be cautious + 2 - do not do accelerator step + 4 - drop, exitDrop and djTolerance all relative + 8 - keep accelerator step to theta=10.0 + + 32 - Scale + 512 - crossover + 2048 - keep lambda across mu change + 4096 - return best solution (not last found) + 8192 - always do a presolve in crossover + 16384 - costed slacks found - so whenUsed_ longer + 32768 - experimental 1 + 65536 - experimental 2 + 131072 - experimental 3 + 262144 - just values pass etc */ + + int lightWeight_; // 0 - normal, 1 lightweight +}; +#endif diff --git a/thirdparty/linux/include/coin1/IpAlgBuilder.hpp b/thirdparty/linux/include/coin1/IpAlgBuilder.hpp new file mode 100644 index 0000000..05692bb --- /dev/null +++ b/thirdparty/linux/include/coin1/IpAlgBuilder.hpp @@ -0,0 +1,360 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgBuilder.hpp 2666 2016-07-20 16:02:55Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-29 + +#ifndef __IPALGBUILDER_HPP__ +#define __IPALGBUILDER_HPP__ + +#include "IpIpoptAlg.hpp" +#include "IpReferenced.hpp" +#include "IpAugSystemSolver.hpp" +#include "IpPDSystemSolver.hpp" + +namespace Ipopt +{ + + // forward declarations + class IterationOutput; + class HessianUpdater; + class ConvergenceCheck; + class SearchDirectionCalculator; + class EqMultiplierCalculator; + class IterateInitializer; + class LineSearch; + class MuUpdate; + + /** Builder for creating a complete IpoptAlg object. This object + * contains all subelements (such as line search objects etc). How + * the resulting IpoptAlg object is built can be influenced by the + * options. + * + * More advanced customization can be achieved by subclassing this + * class and overloading the virtual methods that build the + * individual parts. The advantage of doing this is that it allows + * one to reuse the extensive amount of options processing that + * takes place, for instance, when generating the symmetric linear + * system solver. Another method for customizing the algorithm is + * using the optional custom_solver argument, which allows the + * expert user to provide a specialized linear solver for the + * augmented system (e.g., type GenAugSystemSolver), possibly for + * user-defined matrix objects. The optional custom_solver constructor + * argument is likely obsolete, however, as more control over this + * this process can be achieved by implementing a subclass of this + * AlgBuilder (e.g., by overloading the AugSystemSolverFactory method). + */ + class AlgorithmBuilder : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + AlgorithmBuilder(SmartPtr<AugSystemSolver> custom_solver=NULL); + + /** Destructor */ + virtual ~AlgorithmBuilder() + {} + + //@} + + /** Methods for IpoptTypeInfo */ + //@{ + /** register the options used by the algorithm builder */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** @name Convenience methods for building solvers without having + * to duplicate the significant amount of preprocessor flag and + * option checking that takes place. These solvers are used to + * create a number of core algorithm components across the + * different Build* methods, but depending on what options are + * chosen, the first method requiring the solver to be used can + * vary. Therefore, each of the Factory methods below is paired + * with a Getter method, which is called by all parts of this + * algorithm builder to ensure the Factory is only called once. */ + //@{ + + /** Create a solver that can be used to solve a symmetric linear + * system. + * Dependencies: None + */ + virtual SmartPtr<SymLinearSolver> + SymLinearSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the symmetric linear system solver for this + * algorithm. This method will call the SymLinearSolverFactory + * exactly once (the first time it is used), and store its + * instance on SymSolver_ for use in subsequent calls. + */ + SmartPtr<SymLinearSolver> GetSymLinearSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve an + * augmented system. + * Dependencies: + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<AugSystemSolver> + AugSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the augmented system solver for this algorithm. This + * method will call the AugSystemSolverFactory exactly once (the + * first time it is used), and store its instance on AugSolver_ + * for use in subsequent calls. + */ + SmartPtr<AugSystemSolver> GetAugSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Create a solver that can be used to solve a + * primal-dual system. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<PDSystemSolver> + PDSystemSolverFactory(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Get the primal-dual system solver for this algorithm. This + * method will call the PDSystemSolverFactory exactly once (the + * first time it is used), and store its instance on PDSolver_ + * for use in subsequent calls. + */ + SmartPtr<PDSystemSolver> GetPDSystemSolver(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + /** @name Methods to build parts of the algorithm */ + //@{ + /** Allocates memory for the IpoptNLP, IpoptData, and + * IpoptCalculatedQuanties arguments. + * Dependencies: None + */ + virtual void BuildIpoptObjects(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix, + const SmartPtr<NLP>& nlp, + SmartPtr<IpoptNLP>& ip_nlp, + SmartPtr<IpoptData>& ip_data, + SmartPtr<IpoptCalculatedQuantities>& ip_cq); + + /** Creates an instance of the IpoptAlgorithm class by building + * each of its required constructor arguments piece-by-piece. The + * default algorithm can be customized by overloading this method + * or by overloading one or more of the Build* methods called in + * this method's default implementation. Additional control can + * be achieved by overloading any of the *SolverFactory methods. + * This method will call (in this order): + * -> BuildIterationOutput() + * -> BuildHessianUpdater() + * -> BuildConvergenceCheck() + * -> BuildSearchDirectionCalculator() + * -> BuildEqMultiplierCalculator() + * -> BuildIterateInitializer() + * -> BuildLineSearch() + * -> BuildMuUpdate() + */ + virtual SmartPtr<IpoptAlgorithm> BuildBasicAlgorithm(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterationOutput class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<IterationOutput> + BuildIterationOutput(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the HessianUpdater class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<HessianUpdater> + BuildHessianUpdater(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the ConvergenceCheck class. This method + * is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: None + */ + virtual SmartPtr<ConvergenceCheck> + BuildConvergenceCheck(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the SearchDirectionCalculator + * class. This method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<SearchDirectionCalculator> + BuildSearchDirectionCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the EqMultiplierCalculator class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<EqMultiplierCalculator> + BuildEqMultiplierCalculator(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the IterateInitializer class. This + * method is called in the default implementation of + * BuildBasicAlgorithm. It can be overloaded to customize that + * portion the default algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<IterateInitializer> + BuildIterateInitializer(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the LineSearch class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<LineSearch> BuildLineSearch(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Creates an instance of the MuUpdate class. This method is + * called in the default implementation of BuildBasicAlgorithm. + * It can be overloaded to customize that portion the default + * algorithm. + * Dependencies: + * -> LineSearch_ + * -> EqMultCalculator_ + * -> ConvCheck_ + * -> GetPDSystemSolver() + * -> PDSystemSolverFactory() + * -> GetAugSystemSolver() + * -> AugSystemSolverFactory() + * -> GetSymLinearSolver() + * -> SymLinearSolverFactory() + * -> custom_solver_ + */ + virtual SmartPtr<MuUpdate> BuildMuUpdate(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmBuilder(); + + /** Copy Constructor */ + AlgorithmBuilder(const AlgorithmBuilder&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmBuilder&); + //@} + + /** @name IpoptAlgorithm constructor arguments. + * These components are built in separate Build + * methods in the order defined by BuildBasicAlgorithm. + * A single core component may require one or more + * other core components in its constructor, so the + * this class holds pointers to each component for use + * between the separate Build methods. */ + //@{ + SmartPtr<IterationOutput> IterOutput_; + SmartPtr<HessianUpdater> HessUpdater_; + SmartPtr<ConvergenceCheck> ConvCheck_; + SmartPtr<SearchDirectionCalculator> SearchDirCalc_; + SmartPtr<EqMultiplierCalculator> EqMultCalculator_; + SmartPtr<IterateInitializer> IterInitializer_; + SmartPtr<LineSearch> LineSearch_; + SmartPtr<MuUpdate> MuUpdate_; + //@} + + /** @name Commonly used solver components + * for building core algorithm components. Each + * of these members is paired with a Factory/Getter + * method. */ + //@{ + SmartPtr<SymLinearSolver> SymSolver_; + SmartPtr<AugSystemSolver> AugSolver_; + SmartPtr<PDSystemSolver> PDSolver_; + //@} + + /** Optional pointer to AugSystemSolver. If this is set in the + * contructor, we will use this to solve the linear systems. */ + SmartPtr<AugSystemSolver> custom_solver_; + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpAlgStrategy.hpp b/thirdparty/linux/include/coin1/IpAlgStrategy.hpp new file mode 100644 index 0000000..746a968 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpAlgStrategy.hpp @@ -0,0 +1,185 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgStrategy.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPALGSTRATEGY_HPP__ +#define __IPALGSTRATEGY_HPP__ + +#include "IpOptionsList.hpp" +#include "IpJournalist.hpp" +#include "IpIpoptCalculatedQuantities.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" + +namespace Ipopt +{ + + /** This is the base class for all algorithm strategy objects. The + * AlgorithmStrategyObject base class implements a common interface + * for all algorithm strategy objects. A strategy object is a + * component of the algorithm for which different alternatives or + * implementations exists. It allows to compose the algorithm + * before execution for a particular configuration, without the + * need to call alternatives based on enums. For example, the + * LineSearch object is a strategy object, since different line + * search options might be used for different runs. + * + * This interface is used for + * things that are done to all strategy objects, like + * initialization and setting options. + */ + class AlgorithmStrategyObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + AlgorithmStrategyObject() + : + initialize_called_(false) + {} + + /** Default Destructor */ + virtual ~AlgorithmStrategyObject() + {} + //@} + + /** This method is called every time the algorithm starts again - + * it is used to reset any internal state. The pointers to the + * Journalist, as well as to the IpoptNLP, IpoptData, and + * IpoptCalculatedQuantities objects should be stored in the + * instanciation of this base class. This method is also used to + * get all required user options from the OptionsList. Here, if + * prefix is given, each tag (identifying the options) is first + * looked for with the prefix in front, and if not found, without + * the prefix. Note: you should not cue off of the iteration + * count to indicate the "start" of an algorithm! + * + * Do not overload this method, since it does some general + * initialization that is common for all strategy objects. + * Overload the protected InitializeImpl method instead. + */ + bool Initialize(const Journalist& jnlst, + IpoptNLP& ip_nlp, + IpoptData& ip_data, + IpoptCalculatedQuantities& ip_cq, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = &ip_nlp; + ip_data_ = &ip_data; + ip_cq_ = &ip_cq; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + /** Reduced version of the Initialize method, which does not + * require special Ipopt information. This is useful for + * algorithm objects that could be used outside Ipopt, such as + * linear solvers. */ + bool ReducedInitialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + initialize_called_ = true; + // Copy the pointers for the problem defining objects + jnlst_ = &jnlst; + ip_nlp_ = NULL; + ip_data_ = NULL; + ip_cq_ = NULL; + + bool retval = InitializeImpl(options, prefix); + if (!retval) { + initialize_called_ = false; + } + + return retval; + } + + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** @name Accessor methods for the problem defining objects. + * Those should be used by the derived classes. */ + //@{ + const Journalist& Jnlst() const + { + DBG_ASSERT(initialize_called_); + return *jnlst_; + } + IpoptNLP& IpNLP() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_nlp_)); + return *ip_nlp_; + } + IpoptData& IpData() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_data_)); + return *ip_data_; + } + IpoptCalculatedQuantities& IpCq() const + { + DBG_ASSERT(initialize_called_); + DBG_ASSERT(IsValid(ip_cq_)); + return *ip_cq_; + } + bool HaveIpData() const + { + return IsValid(ip_data_); + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //AlgorithmStrategyObject(); + + + /** Copy Constructor */ + AlgorithmStrategyObject(const AlgorithmStrategyObject&); + + /** Overloaded Equals Operator */ + void operator=(const AlgorithmStrategyObject&); + //@} + + /** @name Pointers to objects defining a particular optimization + * problem */ + //@{ + SmartPtr<const Journalist> jnlst_; + SmartPtr<IpoptNLP> ip_nlp_; + SmartPtr<IpoptData> ip_data_; + SmartPtr<IpoptCalculatedQuantities> ip_cq_; + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpAlgTypes.hpp b/thirdparty/linux/include/coin1/IpAlgTypes.hpp new file mode 100644 index 0000000..53e8ea5 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpAlgTypes.hpp @@ -0,0 +1,66 @@ +// Copyright (C) 2005, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAlgTypes.hpp 2551 2015-02-13 02:51:47Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-07-19 + +#ifndef __IPALGTYPES_HPP__ +#define __IPALGTYPES_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + /**@name Enumerations */ + //@{ + /** enum for the return from the optimize algorithm + * (obviously we need to add more) */ + enum SolverReturn { + SUCCESS, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + STOP_AT_TINY_STEP, + STOP_AT_ACCEPTABLE_POINT, + LOCAL_INFEASIBILITY, + USER_REQUESTED_STOP, + FEASIBLE_POINT_FOUND, + DIVERGING_ITERATES, + RESTORATION_FAILURE, + ERROR_IN_STEP_COMPUTATION, + INVALID_NUMBER_DETECTED, + TOO_FEW_DEGREES_OF_FREEDOM, + INVALID_OPTION, + OUT_OF_MEMORY, + INTERNAL_ERROR, + UNASSIGNED + }; + //@} + + /** @name Some exceptions used in multiple places */ + //@{ + DECLARE_STD_EXCEPTION(LOCALLY_INFEASIBLE); + DECLARE_STD_EXCEPTION(TOO_FEW_DOF); + DECLARE_STD_EXCEPTION(TINY_STEP_DETECTED); + DECLARE_STD_EXCEPTION(ACCEPTABLE_POINT_REACHED); + DECLARE_STD_EXCEPTION(FEASIBILITY_PROBLEM_SOLVED); + DECLARE_STD_EXCEPTION(INVALID_WARMSTART); + DECLARE_STD_EXCEPTION(INTERNAL_ABORT); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_BUT_FEASIBLE); + DECLARE_STD_EXCEPTION(NO_FREE_VARIABLES_AND_INFEASIBLE); + DECLARE_STD_EXCEPTION(INCONSISTENT_BOUNDS); + /** Exception FAILED_INITIALIZATION for problem during + * initialization of a strategy object (or other problems). This + * is thrown by a strategy object, if a problem arises during + * initialization, such as a value out of a feasible range. + */ + DECLARE_STD_EXCEPTION(FAILED_INITIALIZATION); + //@} + + +} + +#endif diff --git a/thirdparty/linux/include/coin1/IpAugSystemSolver.hpp b/thirdparty/linux/include/coin1/IpAugSystemSolver.hpp new file mode 100644 index 0000000..1396ce4 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpAugSystemSolver.hpp @@ -0,0 +1,200 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpAugSystemSolver.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IP_AUGSYSTEMSOLVER_HPP__ +#define __IP_AUGSYSTEMSOLVER_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpSymLinearSolver.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(FATAL_ERROR_IN_LINEAR_SOLVER); + + /** Base class for Solver for the augmented system. This is the + * base class for linear solvers that solve the augmented system, + * which is defined as + * + * \f$\left[\begin{array}{cccc} + * W + D_x + \delta_xI & 0 & J_c^T & J_d^T\\ + * 0 & D_s + \delta_sI & 0 & -I \\ + * J_c & 0 & D_c - \delta_cI & 0\\ + * J_d & -I & 0 & D_d - \delta_dI + * \end{array}\right] + * \left(\begin{array}{c}sol_x\\sol_s\\sol_c\\sol_d\end{array}\right)= + * \left(\begin{array}{c}rhs_x\\rhs_s\\rhs_c\\rhs_d\end{array}\right)\f$ + * + * Since this system might be solved repeatedly for different right + * hand sides, it is desirable to step the factorization of a + * direct linear solver if possible. + */ + class AugSystemSolver: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + AugSystemSolver() + {} + /** Default destructor */ + virtual ~AugSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Set up the augmented system and solve it for a given right hand + * side. If desired (i.e. if check_NegEVals is true), then the + * solution is only computed if the number of negative eigenvalues + * matches numberOfNegEVals. + * + * The return value is the return value of the linear solver object. + */ + virtual ESymSolverStatus Solve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + const Vector& rhs_x, + const Vector& rhs_s, + const Vector& rhs_c, + const Vector& rhs_d, + Vector& sol_x, + Vector& sol_s, + Vector& sol_c, + Vector& sol_d, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector<SmartPtr<const Vector> > rhs_xV(1); + rhs_xV[0] = &rhs_x; + std::vector<SmartPtr<const Vector> > rhs_sV(1); + rhs_sV[0] = &rhs_s; + std::vector<SmartPtr<const Vector> > rhs_cV(1); + rhs_cV[0] = &rhs_c; + std::vector<SmartPtr<const Vector> > rhs_dV(1); + rhs_dV[0] = &rhs_d; + std::vector<SmartPtr<Vector> > sol_xV(1); + sol_xV[0] = &sol_x; + std::vector<SmartPtr<Vector> > sol_sV(1); + sol_sV[0] = &sol_s; + std::vector<SmartPtr<Vector> > sol_cV(1); + sol_cV[0] = &sol_c; + std::vector<SmartPtr<Vector> > sol_dV(1); + sol_dV[0] = &sol_d; + return MultiSolve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, + J_d, D_d, delta_d, rhs_xV, rhs_sV, rhs_cV, rhs_dV, + sol_xV, sol_sV, sol_cV, sol_dV, check_NegEVals, + numberOfNegEVals); + } + + /** Like Solve, but for multiple right hand sides. The inheriting + * class has to be overload at least one of Solve and + * MultiSolve. */ + virtual ESymSolverStatus MultiSolve( + const SymMatrix* W, + double W_factor, + const Vector* D_x, + double delta_x, + const Vector* D_s, + double delta_s, + const Matrix* J_c, + const Vector* D_c, + double delta_c, + const Matrix* J_d, + const Vector* D_d, + double delta_d, + std::vector<SmartPtr<const Vector> >& rhs_xV, + std::vector<SmartPtr<const Vector> >& rhs_sV, + std::vector<SmartPtr<const Vector> >& rhs_cV, + std::vector<SmartPtr<const Vector> >& rhs_dV, + std::vector<SmartPtr<Vector> >& sol_xV, + std::vector<SmartPtr<Vector> >& sol_sV, + std::vector<SmartPtr<Vector> >& sol_cV, + std::vector<SmartPtr<Vector> >& sol_dV, + bool check_NegEVals, + Index numberOfNegEVals) + { + // Solve for one right hand side after the other + Index nrhs = (Index)rhs_xV.size(); + DBG_ASSERT(nrhs>0); + DBG_ASSERT(nrhs==(Index)rhs_sV.size()); + DBG_ASSERT(nrhs==(Index)rhs_cV.size()); + DBG_ASSERT(nrhs==(Index)rhs_dV.size()); + DBG_ASSERT(nrhs==(Index)sol_xV.size()); + DBG_ASSERT(nrhs==(Index)sol_sV.size()); + DBG_ASSERT(nrhs==(Index)sol_cV.size()); + DBG_ASSERT(nrhs==(Index)sol_dV.size()); + + ESymSolverStatus retval=SYMSOLVER_SUCCESS; + for (Index i=0; i<nrhs; i++) { + retval = Solve(W, W_factor, D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, + J_d, D_d, delta_d, + *rhs_xV[i], *rhs_sV[i], *rhs_cV[i], *rhs_dV[i], + *sol_xV[i], *sol_sV[i], *sol_cV[i], *sol_dV[i], + check_NegEVals, numberOfNegEVals); + if (retval!=SYMSOLVER_SUCCESS) { + break; + } + } + return retval; + } + + /** Number of negative eigenvalues detected during last + * solve. Returns the number of negative eigenvalues of + * the most recent factorized matrix. This must not be called if + * the linear solver does not compute this quantities (see + * ProvidesInertia). + */ + virtual Index NumberOfNegEVals() const =0; + + /** Query whether inertia is computed by linear solver. + * Returns true, if linear solver provides inertia. + */ + virtual bool ProvidesInertia() const =0; + + /** Request to increase quality of solution for next solve. Ask + * underlying linear solver to increase quality of solution for + * the next solve (e.g. increase pivot tolerance). Returns + * false, if this is not possible (e.g. maximal pivot tolerance + * already used.) + */ + virtual bool IncreaseQuality() =0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + AugSystemSolver(const AugSystemSolver&); + + /** Overloaded Equals Operator */ + void operator=(const AugSystemSolver&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpBlas.hpp b/thirdparty/linux/include/coin1/IpBlas.hpp new file mode 100644 index 0000000..517057b --- /dev/null +++ b/thirdparty/linux/include/coin1/IpBlas.hpp @@ -0,0 +1,78 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpBlas.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPBLAS_HPP__ +#define __IPBLAS_HPP__ + +#include "IpUtils.hpp" + +namespace Ipopt +{ + // If CBLAS is not available, this is our own interface to the Fortran + // implementation + + /** Wrapper for BLAS function DDOT. Compute dot product of vector x + and vector y */ + Number IpBlasDdot(Index size, const Number *x, Index incX, const Number *y, + Index incY); + + /** Wrapper for BLAS function DNRM2. Compute 2-norm of vector x*/ + Number IpBlasDnrm2(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS function DASUM. Compute 1-norm of vector x*/ + Number IpBlasDasum(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS function IDAMAX. Compute index for largest + absolute element of vector x */ + Index IpBlasIdamax(Index size, const Number *x, Index incX); + + /** Wrapper for BLAS subroutine DCOPY. Copying vector x into vector + y */ + void IpBlasDcopy(Index size, const Number *x, Index incX, Number *y, + Index incY); + + /** Wrapper for BLAS subroutine DAXPY. Adding the alpha multiple of + vector x to vector y */ + void IpBlasDaxpy(Index size, Number alpha, const Number *x, Index incX, + Number *y, Index incY); + + /** Wrapper for BLAS subroutine DSCAL. Scaling vector x by scalar + alpha */ + void IpBlasDscal(Index size, Number alpha, Number *x, Index incX); + + /** Wrapper for BLAS subroutine DGEMV. Multiplying a matrix with a + vector. */ + void IpBlasDgemv(bool trans, Index nRows, Index nCols, Number alpha, + const Number* A, Index ldA, const Number* x, + Index incX, Number beta, Number* y, Index incY); + + /** Wrapper for BLAS subroutine DSYMV. Multiplying a symmetric + matrix with a vector. */ + void IpBlasDsymv(Index n, Number alpha, const Number* A, Index ldA, + const Number* x, Index incX, Number beta, Number* y, + Index incY); + + /** Wrapper for BLAS subroutine DGEMM. Multiplying two matrices */ + void IpBlasDgemm(bool transa, bool transb, Index m, Index n, Index k, + Number alpha, const Number* A, Index ldA, const Number* B, + Index ldB, Number beta, Number* C, Index ldC); + + /** Wrapper for BLAS subroutine DSYRK. Adding a high-rank update to + * a matrix */ + void IpBlasDsyrk(bool trans, Index ndim, Index nrank, + Number alpha, const Number* A, Index ldA, + Number beta, Number* C, Index ldC); + + /** Wrapper for BLAS subroutine DTRSM. Backsolve for a lower triangular + * matrix. */ + void IpBlasDtrsm(bool trans, Index ndim, Index nrhs, Number alpha, + const Number* A, Index ldA, Number* B, Index ldB); + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpCachedResults.hpp b/thirdparty/linux/include/coin1/IpCachedResults.hpp new file mode 100644 index 0000000..b9f5f15 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpCachedResults.hpp @@ -0,0 +1,779 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCachedResults.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCACHEDRESULTS_HPP__ +#define __IPCACHEDRESULTS_HPP__ + +#include "IpTaggedObject.hpp" +#include "IpObserver.hpp" +#include <algorithm> +#include <vector> +#include <list> + +namespace Ipopt +{ + +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_CACHE +#endif +#ifdef IP_DEBUG_CACHE +# include "IpDebug.hpp" +#endif + + // Forward Declarations + + template <class T> + class DependentResult; + + // AW: I'm taking this out, since this is by far the most used + // class. We should keep it as simple as possible. + // /** Cache Priority Enum */ + // enum CachePriority + // { + // CP_Lowest, + // CP_Standard, + // CP_Trial, + // CP_Iterate + // }; + + /** Templated class for Cached Results. This class stores up to a + * given number of "results", entities that are stored here + * together with identifiers, that can be used to later retrieve the + * information again. + * + * Typically, T is a SmartPtr for some calculated quantity that + * should be stored (such as a Vector). The identifiers (or + * dependencies) are a (possibly varying) number of Tags from + * TaggedObjects, and a number of Numbers. Results are added to + * the cache using the AddCachedResults methods, and the can be + * retrieved with the GetCachedResults methods. The second set of + * methods checks whether a result has been cached for the given + * identifiers. If a corresponding result is found, a copy of it + * is returned and the method evaluates to true, otherwise it + * evaluates to false. + * + * Note that cached results can become "stale", namely when a + * TaggedObject that is used to identify this CachedResult is + * changed. When this happens, the cached result can never be + * asked for again, so that there is no point in storing it any + * longer. For this purpose, a cached result, which is stored as a + * DependentResult, inherits off an Observer. This Observer + * retrieves notification whenever a TaggedObject dependency has + * changed. Stale results are later removed from the cache. + */ + template <class T> + class CachedResults + { + public: +#ifdef IP_DEBUG_CACHE + /** (Only if compiled in DEBUG mode): debug verbosity level */ + static const Index dbg_verbosity; +#endif + + /** @name Constructors and Destructors. */ + //@{ + /** Constructor, where max_cache_size is the maximal number of + * results that should be cached. If max_cache_size is negative, + * we allow an infinite amount of cache. + */ + CachedResults(Int max_cache_size); + + /** Destructor */ + virtual ~CachedResults(); + //@} + + /** @name Generic methods for adding and retrieving cached results. */ + //@{ + /** Generic method for adding a result to the cache, given a + * std::vector of TaggesObjects and a std::vector of Numbers. + */ + void AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Generic method for retrieving a cached results, given the + * dependencies as a std::vector of TaggesObjects and a + * std::vector of Numbers. + */ + bool GetCachedResult(T& retResult, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const; + + /** Method for adding a result, providing only a std::vector of + * TaggedObjects. + */ + void AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents); + + /** Method for retrieving a cached result, providing only a + * std::vector of TaggedObjects. + */ + bool GetCachedResult(T& retResult, + const std::vector<const TaggedObject*>& dependents) const; + //@} + + /** @name Pointer-based methods for adding and retrieving cached + * results, providing dependencies explicitly. + */ + //@{ + /** Method for adding a result to the cache, proving one + * dependency as a TaggedObject explicitly. + */ + void AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1); + + /** Method for retrieving a cached result, proving one dependency + * as a TaggedObject explicitly. + */ + bool GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1); + + /** Method for adding a result to the cache, proving two + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult2Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for retrieving a cached result, proving two + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult2Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2); + + /** Method for adding a result to the cache, proving three + * dependencies as a TaggedObject explicitly. + */ + void AddCachedResult3Dep(const T& result, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** Method for retrieving a cached result, proving three + * dependencies as a TaggedObject explicitly. + */ + bool GetCachedResult3Dep(T& retResult, + const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3); + + /** @name Pointer-free version of the Add and Get methods */ + //@{ + bool GetCachedResult1Dep(T& retResult, const TaggedObject& dependent1) + { + return GetCachedResult1Dep(retResult, &dependent1); + } + bool GetCachedResult2Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + return GetCachedResult2Dep(retResult, &dependent1, &dependent2); + } + bool GetCachedResult3Dep(T& retResult, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + return GetCachedResult3Dep(retResult, &dependent1, &dependent2, &dependent3); + } + void AddCachedResult1Dep(const T& result, + const TaggedObject& dependent1) + { + AddCachedResult1Dep(result, &dependent1); + } + void AddCachedResult2Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2) + { + AddCachedResult2Dep(result, &dependent1, &dependent2); + } + void AddCachedResult3Dep(const T& result, + const TaggedObject& dependent1, + const TaggedObject& dependent2, + const TaggedObject& dependent3) + { + AddCachedResult3Dep(result, &dependent1, &dependent2, &dependent3); + } + //@} + + /** Invalidates the result for given dependencies. Sets the stale + * flag for the corresponding cached result to true if it is + * found. Returns true, if the result was found. */ + bool InvalidateResult(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Invalidates all cached results */ + void Clear(); + + /** Invalidate all cached results and changes max_cache_size */ + void Clear(Int max_cache_size); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CachedResults(); + + /** Copy Constructor */ + CachedResults(const CachedResults&); + + /** Overloaded Equals Operator */ + void operator=(const CachedResults&); + //@} + + /** maximum number of cached results */ + Int max_cache_size_; + + /** list of currently cached results. */ + mutable std::list<DependentResult<T>*>* cached_results_; + + /** internal method for removing stale DependentResults from the + * list. It is called at the beginning of every + * GetDependentResult method. + */ + void CleanupInvalidatedResults() const; + + /** Print list of currently cached results */ + void DebugPrintCachedResults() const; + }; + + /** Templated class which stores one entry for the CachedResult + * class. It stores the result (of type T), together with its + * dependencies (vector of TaggedObjects and vector of Numbers). + * It also stores a priority. + */ + template <class T> + class DependentResult : public Observer + { + public: + +#ifdef IP_DEBUG_CACHE + static const Index dbg_verbosity; +#endif + + /** @name Constructor, Destructors */ + //@{ + /** Constructor, given all information about the result. */ + DependentResult(const T& result, const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents); + + /** Destructor. */ + ~DependentResult(); + //@} + + /** @name Accessor method. */ + //@{ + /** This returns true, if the DependentResult is no longer valid. */ + bool IsStale() const; + + /** Invalidates the cached result. */ + void Invalidate(); + + /** Returns the cached result. */ + const T& GetResult() const; + //@} + + /** This method returns true if the dependencies provided to this + * function are identical to the ones stored with the + * DependentResult. + */ + bool DependentsIdentical(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const; + + /** Print information about this DependentResults. */ + void DebugPrint() const; + + protected: + /** This method is overloading the pure virtual method from the + * Observer base class. This method is called when a Subject + * registered for this Observer sends a notification. In this + * particular case, if this method is called with + * notify_type==NT_Changed or NT_BeingDeleted, then this results + * is marked as stale. + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DependentResult(); + + /** Copy Constructor */ + DependentResult(const DependentResult&); + + /** Overloaded Equals Operator */ + void operator=(const DependentResult&); + //@} + + /** Flag indicating, if the cached result is still valid. A + result becomes invalid, if the RecieveNotification method is + called with NT_Changed */ + bool stale_; + /** The value of the dependent results */ + const T result_; + /** Dependencies in form of TaggedObjects */ + std::vector<TaggedObject::Tag> dependent_tags_; + /** Dependencies in form a Numbers */ + std::vector<Number> scalar_dependents_; + }; + +#ifdef IP_DEBUG_CACHE + template <class T> + const Index CachedResults<T>::dbg_verbosity = 0; + + template <class T> + const Index DependentResult<T>::dbg_verbosity = 0; +#endif + + template <class T> + DependentResult<T>::DependentResult( + const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + : + stale_(false), + result_(result), + dependent_tags_(dependents.size()), + scalar_dependents_(scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DependentResult()", dbg_verbosity); +#endif + + for (Index i=0; i<(Index)dependents.size(); i++) { + if (dependents[i]) { + // Call the RequestAttach method of the Observer base class. + // This will add this dependent result in the Observer list + // for the Subject dependents[i]. As a consequence, the + // RecieveNotification method of this DependentResult will be + // called with notify_type=NT_Changed, whenever the + // TaggedResult dependents[i] is changed (i.e. its HasChanged + // method is called). + RequestAttach(NT_Changed, dependents[i]); + dependent_tags_[i] = dependents[i]->GetTag(); + } + else { + dependent_tags_[i] = 0; + } + } + } + + template <class T> + DependentResult<T>::~DependentResult() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::~DependentResult()", dbg_verbosity); + //DBG_ASSERT(stale_ == true); +#endif + // Nothing to be done here, destructor + // of T should sufficiently remove + // any memory, etc. + } + + template <class T> + bool DependentResult<T>::IsStale() const + { + return stale_; + } + + template <class T> + void DependentResult<T>::Invalidate() + { + stale_ = true; + } + + template <class T> + void DependentResult<T>::RecieveNotification(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::RecieveNotification", dbg_verbosity); +#endif + + if (notify_type == NT_Changed || notify_type==NT_BeingDestroyed) { + stale_ = true; + // technically, I could unregister the notifications here, but they + // aren't really hurting anything + } + } + + template <class T> + bool DependentResult<T>::DependentsIdentical(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DependentsIdentical", dbg_verbosity); + DBG_ASSERT(stale_ == false); + DBG_ASSERT(dependents.size() == dependent_tags_.size()); +#endif + + bool retVal = true; + + if (dependents.size() != dependent_tags_.size() + || scalar_dependents.size() != scalar_dependents_.size()) { + retVal = false; + } + else { + for (Index i=0; i<(Index)dependents.size(); i++) { + if ( (dependents[i] && dependents[i]->GetTag() != dependent_tags_[i]) + || (!dependents[i] && dependent_tags_[i] != 0) ) { + retVal = false; + break; + } + } + if (retVal) { + for (Index i=0; i<(Index)scalar_dependents.size(); i++) { + if (scalar_dependents[i] != scalar_dependents_[i]) { + retVal = false; + break; + } + } + } + } + + return retVal; + } + + template <class T> + const T& DependentResult<T>::GetResult() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::GetResult()", dbg_verbosity); + DBG_ASSERT(stale_ == false); +#endif + + return result_; + } + + template <class T> + void DependentResult<T>::DebugPrint() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("DependentResult<T>::DebugPrint", dbg_verbosity); +#endif + + } + + template <class T> + CachedResults<T>::CachedResults(Int max_cache_size) + : + max_cache_size_(max_cache_size), + cached_results_(NULL) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::CachedResults", dbg_verbosity); +#endif + + } + + template <class T> + CachedResults<T>::~CachedResults() + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::!CachedResults()", dbg_verbosity); +#endif + + if (cached_results_) { + for (typename std::list< DependentResult<T>* >::iterator iter = cached_results_-> + begin(); + iter != cached_results_->end(); + iter++) { + delete *iter; + } + delete cached_results_; + } + /* + while (!cached_results_.empty()) { + DependentResult<T>* result = cached_results_.back(); + cached_results_.pop_back(); + delete result; + } + */ + } + + template <class T> + void CachedResults<T>::AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult", dbg_verbosity); +#endif + + CleanupInvalidatedResults(); + + // insert the new one here + DependentResult<T>* newResult = new DependentResult<T>(result, dependents, scalar_dependents); + if (!cached_results_) { + cached_results_ = new std::list<DependentResult<T>*>; + } + cached_results_->push_front(newResult); + + // keep the list small enough + if (max_cache_size_ >= 0) { // if negative, allow infinite cache + // non-negative - limit size of list to max_cache_size + DBG_ASSERT((Int)cached_results_->size()<=max_cache_size_+1); + if ((Int)cached_results_->size() > max_cache_size_) { + delete cached_results_->back(); + cached_results_->pop_back(); + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + } + + template <class T> + void CachedResults<T>::AddCachedResult(const T& result, + const std::vector<const TaggedObject*>& dependents) + { + std::vector<Number> scalar_dependents; + AddCachedResult(result, dependents, scalar_dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult(T& retResult, const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult", dbg_verbosity); +#endif + + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + retResult = (*iter)->GetResult(); + retValue = true; + break; + } + } + +#ifdef IP_DEBUG_CACHE + DBG_EXEC(2, DebugPrintCachedResults()); +#endif + + return retValue; + } + + template <class T> + bool CachedResults<T>::GetCachedResult( + T& retResult, const std::vector<const TaggedObject*>& dependents) const + { + std::vector<Number> scalar_dependents; + return GetCachedResult(retResult, dependents, scalar_dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult1Dep(const T& result, + const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult1Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(1); + dependents[0] = dependent1; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult1Dep(T& retResult, const TaggedObject* dependent1) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult1Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(1); + dependents[0] = dependent1; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult2Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult2Dep(T& retResult, const TaggedObject* dependent1, const TaggedObject* dependent2) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(2); + dependents[0] = dependent1; + dependents[1] = dependent2; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + void CachedResults<T>::AddCachedResult3Dep(const T& result, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::AddCachedResult2dDep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + AddCachedResult(result, dependents); + } + + template <class T> + bool CachedResults<T>::GetCachedResult3Dep(T& retResult, const TaggedObject* dependent1, + const TaggedObject* dependent2, + const TaggedObject* dependent3) + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::GetCachedResult2Dep", dbg_verbosity); +#endif + + std::vector<const TaggedObject*> dependents(3); + dependents[0] = dependent1; + dependents[1] = dependent2; + dependents[2] = dependent3; + + return GetCachedResult(retResult, dependents); + } + + template <class T> + bool CachedResults<T>::InvalidateResult(const std::vector<const TaggedObject*>& dependents, + const std::vector<Number>& scalar_dependents) + { + if (!cached_results_) + return false; + + CleanupInvalidatedResults(); + + bool retValue = false; + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + if ((*iter)->DependentsIdentical(dependents, scalar_dependents)) { + (*iter)->Invalidate(); + retValue = true; + break; + } + } + + return retValue; + } + + template <class T> + void CachedResults<T>::Clear() + { + if (!cached_results_) + return; + + typename std::list< DependentResult<T>* >::const_iterator iter; + for (iter = cached_results_->begin(); iter != cached_results_->end(); + iter++) { + (*iter)->Invalidate(); + } + + CleanupInvalidatedResults(); + } + + template <class T> + void CachedResults<T>::Clear(Int max_cache_size) + { + Clear(); + max_cache_size_ = max_cache_size; + } + + template <class T> + void CachedResults<T>::CleanupInvalidatedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::CleanupInvalidatedResults", dbg_verbosity); +#endif + + if (!cached_results_) + return; + + typename std::list< DependentResult<T>* >::iterator iter; + iter = cached_results_->begin(); + while (iter != cached_results_->end()) { + if ((*iter)->IsStale()) { + typename std::list< DependentResult<T>* >::iterator + iter_to_remove = iter; + iter++; + DependentResult<T>* result_to_delete = (*iter_to_remove); + cached_results_->erase(iter_to_remove); + delete result_to_delete; + } + else { + iter++; + } + } + } + + template <class T> + void CachedResults<T>::DebugPrintCachedResults() const + { +#ifdef IP_DEBUG_CACHE + DBG_START_METH("CachedResults<T>::DebugPrintCachedResults", dbg_verbosity); + if (DBG_VERBOSITY()>=2 ) { + if (!cached_results_) { + DBG_PRINT((2,"Currentlt no cached results:\n")); + } + else { + typename std::list< DependentResult<T>* >::const_iterator iter; + DBG_PRINT((2,"Current set of cached results:\n")); + for (iter = cached_results_->begin(); iter != cached_results_->end(); iter++) { + DBG_PRINT((2," DependentResult:0x%x\n", (*iter))); + } + } + } +#endif + + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpCompoundMatrix.hpp b/thirdparty/linux/include/coin1/IpCompoundMatrix.hpp new file mode 100644 index 0000000..03e2e2a --- /dev/null +++ b/thirdparty/linux/include/coin1/IpCompoundMatrix.hpp @@ -0,0 +1,340 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDMATRIX_HPP__ +#define __IPCOMPOUNDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundMatrixSpace; + + /** Class for Matrices consisting of other matrices. This matrix is + * a matrix that consists of zero, one or more Matrices's which are + * arranged like this: \f$ M_{\rm compound} = + * \left(\begin{array}{cccc}M_{00} & M_{01} & \ldots & M_{0,{\rm + * ncomp\_cols}-1} \\ \dots &&&\dots \\ M_{{\rm ncomp\_rows}-1,0} & + * M_{{\rm ncomp\_rows}-1,1} & \dots & M_{{\rm ncomp\_rows}-1,{\rm + * ncomp\_cols}-1}\end{array}\right)\f$. The individual components + * can be associated to different MatrixSpaces. The individual + * components can also be const and non-const Matrices. If a + * component is not set (i.e., it's pointer is NULL), then this + * components is treated like a zero-matrix of appropriate + * dimensions. + */ + class CompoundMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. The owner_space has to + * be defined, so that at each block row and column contain at + * least one non-NULL component. The individual components can + * be set afterwards with the SeteComp and SetCompNonConst + * methods. + */ + CompoundMatrix(const CompoundMatrixSpace* owner_space); + + /** Destructor */ + virtual ~CompoundMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Method to set a non-const Matrix entry */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method to create a new matrix from the space for this block */ + void CreateBlockFromSpace(Index irow, Index jcol); + + /** Method for retrieving one block from the compound matrix as a + * const Matrix. + */ + SmartPtr<const Matrix> GetComp(Index irow, Index jcol) const + { + return ConstComp(irow, jcol); + } + + /** Method for retrieving one block from the compound matrix as a + * non-const Matrix. Note that calling this method with mark the + * CompoundMatrix as changed. Therefore, only use this method if + * you are intending to change the Matrix that you receive. */ + SmartPtr<Matrix> GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow, jcol); + } + + /** Number of block rows of this compound matrix. */ + inline Index NComps_Rows() const; + /** Number of block colmuns of this compound matrix. */ + inline Index NComps_Cols() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundMatrix(); + + /** Copy Constructor */ + CompoundMatrix(const CompoundMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundMatrix&); + //@} + + /** Matrix of matrix's containing the components */ + std::vector<std::vector<SmartPtr<Matrix> > > comps_; + + /** Matrix of const matrix's containing the components */ + std::vector<std::vector<SmartPtr<const Matrix> > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundMatrixSpace instead + * of MatrixSpace */ + const CompoundMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** Method to check whether or not the matrices are valid */ + bool MatricesValid() const; + + inline const Matrix* ConstComp(Index irow, Index jcol) const; + + inline Matrix* Comp(Index irow, Index jcol); + }; + + /** This is the matrix space for CompoundMatrix. Before a CompoundMatrix + * can be created, at least one MatrixSpace has to be set per block + * row and column. Individual component MatrixSpace's can be set + * with the SetComp method. + */ + class CompoundMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + CompoundMatrixSpace(Index ncomps_rows, + Index ncomps_cols, + Index total_nRows, + Index total_nCols); + + /** Destructor */ + ~CompoundMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the number nrows of rows in row-block number irow. */ + void SetBlockRows(Index irow, Index nrows); + + /** Set the number ncols of columns in column-block number jcol. */ + void SetBlockCols(Index jcol, Index ncols); + + /** Get the number nrows of rows in row-block number irow. */ + Index GetBlockRows(Index irow) const; + + /** Set the number ncols of columns in column-block number jcol. */ + Index GetBlockCols(Index jcol) const; + + /** Set the component MatrixSpace. If auto_allocate is true, then + * a new CompoundMatrix created later with MakeNew will have this + * component automatically created with the Matrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr<const MatrixSpace> GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow<NComps_Rows()); + DBG_ASSERT(jcol<NComps_Cols()); + return comp_spaces_[irow][jcol]; + } + + /** @name Accessor methods */ + //@{ + /** Number of block rows */ + Index NComps_Rows() const + { + return ncomps_rows_; + } + /** Number of block columns */ + Index NComps_Cols() const + { + return ncomps_cols_; + } + + /** True if the blocks lie on the diagonal - can make some operations faster */ + bool Diagonal() const + { + return diagonal_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + CompoundMatrix* MakeNewCompoundMatrix() const; + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewCompoundMatrix(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundMatrixSpace(); + + /** Copy Constructor */ + CompoundMatrixSpace(const CompoundMatrixSpace&); + + /** Overloaded Equals Operator */ + CompoundMatrixSpace& operator=(const CompoundMatrixSpace&); + //@} + + /** Number of block rows */ + Index ncomps_rows_; + + /** Number of block columns */ + Index ncomps_cols_; + + /** Store whether or not the dimensions are valid */ + mutable bool dimensions_set_; + + /** 2-dim std::vector of matrix spaces for the components */ + std::vector<std::vector<SmartPtr<const MatrixSpace> > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector<std::vector< bool > > allocate_block_; + + /** Vector of the number of rows in each comp column */ + std::vector<Index> block_rows_; + + /** Vector of the number of cols in each comp row */ + std::vector<Index> block_cols_; + + /** true if the CompoundMatrixSpace only has Matrix spaces along the diagonal. + * this means that the CompoundMatrix will only have matrices along the + * diagonal and it could make some operations more efficient + */ + bool diagonal_; + + /** Auxilliary function for debugging to set if all block + * dimensions have been set. */ + bool DimensionsSet() const; + }; + + /* inline methods */ + inline + Index CompoundMatrix::NComps_Rows() const + { + return owner_space_->NComps_Rows(); + } + + inline + Index CompoundMatrix::NComps_Cols() const + { + return owner_space_->NComps_Cols(); + } + + inline + const Matrix* CompoundMatrix::ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + inline + Matrix* CompoundMatrix::Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Rows()); + DBG_ASSERT(jcol < NComps_Cols()); + return GetRawPtr(comps_[irow][jcol]); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpCompoundSymMatrix.hpp b/thirdparty/linux/include/coin1/IpCompoundSymMatrix.hpp new file mode 100644 index 0000000..4ca18fe --- /dev/null +++ b/thirdparty/linux/include/coin1/IpCompoundSymMatrix.hpp @@ -0,0 +1,283 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDSYMMATRIX_HPP__ +#define __IPCOMPOUNDSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundSymMatrixSpace; + + /** Class for symmetric matrices consisting of other matrices. + * Here, the lower left block of the matrix is stored. + */ + class CompoundSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking only the number for block components into the + * row and column direction. The owner_space has to be defined, so + * that at each block row and column contain at least one non-NULL + * component. + */ + CompoundSymMatrix(const CompoundSymMatrixSpace* owner_space); + + /** Destructor */ + ~CompoundSymMatrix(); + //@} + + /** Method for setting an individual component at position (irow, + * icol) in the compound matrix. The counting of indices starts + * at 0. Since this only the lower left components are stored, we need + * to have jcol<=irow, and if irow==jcol, the matrix must be a SymMatrix */ + void SetComp(Index irow, Index jcol, const Matrix& matrix); + + /** Non const version of the same method */ + void SetCompNonConst(Index irow, Index jcol, Matrix& matrix); + + /** Method for retrieving one block from the compound matrix. + * Since this only the lower left components are stored, we need + * to have jcol<=irow */ + SmartPtr<const Matrix> GetComp(Index irow, Index jcol) const + { + return ConstComp(irow,jcol); + } + + /** Non const version of GetComp. You should only use this method + * if you are intending to change the matrix you receive, since + * this CompoundSymMatrix will be marked as changed. */ + SmartPtr<Matrix> GetCompNonConst(Index irow, Index jcol) + { + ObjectChanged(); + return Comp(irow,jcol); + } + + /** Method for creating a new matrix of this specific type. */ + SmartPtr<CompoundSymMatrix> MakeNewCompoundSymMatrix() const; + + // The following don't seem to be necessary + /* Number of block rows of this compound matrix. */ + // Index NComps_NRows() const { return NComps_Dim(); } + + /* Number of block colmuns of this compound matrix. */ + // Index NComps_NCols() const { return NComps_Dim(); } + + /** Number of block rows and columns */ + Index NComps_Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + CompoundSymMatrix(); + + /** Copy Constructor */ + CompoundSymMatrix(const CompoundSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundSymMatrix&); + //@} + + /** Vector of vectors containing the components */ + std::vector<std::vector<SmartPtr<Matrix> > > comps_; + + /** Vector of vectors containing the const components */ + std::vector<std::vector<SmartPtr<const Matrix> > > const_comps_; + + /** Copy of the owner_space ptr as a CompoundSymMatrixSpace */ + const CompoundSymMatrixSpace* owner_space_; + + /** boolean indicating if the compound matrix is in a "valid" state */ + mutable bool matrices_valid_; + + /** method to check wether or not the matrices are valid */ + bool MatricesValid() const; + + /** Internal method to return a const pointer to one of the comps */ + const Matrix* ConstComp(Index irow, Index jcol) const + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + else if (IsValid(const_comps_[irow][jcol])) { + return GetRawPtr(const_comps_[irow][jcol]); + } + + return NULL; + } + + /** Internal method to return a non-const pointer to one of the comps */ + Matrix* Comp(Index irow, Index jcol) + { + DBG_ASSERT(irow < NComps_Dim()); + DBG_ASSERT(jcol <= irow); + // We shouldn't be asking for a non-const if this entry holds a + // const one... + DBG_ASSERT(IsNull(const_comps_[irow][jcol])); + if (IsValid(comps_[irow][jcol])) { + return GetRawPtr(comps_[irow][jcol]); + } + + return NULL; + } + }; + + /** This is the matrix space for CompoundSymMatrix. Before a + * CompoundSymMatrix can be created, at least one SymMatrixSpace has + * to be set per block row and column. Individual component + * SymMatrixSpace's can be set with the SetComp method. + */ + class CompoundSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of blocks (same for rows and + * columns), as well as the total dimension of the matrix. + */ + CompoundSymMatrixSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundSymMatrixSpace() + {} + //@} + + /** @name Methods for setting information about the components. */ + //@{ + /** Set the dimension dim for block row (or column) irow_jcol */ + void SetBlockDim(Index irow_jcol, Index dim); + + /** Get the dimension dim for block row (or column) irow_jcol */ + Index GetBlockDim(Index irow_jcol) const; + + /** Set the component SymMatrixSpace. If auto_allocate is true, then + * a new CompoundSymMatrix created later with MakeNew will have this + * component automatically created with the SymMatrix's MakeNew. + * Otherwise, the corresponding component will be NULL and has to + * be set with the SetComp methods of the CompoundSymMatrix. + */ + void SetCompSpace(Index irow, Index jcol, + const MatrixSpace& mat_space, + bool auto_allocate = false); + //@} + + /** Obtain the component MatrixSpace in block row irow and block + * column jcol. + */ + SmartPtr<const MatrixSpace> GetCompSpace(Index irow, Index jcol) const + { + DBG_ASSERT(irow<ncomp_spaces_); + DBG_ASSERT(jcol<=irow); + return comp_spaces_[irow][jcol]; + } + + /** @name Accessor methods */ + //@{ + Index NComps_Dim() const + { + return ncomp_spaces_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + CompoundSymMatrix* MakeNewCompoundSymMatrix() const; + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewCompoundSymMatrix(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundSymMatrixSpace(); + + /** Copy Constructor */ + CompoundSymMatrixSpace(const CompoundSymMatrix&); + + /** Overloaded Equals Operator */ + CompoundSymMatrixSpace& operator=(const CompoundSymMatrixSpace&); + //@} + + /** Number of components per row and column */ + Index ncomp_spaces_; + + /** Vector of the number of rows in each comp column, + * Since this is symmetric, this is also the number + * of columns in each row, hence, it is the dimension + * each of the diagonals */ + std::vector<Index> block_dim_; + + /** 2-dim std::vector of matrix spaces for the components. Only + * the lower right part is stored. */ + std::vector<std::vector<SmartPtr<const MatrixSpace> > > comp_spaces_; + + /** 2-dim std::vector of booleans deciding whether to + * allocate a new matrix for the blocks automagically */ + std::vector<std::vector< bool > > allocate_block_; + + /** boolean indicating if the compound matrix space is in a "valid" state */ + mutable bool dimensions_set_; + + /** Method to check whether or not the spaces are valid */ + bool DimensionsSet() const; + }; + + inline + SmartPtr<CompoundSymMatrix> CompoundSymMatrix::MakeNewCompoundSymMatrix() const + { + return owner_space_->MakeNewCompoundSymMatrix(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpCompoundVector.hpp b/thirdparty/linux/include/coin1/IpCompoundVector.hpp new file mode 100644 index 0000000..a4c52ab --- /dev/null +++ b/thirdparty/linux/include/coin1/IpCompoundVector.hpp @@ -0,0 +1,339 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpCompoundVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCOMPOUNDVECTOR_HPP__ +#define __IPCOMPOUNDVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include <vector> + +namespace Ipopt +{ + + /* forward declarations */ + class CompoundVectorSpace; + + /** Class of Vectors consisting of other vectors. This vector is a + * vector that consists of zero, one or more Vector's which are + * stacked on each others: \f$ x_{\rm compound} = + * \left(\begin{array}{c}x_0\\\dots\\x_{{\rm + * ncomps} - 1}\end{array}\right)\f$. The individual components can be + * associated to different VectorSpaces. The individual components + * can also be const and non-const Vectors. + */ + class CompoundVector : public Vector + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor, given the corresponding CompoundVectorSpace. + * Before this constructor can be called, all components of the + * CompoundVectorSpace have to be set, so that the constructors + * for the individual components can be called. If the flag + * create_new is true, then the individual components of the new + * CompoundVector are initialized with the MakeNew methods of + * each VectorSpace (and are non-const). Otherwise, the + * individual components can later be set using the SetComp and + * SetCompNonConst method. + */ + CompoundVector(const CompoundVectorSpace* owner_space, bool create_new); + + /** Default destructor */ + virtual ~CompoundVector(); + //@} + + /** Method for setting the pointer for a component that is a const + * Vector + */ + void SetComp(Index icomp, const Vector& vec); + + /** Method for setting the pointer for a component that is a + * non-const Vector + */ + void SetCompNonConst(Index icomp, Vector& vec); + + /** Number of components of this compound vector */ + inline Index NComps() const; + + /** Check if a particular component is const or not */ + bool IsCompConst(Index i) const + { + DBG_ASSERT(i > 0 && i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(const_comps_[i])) { + return true; + } + return false; + } + + /** Check if a particular component is null or not */ + bool IsCompNull(Index i) const + { + DBG_ASSERT(i >= 0 && i < NComps()); + if (IsValid(comps_[i]) || IsValid(const_comps_[i])) { + return false; + } + return true; + } + + /** Return a particular component (const version) */ + SmartPtr<const Vector> GetComp(Index i) const + { + return ConstComp(i); + } + + /** Return a particular component (non-const version). Note that + * calling this method with mark the CompoundVector as changed. + * Therefore, only use this method if you are intending to change + * the Vector that you receive. + */ + SmartPtr<Vector> GetCompNonConst(Index i) + { + ObjectChanged(); + return Comp(i); + } + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** Element-wise reciprocal */ + virtual void ElementWiseReciprocalImpl(); + + /** Element-wise absolute values */ + virtual void ElementWiseAbsImpl(); + + /** Element-wise square-root */ + virtual void ElementWiseSqrtImpl(); + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + CompoundVector(); + + /** Copy Constructor */ + CompoundVector(const CompoundVector&); + + /** Overloaded Equals Operator */ + void operator=(const CompoundVector&); + //@} + + /** Components of the compound vector. The components + * are stored by SmartPtrs in a std::vector + */ + std::vector< SmartPtr<Vector> > comps_; + std::vector< SmartPtr<const Vector> > const_comps_; + + const CompoundVectorSpace* owner_space_; + + bool vectors_valid_; + + bool VectorsValid(); + + inline const Vector* ConstComp(Index i) const; + + inline Vector* Comp(Index i); + }; + + /** This vectors space is the vector space for CompoundVector. + * Before a CompoundVector can be created, all components of this + * CompoundVectorSpace have to be set. When calling the constructor, + * the number of component has to be specified. The individual + * VectorSpaces can be set with the SetComp method. + */ + class CompoundVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, has to be given the number of components and the + * total dimension of all components combined. */ + CompoundVectorSpace(Index ncomp_spaces, Index total_dim); + + /** Destructor */ + ~CompoundVectorSpace() + {} + //@} + + /** Method for setting the individual component VectorSpaces */ + virtual void SetCompSpace(Index icomp /** Number of the component to be set */ , + const VectorSpace& vec_space /** VectorSpace for component icomp */ + ); + + /** Method for obtaining an individual component VectorSpace */ + SmartPtr<const VectorSpace> GetCompSpace(Index icomp) const; + + /** Accessor method to obtain the number of components */ + Index NCompSpaces() const + { + return ncomp_spaces_; + } + + /** Method for creating a new vector of this specific type. */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return new CompoundVector(this, create_new); + } + + /** Overloaded MakeNew method for the VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewCompoundVector(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + CompoundVectorSpace(); + + /** Copy Constructor */ + CompoundVectorSpace(const CompoundVectorSpace&); + + /** Overloaded Equals Operator */ + CompoundVectorSpace& operator=(const CompoundVectorSpace&); + //@} + + /** Number of components */ + const Index ncomp_spaces_; + + /** std::vector of vector spaces for the components */ + std::vector< SmartPtr<const VectorSpace> > comp_spaces_; + }; + + /* inline methods */ + inline + Index CompoundVector::NComps() const + { + return owner_space_->NCompSpaces(); + } + + inline + const Vector* CompoundVector::ConstComp(Index i) const + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i]) || IsValid(const_comps_[i])); + if (IsValid(comps_[i])) { + return GetRawPtr(comps_[i]); + } + else if (IsValid(const_comps_[i])) { + return GetRawPtr(const_comps_[i]); + } + + DBG_ASSERT(false && "shouldn't be here"); + return NULL; + } + + inline + Vector* CompoundVector::Comp(Index i) + { + DBG_ASSERT(i < NComps()); + DBG_ASSERT(IsValid(comps_[i])); + return GetRawPtr(comps_[i]); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpConvCheck.hpp b/thirdparty/linux/include/coin1/IpConvCheck.hpp new file mode 100644 index 0000000..033fce4 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpConvCheck.hpp @@ -0,0 +1,87 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpConvCheck.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPCONVCHECK_HPP__ +#define __IPCONVCHECK_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for checking the algorithm + * termination criteria. + */ + class ConvergenceCheck : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + ConvergenceCheck() + {} + + /** Default destructor */ + virtual ~ConvergenceCheck() + {} + //@} + + /** Convergence return enum */ + enum ConvergenceStatus { + CONTINUE, + CONVERGED, + CONVERGED_TO_ACCEPTABLE_POINT, + MAXITER_EXCEEDED, + CPUTIME_EXCEEDED, + DIVERGING, + USER_STOP, + FAILED + }; + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for performing the convergence test. If + * call_intermediate_callback is true, the user callback method + * in the NLP should be called in order to see if the user + * requests an early termination. */ + virtual ConvergenceStatus + CheckConvergence(bool call_intermediate_callback = true) = 0; + + /** Method for testing if the current iterate is considered to + * satisfy the "accptable level" of accuracy. The idea is that + * if the desired convergence tolerance cannot be achieved, the + * algorithm might stop after a number of acceptable points have + * been encountered. */ + virtual bool CurrentIsAcceptable()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // ConvergenceCheck(); + + /** Copy Constructor */ + ConvergenceCheck(const ConvergenceCheck&); + + /** Overloaded Equals Operator */ + void operator=(const ConvergenceCheck&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpDebug.hpp b/thirdparty/linux/include/coin1/IpDebug.hpp new file mode 100644 index 0000000..b8aae13 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpDebug.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDebug.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDEBUG_HPP__ +#define __IPDEBUG_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" + +#ifdef COIN_IPOPT_CHECKLEVEL +#ifdef HAVE_CASSERT +# include <cassert> +#else +# ifdef HAVE_ASSERT_H +# include <assert.h> +# else +# error "don't have header file for assert" +# endif +#endif +#else +#define COIN_IPOPT_CHECKLEVEL 0 +#endif + +#if COIN_IPOPT_CHECKLEVEL > 0 +# ifdef NDEBUG +# undef NDEBUG +# endif +# define DBG_ASSERT(test) assert(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + ASSERT_EXCEPTION( (__condition), __except_type, __msg); +# define DBG_DO(__cmd) __cmd +#else +# define DBG_ASSERT(test) +# define DBG_ASSERT_EXCEPTION(__condition, __except_type, __msg) +# define DBG_DO(__cmd) +#endif + +#ifndef COIN_IPOPT_VERBOSITY +#define COIN_IPOPT_VERBOSITY 0 +#endif + +#if COIN_IPOPT_VERBOSITY < 1 +# define DBG_START_FUN(__func_name, __verbose_level) +# define DBG_START_METH(__func_name, __verbose_level) +# define DBG_PRINT(__printf_args) +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +# define DBG_EXEC(__verbosity, __cmd) +# define DBG_VERBOSITY() 0 +#else +#include <string> + +namespace Ipopt +{ + // forward definition + class Journalist; + + /** Class that lives throughout the execution of a method or + * function for which debug output is to be generated. The output + * is sent to the unique debug journalist that is set with + * SetJournalist at the beginning of program execution. */ + class DebugJournalistWrapper + { + public: + /** @name Constructors/Destructors. */ + //@{ + DebugJournalistWrapper(std::string func_name, Index verbose_level); + DebugJournalistWrapper(std::string func_name, Index verbose_level, + const void* const method_owner); + ~DebugJournalistWrapper(); + //@} + + /** @name accessor methods */ + //@{ + Index Verbosity() + { + return verbose_level_; + } + const Journalist* Jnlst() + { + return jrnl_; + } + Index IndentationLevel() + { + return indentation_level_; + } + //@} + + /** Printing */ + void DebugPrintf(Index verbosity, const char* pformat, ...); + + /* Method for initialization of the static GLOBAL journalist, + * through with all debug printout is to be written. This needs + * to be set before any debug printout can be done. */ + static void SetJournalist(Journalist* jrnl); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + DebugJournalistWrapper(); + + /** copy contructor */ + DebugJournalistWrapper(const DebugJournalistWrapper&); + + /** Overloaded Equals Operator */ + DebugJournalistWrapper& operator=(const DebugJournalistWrapper&); + //@} + + static Index indentation_level_; + std::string func_name_; + Index verbose_level_; + const void* method_owner_; + + static Journalist* jrnl_; + }; +} + +# define DBG_START_FUN(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level)); \ + +# define DBG_START_METH(__func_name, __verbose_level) \ + DebugJournalistWrapper dbg_jrnl((__func_name), (__verbose_level), this); + +# define DBG_PRINT(__args) \ + dbg_jrnl.DebugPrintf __args; + +# define DBG_EXEC(__verbose_level, __cmd) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + (__cmd); \ + } + +# define DBG_VERBOSITY() \ + dbg_jrnl.Verbosity() + +#endif + + +#endif diff --git a/thirdparty/linux/include/coin1/IpDenseVector.hpp b/thirdparty/linux/include/coin1/IpDenseVector.hpp new file mode 100644 index 0000000..380a06c --- /dev/null +++ b/thirdparty/linux/include/coin1/IpDenseVector.hpp @@ -0,0 +1,550 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDenseVector.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDENSEVECTOR_HPP__ +#define __IPDENSEVECTOR_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include <map> + +namespace Ipopt +{ + + /* forward declarations */ + class DenseVectorSpace; + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(METADATA_ERROR); + //@} + + /** Dense Vector Implementation. This is the default Vector class + * in Ipopt. It stores vectors in contiguous Number arrays, unless + * the vector has the same value in all entires. In the latter + * case, we call the vector "homogeneous", and we store only the + * values that is repeated in all elements. If you want to obtain + * the values of vector, use the IsHomogeneous() method to find out + * what status the vector is in, and then use either Values() const + * or Scalar() const methods to get the values. To set the values + * of a homogeneous method, use the Set method. To set the values + * of a non-homogeneous vector, use the SetValues method, or use + * the non-const Values method to get an array that you can + * overwrite. In the latter case, storage is ensured. + */ + class DenseVector : public Vector + { + public: + + /**@name Constructors / Destructors */ + //@{ + /** Default Constructor + */ + DenseVector(const DenseVectorSpace* owner_space); + + /** Destructor + */ + virtual ~DenseVector(); + //@} + + /** @name Additional public methods not in Vector base class. */ + //@{ + /** Create a new DenseVector from same VectorSpace */ + SmartPtr<DenseVector> MakeNewDenseVector() const; + + /** Set elements in the vector to the Number array x. */ + void SetValues(const Number *x); + + /** Obtain pointer to the internal Number array with vector + * elements with the indention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed!. + */ + inline Number* Values(); + + /** Obtain pointer to the internal Number array with vector + * elements without the intention to change the vector data (USE + * WITH CARE!). This does not produce a copy, and lifetime is not + * guaranteed! IMPORTANT: If this method is currently + * homogeneous (i.e. IsHomogeneous returns true), then you cannot + * call this method. Instead, you need to use the Scalar() + * method. + */ + inline const Number* Values() const; + + /** The same as the const version of Values, but we ensure that we + * always return a valid array, even if IsHomogeneous returns + * true. */ + const Number* ExpandedValues() const; + + /** This is the same as Values, but we add it here so that + * ExpandedValues can also be used for the non-const case. */ + inline Number* ExpandedValues() + { + return Values(); + } + + /** Indicates if the vector is homogeneous (i.e., all entries have + * the value Scalar() */ + bool IsHomogeneous() const + { + return homogeneous_; + } + + /** Scalar value of all entries in a homogeneous vector */ + Number Scalar() const + { + DBG_ASSERT(homogeneous_); + return scalar_; + } + //@} + + /** @name Modifying subranges of the vector. */ + //@{ + /** Copy the data in x into the subrange of this vector starting + * at position Pos in this vector. Position count starts at 0. + */ + void CopyToPos(Index Pos, const Vector& x); + /** Copy a subrange of x, starting at Pos, into the full data of + * this vector. Position count starts at 0. + */ + void CopyFromPos(Index Pos, const Vector& x); + //@} + + protected: + /** @name Overloaded methods from Vector base class */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number value); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$.*/ + virtual void ElementWiseDivideImpl(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$.*/ + virtual void ElementWiseMultiplyImpl(const Vector& x); + + /** Set entry to max of itself and the corresponding element in x */ + virtual void ElementWiseMaxImpl(const Vector& x); + + /** Set entry to min of itself and the corresponding element in x */ + virtual void ElementWiseMinImpl(const Vector& x); + + /** reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl(); + + /** take abs of the elements of the vector */ + virtual void ElementWiseAbsImpl(); + + /** take square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl(); + + /** Changes each entry in the vector to its sgn value */ + virtual void ElementWiseSgnImpl(); + + /** Add scalar to every component of the vector.*/ + virtual void AddScalarImpl(Number scalar); + + /** Max value in the vector */ + virtual Number MaxImpl() const; + + /** Min value in the vector */ + virtual Number MinImpl() const; + + /** Computes the sum of the lements of vector */ + virtual Number SumImpl() const; + + /** Computes the sum of the logs of the elements of vector */ + virtual Number SumLogsImpl() const; + + /** @name Implemented specialized functions */ + //@{ + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. */ + Number FracToBoundImpl(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + void AddVectorQuotientImpl(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** @name Output methods */ + //@{ + /* Print the entire vector with padding */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1); + } + /* Print the entire vector with padding, and start counting with + an offset. */ + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + //@} + friend class ParVector; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DenseVector(); + + /** Copy Constructor */ + DenseVector(const DenseVector&); + + /** Overloaded Equals Operator */ + void operator=(const DenseVector&); + //@} + + /** Copy of the owner_space ptr as a DenseVectorSpace instead + * of a VectorSpace + */ + const DenseVectorSpace* owner_space_; + + /** Dense Number array of vector values. */ + Number* values_; + + /** Dense Number array pointer that is used for ExpandedValues */ + mutable Number* expanded_values_; + + /** Method of getting the internal values array, making sure that + * memory has been allocated */ + inline + Number* values_allocated(); + + /** Flag for Initialization. This flag is false, if the data has + not yet been initialized. */ + bool initialized_; + + /** Flag indicating whether the vector is currently homogeneous + * (that is, all elements have the same value). This flag is used + * to determine whether the elements of the vector are stored in + * values_ or in scalar_ */ + bool homogeneous_; + + /** Homogeneous value of all elements if the vector is currently + * homogenous */ + Number scalar_; + + /** Auxilliary method for setting explicitly all elements in + * values_ to the current scalar value. */ + void set_values_from_scalar(); + }; + + /** typedefs for the map variables that define meta data for the + * DenseVectorSpace + */ + typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType; + typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType; + typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType; + + /** This vectors space is the vector space for DenseVector. + */ + class DenseVectorSpace : public VectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor, requires dimension of all vector for this + * VectorSpace + */ + DenseVectorSpace(Index dim) + : + VectorSpace(dim) + {} + + /** Destructor */ + ~DenseVectorSpace() + {} + //@} + + /** Method for creating a new vector of this specific type. */ + inline + DenseVector* MakeNewDenseVector() const + { + return new DenseVector(this); + } + + /** Instantiation of the generate MakeNew method for the + * VectorSpace base class. + */ + virtual Vector* MakeNew() const + { + return MakeNewDenseVector(); + } + + /**@name Methods called by DenseVector for memory management. + * This could allow to have sophisticated memory management in the + * VectorSpace. + */ + //@{ + /** Allocate internal storage for the DenseVector */ + inline + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the DenseVector */ + inline + void FreeInternalStorage(Number* values) const; + //@} + + /**@name Methods for dealing with meta data on the vector + */ + //@{ + /** Check if string meta exists for tag */ + inline + bool HasStringMetaData(const std::string tag) const; + + /** Check if Integer meta exists for tag */ + inline + bool HasIntegerMetaData(const std::string tag) const; + + /** Check if Numeric meta exists for tag */ + inline + bool HasNumericMetaData(const std::string tag) const; + + /** Get meta data of type std::string by tag */ + inline + const std::vector<std::string>& GetStringMetaData(const std::string& tag) const; + + /** Get meta data of type Index by tag */ + inline + const std::vector<Index>& GetIntegerMetaData(const std::string& tag) const; + + /** Get meta data of type Number by tag */ + inline + const std::vector<Number>& GetNumericMetaData(const std::string& tag) const; + + /** Set meta data of type std::string by tag */ + inline + void SetStringMetaData(std::string tag, std::vector<std::string> meta_data); + + /** Set meta data of type Index by tag */ + inline + void SetIntegerMetaData(std::string tag, std::vector<Index> meta_data); + + /** Set meta data of type Number by tag */ + inline + void SetNumericMetaData(std::string tag, std::vector<Number> meta_data); + + /** Get map of meta data of type Number */ + inline + const StringMetaDataMapType& GetStringMetaData() const; + + /** Get map of meta data of type Number */ + inline + const IntegerMetaDataMapType& GetIntegerMetaData() const; + + /** Get map of meta data of type Number */ + inline + const NumericMetaDataMapType& GetNumericMetaData() const; + //@} + + private: + // variables to store vector meta data + StringMetaDataMapType string_meta_data_; + IntegerMetaDataMapType integer_meta_data_; + NumericMetaDataMapType numeric_meta_data_; + + }; + + // inline functions + inline Number* DenseVector::Values() + { + // Here we assume that every time someone requests this direct raw + // pointer, the data is going to change and the Tag for this + // vector has to be updated. + + if (initialized_ && homogeneous_) { + // If currently the vector is a homogeneous vector, set all elements + // explicitly to this value + set_values_from_scalar(); + } + ObjectChanged(); + initialized_= true; + homogeneous_ = false; + return values_allocated(); + } + + inline const Number* DenseVector::Values() const + { + DBG_ASSERT(initialized_ && (Dim()==0 || values_)); + return values_; + } + + inline Number* DenseVector::values_allocated() + { + if (values_==NULL) { + values_ = owner_space_->AllocateInternalStorage(); + } + return values_; + } + + inline + Number* DenseVectorSpace::AllocateInternalStorage() const + { + if (Dim()>0) { + return new Number[Dim()]; + } + else { + return NULL; + } + } + + inline + void DenseVectorSpace::FreeInternalStorage(Number* values) const + { + delete [] values; + } + + inline + SmartPtr<DenseVector> DenseVector::MakeNewDenseVector() const + { + return owner_space_->MakeNewDenseVector(); + } + + inline + bool DenseVectorSpace::HasStringMetaData(const std::string tag) const + { + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + + if (iter != string_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasIntegerMetaData(const std::string tag) const + { + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + + if (iter != integer_meta_data_.end()) { + return true; + } + + return false; + } + + inline + bool DenseVectorSpace::HasNumericMetaData(const std::string tag) const + { + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + + if (iter != numeric_meta_data_.end()) { + return true; + } + + return false; + } + + inline + const std::vector<std::string>& DenseVectorSpace::GetStringMetaData(const std::string& tag) const + { + DBG_ASSERT(HasStringMetaData(tag)); + StringMetaDataMapType::const_iterator iter; + iter = string_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector<Index>& DenseVectorSpace::GetIntegerMetaData(const std::string& tag) const + { + DBG_ASSERT(HasIntegerMetaData(tag)); + IntegerMetaDataMapType::const_iterator iter; + iter = integer_meta_data_.find(tag); + return iter->second; + } + + inline + const std::vector<Number>& DenseVectorSpace::GetNumericMetaData(const std::string& tag) const + { + DBG_ASSERT(HasNumericMetaData(tag)); + NumericMetaDataMapType::const_iterator iter; + iter = numeric_meta_data_.find(tag); + return iter->second; + } + + inline + void DenseVectorSpace::SetStringMetaData(std::string tag, std::vector<std::string> meta_data) + { + string_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetIntegerMetaData(std::string tag, std::vector<Index> meta_data) + { + integer_meta_data_[tag] = meta_data; + } + + inline + void DenseVectorSpace::SetNumericMetaData(std::string tag, std::vector<Number> meta_data) + { + numeric_meta_data_[tag] = meta_data; + } + + inline + const StringMetaDataMapType& DenseVectorSpace::GetStringMetaData() const + { + return string_meta_data_; + } + + inline + const IntegerMetaDataMapType& DenseVectorSpace::GetIntegerMetaData() const + { + return integer_meta_data_; + } + + inline + const NumericMetaDataMapType& DenseVectorSpace::GetNumericMetaData() const + { + return numeric_meta_data_; + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpDiagMatrix.hpp b/thirdparty/linux/include/coin1/IpDiagMatrix.hpp new file mode 100644 index 0000000..d912e77 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpDiagMatrix.hpp @@ -0,0 +1,141 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpDiagMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPDIAGMATRIX_HPP__ +#define __IPDIAGMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for diagonal matrices. The diagonal is stored as a + * Vector. */ + class DiagMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, given the corresponding matrix space. */ + DiagMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~DiagMatrix(); + //@} + + /** Method for setting the diagonal elements (as a Vector). */ + void SetDiag(const Vector& diag) + { + diag_ = &diag; + } + + /** Method for setting the diagonal elements. */ + SmartPtr<const Vector> GetDiag() const + { + return diag_; + } + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrix(); + + /** Copy Constructor */ + DiagMatrix(const DiagMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrix&); + //@} + + /** Vector storing the diagonal elements */ + SmartPtr<const Vector> diag_; + }; + + /** This is the matrix space for DiagMatrix. */ + class DiagMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + DiagMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~DiagMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewDiagMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + DiagMatrix* MakeNewDiagMatrix() const + { + return new DiagMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + DiagMatrixSpace(); + + /** Copy Constructor */ + DiagMatrixSpace(const DiagMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const DiagMatrixSpace&); + //@} + + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpEqMultCalculator.hpp b/thirdparty/linux/include/coin1/IpEqMultCalculator.hpp new file mode 100644 index 0000000..7c3cb20 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpEqMultCalculator.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpEqMultCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-23 + +#ifndef __IPEQMULTCALCULATOR_HPP__ +#define __IPEQMULTCALCULATOR_HPP__ + +#include "IpUtils.hpp" +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Base Class for objects that compute estimates for the equality + * constraint multipliers y_c and y_d. For example, this is the + * base class for objects for computing least square multipliers or + * coordinate multipliers. */ + class EqMultiplierCalculator: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor. */ + EqMultiplierCalculator() + {} + /** Default destructor */ + virtual ~EqMultiplierCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** This method computes the estimates for y_c and y_d at the + * current point. If the estimates cannot be computed (e.g. some + * linear system is singular), the return value of this method is + * false. */ + virtual bool CalculateMultipliers(Vector& y_c, + Vector& y_d) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + EqMultiplierCalculator(const EqMultiplierCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const EqMultiplierCalculator&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpException.hpp b/thirdparty/linux/include/coin1/IpException.hpp new file mode 100644 index 0000000..e64226f --- /dev/null +++ b/thirdparty/linux/include/coin1/IpException.hpp @@ -0,0 +1,147 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpException.hpp 2023 2011-06-18 18:49:49Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXCEPTION_HPP__ +#define __IPEXCEPTION_HPP__ + +#include "IpUtils.hpp" +#include "IpJournalist.hpp" + +/* This file contains a base class for all exceptions + * and a set of macros to help with exceptions + */ + +namespace Ipopt +{ + + /** This is the base class for all exceptions. The easiest way to + * use this class is by means of the following macros: + * + * \verbatim + + DECLARE_STD_EXCEPTION(ExceptionType); + \endverbatim + * + * This macro defines a new class with the name ExceptionType, + * inherited from the base class IpoptException. After this, + * exceptions of this type can be thrown using + * + * \verbatim + + THROW_EXCEPTION(ExceptionType, Message); + \endverbatim + * + * where Message is a std::string with a message that gives an + * indication of what caused the exception. Exceptions can also be + * thrown using the macro + * + * \verbatim + + ASSERT_EXCEPTION(Condition, ExceptionType, Message); + \endverbatim + * + * where Conditions is an expression. If Condition evaluates to + * false, then the exception of the type ExceptionType is thrown + * with Message. + * + * When an exception is caught, the method ReportException can be + * used to write the information about the exception to the + * Journalist, using the level J_ERROR and the category J_MAIN. + * + */ + class IpoptException + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptException(std::string msg, std::string file_name, Index line_number, std::string type="IpoptException") + : + msg_(msg), + file_name_(file_name), + line_number_(line_number), + type_(type) + {} + + /** Copy Constructor */ + IpoptException(const IpoptException& copy) + : + msg_(copy.msg_), + file_name_(copy.file_name_), + line_number_(copy.line_number_), + type_(copy.type_) + {} + + /** Default destructor */ + virtual ~IpoptException() + {} + //@} + + /** Method to report the exception to a journalist */ + void ReportException(const Journalist& jnlst, + EJournalLevel level = J_ERROR) const + { + jnlst.Printf(level, J_MAIN, + "Exception of type: %s in file \"%s\" at line %d:\n Exception message: %s\n", + type_.c_str(), file_name_.c_str(), line_number_, msg_.c_str()); + } + + const std::string& Message() const + { + return msg_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptException(); + + /** Overloaded Equals Operator */ + void operator=(const IpoptException&); + //@} + + std::string msg_; + std::string file_name_; + Index line_number_; + std::string type_; + }; + +} // namespace Ipopt + +#define THROW_EXCEPTION(__except_type, __msg) \ + throw __except_type( (__msg), (__FILE__), (__LINE__) ); + +#define ASSERT_EXCEPTION(__condition, __except_type, __msg) \ + if (! (__condition) ) { \ + std::string newmsg = #__condition; \ + newmsg += " evaluated false: "; \ + newmsg += __msg; \ + throw __except_type( (newmsg), (__FILE__), (__LINE__) ); \ + } + +#define DECLARE_STD_EXCEPTION(__except_type) \ + class __except_type : public Ipopt::IpoptException \ + { \ + public: \ + __except_type(std::string msg, std::string fname, Ipopt::Index line) \ + : Ipopt::IpoptException(msg,fname,line, #__except_type) {} \ + __except_type(const __except_type& copy) \ + : Ipopt::IpoptException(copy) {} \ + private: \ + __except_type(); \ + void operator=(const __except_type&); \ + } + +#endif diff --git a/thirdparty/linux/include/coin1/IpExpansionMatrix.hpp b/thirdparty/linux/include/coin1/IpExpansionMatrix.hpp new file mode 100644 index 0000000..cbb9a99 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpExpansionMatrix.hpp @@ -0,0 +1,212 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpExpansionMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPEXPANSIONMATRIX_HPP__ +#define __IPEXPANSIONMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /** forward declarations */ + class ExpansionMatrixSpace; + + /** Class for expansion/projection matrices. These matrices allow + * to lift a vector to a vector with larger dimension, keeping + * some elements of the larger vector zero. This operation is achieved + * by the MultVector operation. The transpose operation then + * filters some elements from a large vector into a smaller vector. + */ + class ExpansionMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ExpansionMatrix(const ExpansionMatrixSpace* owner_space); + + /** Destructor */ + ~ExpansionMatrix(); + //@} + + /** Return the vector of indices marking the expanded position. + * The result is the Index array (of length NSmallVec=NCols()) + * that stores the mapping from the small vector to the large + * vector. For each element i=0,..,NSmallVec in the small + * vector, ExpandedPosIndices()[i] give the corresponding index + * in the large vector. + */ + const Index* ExpandedPosIndices() const; + + /** Return the vector of indices marking the compressed position. + * The result is the Index array (of length NLargeVec=NRows()) + * that stores the mapping from the large vector to the small + * vector. For each element i=0,..,NLargeVec in the large + * vector, CompressedPosIndices()[i] gives the corresponding + * index in the small vector, unless CompressedPosIndices()[i] is + * negative. + */ + const Index* CompressedPosIndices() const; + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized implementation. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 1, 1); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index row_offset, + Index col_offset) const; + + friend class ParExpansionMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ExpansionMatrix(); + + /** Copy Constructor */ + ExpansionMatrix(const ExpansionMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ExpansionMatrix&); + //@} + + const ExpansionMatrixSpace* owner_space_; + + }; + + /** This is the matrix space for ExpansionMatrix. + */ + class ExpansionMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the list of elements of the large vector + * (of size NLargeVec) to be filtered into the small vector (of + * size NSmallVec). For each i=0..NSmallVec-1 the i-th element + * of the small vector will be put into the ExpPos[i] position of + * the large vector. The position counting in the vector is + * assumed to start at 0 (C-like array notation). + */ + ExpansionMatrixSpace(Index NLargeVec, + Index NSmallVec, + const Index *ExpPos, + const int offset = 0); + + /** Destructor */ + ~ExpansionMatrixSpace() + { + delete [] compressed_pos_; + delete [] expanded_pos_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + ExpansionMatrix* MakeNewExpansionMatrix() const + { + return new ExpansionMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewExpansionMatrix(); + } + + /** Accessor Method to obtain the Index array (of length + * NSmallVec=NCols()) that stores the mapping from the small + * vector to the large vector. For each element i=0,..,NSmallVec + * in the small vector, ExpandedPosIndices()[i] give the + * corresponding index in the large vector. + */ + const Index* ExpandedPosIndices() const + { + return expanded_pos_; + } + + /** Accessor Method to obtain the Index array (of length + * NLargeVec=NRows()) that stores the mapping from the large + * vector to the small vector. For each element i=0,..,NLargeVec + * in the large vector, CompressedPosIndices()[i] gives the + * corresponding index in the small vector, unless + * CompressedPosIndices()[i] is negative. + */ + const Index* CompressedPosIndices() const + { + return compressed_pos_; + } + + private: + Index *expanded_pos_; + Index *compressed_pos_; + }; + + /* inline methods */ + inline + const Index* ExpansionMatrix::ExpandedPosIndices() const + { + return owner_space_->ExpandedPosIndices(); + } + + inline + const Index* ExpansionMatrix::CompressedPosIndices() const + { + return owner_space_->CompressedPosIndices(); + } + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpGenTMatrix.hpp b/thirdparty/linux/include/coin1/IpGenTMatrix.hpp new file mode 100644 index 0000000..059bfea --- /dev/null +++ b/thirdparty/linux/include/coin1/IpGenTMatrix.hpp @@ -0,0 +1,264 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpGenTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPGENTMATRIX_HPP__ +#define __IPGENTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class GenTMatrixSpace; + + /** Class for general matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a general matrix is + * stored in three arrays, Irow, Jcol, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (row and column indices), and the last array + * stores the value at that location. If nonzero elements are + * listed more than once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irow and Jcol) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + */ + class GenTMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + GenTMatrix(const GenTMatrixSpace* owner_space); + + /** Destructor */ + ~GenTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements are copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to one of the + * constructors above. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Array with Row indices (counting starts at 1) */ + const Index* Irows() const; + + /** Array with Column indices (counting starts at 1) */ + const Index* Jcols() const; + + /** Array with nonzero values (const version). */ + const Number* Values() const + { + return values_; + } + + /** Array with the nonzero values of this matrix (non-const + * version). Use this method only if you are intending to change + * the values, because the GenTMatrix will be marked as changed. + */ + Number* Values() + { + ObjectChanged(); + initialized_ = true; + return values_; + } + //@} + + protected: + /**@name Overloaded methods from Matrix base class*/ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector &x, Number beta, + Vector &y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const + { + PrintImplOffset(jnlst, level, category, name, indent, prefix, 0); + } + //@} + + void PrintImplOffset(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix, + Index offset) const; + + friend class ParGenMatrix; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + GenTMatrix(); + + /** Copy Constructor */ + GenTMatrix(const GenTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const GenTMatrix&); + //@} + + /** Copy of the owner space as a GenTMatrixSpace instead of + * a MatrixSpace + */ + const GenTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a GenTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class GenTMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns, as well as + * the number of nonzeros and the position of the nonzero + * elements. Note that the counting of the nonzeros starts a 1, + * i.e., iRows[i]==1 and jCols[i]==1 refers to the first element + * in the first row. This is in accordance with the HSL data + * structure. + */ + GenTMatrixSpace(Index nRows, Index nCols, + Index nonZeros, + const Index* iRows, const Index* jCols); + + /** Destructor */ + ~GenTMatrixSpace() + { + delete [] iRows_; + delete [] jCols_; + } + //@} + + /** Method for creating a new matrix of this specific type. */ + GenTMatrix* MakeNewGenTMatrix() const + { + return new GenTMatrix(this); + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewGenTMatrix(); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element (counting starts at 1) */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element (counting starts at 1) */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /** @name Sparsity structure of matrices generated by this matrix + * space. + */ + //@{ + const Index nonZeros_; + Index* jCols_; + Index* iRows_; + //@} + + /** This method is only for the GenTMatrix to call in order + * to allocate internal storage */ + Number* AllocateInternalStorage() const; + + /** This method is only for the GenTMatrix to call in order + * to de-allocate internal storage */ + void FreeInternalStorage(Number* values) const; + + friend class GenTMatrix; + }; + + /* inline methods */ + inline + Index GenTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* GenTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* GenTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpHessianUpdater.hpp b/thirdparty/linux/include/coin1/IpHessianUpdater.hpp new file mode 100644 index 0000000..a3912d6 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpHessianUpdater.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpHessianUpdater.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-12-26 + +#ifndef __IPHESSIANUPDATER_HPP__ +#define __IPHESSIANUPDATER_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Abstract base class for objects responsible for updating the + * Hessian information. This can be done using exact second + * derivatives from the NLP, or by a quasi-Newton Option. The + * result is put into the W field in IpData. + */ + class HessianUpdater : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + HessianUpdater() + {} + + /** Default destructor */ + virtual ~HessianUpdater() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Update the Hessian based on the current information in IpData, + * and possibly on information from previous calls. + */ + virtual void UpdateHessian() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + HessianUpdater(const HessianUpdater&); + + /** Overloaded Equals Operator */ + void operator=(const HessianUpdater&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIdentityMatrix.hpp b/thirdparty/linux/include/coin1/IpIdentityMatrix.hpp new file mode 100644 index 0000000..8032306 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIdentityMatrix.hpp @@ -0,0 +1,149 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIdentityMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIDENTITYMATRIX_HPP__ +#define __IPIDENTITYMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Matrices which are multiples of the identity matrix. + * + */ + class IdentityMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix + * (true identity matrix). + */ + IdentityMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~IdentityMatrix(); + //@} + + /** Method for setting the factor for the identity matrix. */ + void SetFactor(Number factor) + { + factor_ = factor; + } + + /** Method for getting the factor for the identity matrix. */ + Number GetFactor() const + { + return factor_; + } + + /** Method for obtaining the dimention of the matrix. */ + Index Dim() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void AddMSinvZImpl(Number alpha, const Vector& S, + const Vector& Z, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrix(); + + /** Copy Constructor */ + IdentityMatrix(const IdentityMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrix&); + //@} + + /** Scaling factor for this identity matrix */ + Number factor_; + }; + + /** This is the matrix space for IdentityMatrix. */ + class IdentityMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix. */ + IdentityMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~IdentityMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewIdentityMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + IdentityMatrix* MakeNewIdentityMatrix() const + { + return new IdentityMatrix(this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IdentityMatrixSpace(); + + /** Copy Constructor */ + IdentityMatrixSpace(const IdentityMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const IdentityMatrixSpace&); + //@} + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpIpoptAlg.hpp b/thirdparty/linux/include/coin1/IpIpoptAlg.hpp new file mode 100644 index 0000000..60e3147 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIpoptAlg.hpp @@ -0,0 +1,224 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptAlg.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTALG_HPP__ +#define __IPIPOPTALG_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpAlgStrategy.hpp" +#include "IpSearchDirCalculator.hpp" +#include "IpLineSearch.hpp" +#include "IpMuUpdate.hpp" +#include "IpConvCheck.hpp" +#include "IpOptionsList.hpp" +#include "IpIterateInitializer.hpp" +#include "IpIterationOutput.hpp" +#include "IpAlgTypes.hpp" +#include "IpHessianUpdater.hpp" +#include "IpEqMultCalculator.hpp" + +namespace Ipopt +{ + + /** @name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(STEP_COMPUTATION_FAILED); + //@} + + /** The main ipopt algorithm class. + * Main Ipopt algorithm class, contains the main optimize method, + * handles the execution of the optimization. + * The constructor initializes the data structures through the nlp, + * and the Optimize method then assumes that everything is + * initialized and ready to go. + * After an optimization is complete, the user can access the + * solution through the passed in ip_data structure. + * Multiple calls to the Optimize method are allowed as long as the + * structure of the problem remains the same (i.e. starting point + * or nlp parameter changes only). + */ + class IpoptAlgorithm : public AlgorithmStrategyObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor. (The IpoptAlgorithm uses smart pointers for these + * passed-in pieces to make sure that a user of IpoptAlgoroithm + * cannot pass in an object created on the stack!) + */ + IpoptAlgorithm(const SmartPtr<SearchDirectionCalculator>& search_dir_calculator, + const SmartPtr<LineSearch>& line_search, + const SmartPtr<MuUpdate>& mu_update, + const SmartPtr<ConvergenceCheck>& conv_check, + const SmartPtr<IterateInitializer>& iterate_initializer, + const SmartPtr<IterationOutput>& iter_output, + const SmartPtr<HessianUpdater>& hessian_updater, + const SmartPtr<EqMultiplierCalculator>& eq_multiplier_calculator = NULL); + + /** Default destructor */ + virtual ~IpoptAlgorithm(); + //@} + + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** Main solve method. */ + SolverReturn Optimize(bool isResto = false); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /**@name Access to internal strategy objects */ + //@{ + SmartPtr<SearchDirectionCalculator> SearchDirCalc() + { + return search_dir_calculator_; + } + //@} + + static void print_copyright_message(const Journalist& jnlst); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptAlgorithm(); + + /** Copy Constructor */ + IpoptAlgorithm(const IpoptAlgorithm&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAlgorithm&); + //@} + + /** @name Strategy objects */ + //@{ + SmartPtr<SearchDirectionCalculator> search_dir_calculator_; + SmartPtr<LineSearch> line_search_; + SmartPtr<MuUpdate> mu_update_; + SmartPtr<ConvergenceCheck> conv_check_; + SmartPtr<IterateInitializer> iterate_initializer_; + SmartPtr<IterationOutput> iter_output_; + SmartPtr<HessianUpdater> hessian_updater_; + /** The multipler calculator (for y_c and y_d) has to be set only + * if option recalc_y is set to true */ + SmartPtr<EqMultiplierCalculator> eq_multiplier_calculator_; + //@} + + /** @name Main steps of the algorthim */ + //@{ + /** Method for updating the current Hessian. This can either just + * evaluate the exact Hessian (based on the current iterate), or + * perform a quasi-Newton update. + */ + void UpdateHessian(); + + /** Method to update the barrier parameter. Returns false, if the + * algorithm can't continue with the regular procedure and needs + * to revert to a fallback mechanism in the line search (such as + * restoration phase) */ + bool UpdateBarrierParameter(); + + /** Method to setup the call to the PDSystemSolver. Returns + * false, if the algorithm can't continue with the regular + * procedure and needs to revert to a fallback mechanism in the + * line search (such as restoration phase) */ + bool ComputeSearchDirection(); + + /** Method computing the new iterate (usually vialine search). + * The acceptable point is the one in trial after return. + */ + void ComputeAcceptableTrialPoint(); + + /** Method for accepting the trial point as the new iteration, + * possibly after adjusting the variable bounds in the NLP. */ + void AcceptTrialPoint(); + + /** Do all the output for one iteration */ + void OutputIteration(); + + /** Sets up initial values for the iterates, + * Corrects the initial values for x and s (force in bounds) + */ + void InitializeIterates(); + + /** Print the problem size statistics */ + void PrintProblemStatistics(); + + /** Compute the Lagrangian multipliers for a feasibility problem*/ + void ComputeFeasibilityMultipliers(); + //@} + + /** @name internal flags */ + //@{ + /** Flag indicating if the statistic should not be printed */ + bool skip_print_problem_stats_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** safeguard factor for bound multipliers. If value >= 1, then + * the dual variables will never deviate from the primal estimate + * by more than the factors kappa_sigma and 1./kappa_sigma. + */ + Number kappa_sigma_; + /** Flag indicating whether the y multipliers should be + * recalculated with the eq_mutliplier_calculator object for each + * new point. */ + bool recalc_y_; + /** Feasibility threshold for recalc_y */ + Number recalc_y_feas_tol_; + /** Flag indicating if we want to do Mehrotras's algorithm. This + * means that a number of options are ignored, or have to be set + * (or are automatically set) to certain values. */ + bool mehrotra_algorithm_; + /** String specifying linear solver */ + std::string linear_solver_; + //@} + + /** @name auxiliary functions */ + //@{ + void calc_number_of_bounds( + const Vector& x, + const Vector& x_L, + const Vector& x_U, + const Matrix& Px_L, + const Matrix& Px_U, + Index& n_tot, + Index& n_only_lower, + Index& n_both, + Index& n_only_upper); + + /** Method for ensuring that the trial multipliers are not too far + * from the primal estime. If a correction is made, new_trial_z + * is a pointer to the corrected multiplier, and the return value + * of this method give the magnitutde of the largest correction + * that we done. If no correction was made, new_trial_z is just + * a pointer to trial_z, and the return value is zero. + */ + Number correct_bound_multiplier(const Vector& trial_z, + const Vector& trial_slack, + const Vector& trial_compl, + SmartPtr<const Vector>& new_trial_z); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIpoptApplication.hpp b/thirdparty/linux/include/coin1/IpIpoptApplication.hpp new file mode 100644 index 0000000..0febc94 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIpoptApplication.hpp @@ -0,0 +1,296 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptApplication.hpp 2617 2015-11-26 16:00:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTAPPLICATION_HPP__ +#define __IPIPOPTAPPLICATION_HPP__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#include <iostream> + +#include "IpJournalist.hpp" +#include "IpTNLP.hpp" +#include "IpNLP.hpp" +/* Return codes for the Optimize call for an application */ +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(IPOPT_APPLICATION_ERROR); + + /* forward declarations */ + class IpoptAlgorithm; + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + class AlgorithmBuilder; + class RegisteredOptions; + class OptionsList; + class SolveStatistics; + + /** This is the main application class for making calls to Ipopt. */ + class IpoptApplication : public ReferencedObject + { + public: + IpoptApplication(bool create_console_out = true, + bool create_empty = false); + + /** Another constructor that assumes that the code in the + * (default) constructor has already been executed */ + IpoptApplication(SmartPtr<RegisteredOptions> reg_options, + SmartPtr<OptionsList> options, + SmartPtr<Journalist> jnlst); + + virtual ~IpoptApplication(); + + /** Method for creating a new IpoptApplication that uses the same + * journalist and registered options, and a copy of the options + list. */ + virtual SmartPtr<IpoptApplication> clone(); + + /** Initialization method. This method reads options from the + * input stream and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the input stream. + */ + virtual ApplicationReturnStatus Initialize(std::istream& is, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(std::string params_file, bool allow_clobber = false); + /** Initialization method. This method reads options from the + * params file and initializes the journalists. It returns + * something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * You should call one of the initialization methods at some + * point before the first optimize call. + * Note: You can skip the processing of a params file by + * setting params_file to "". + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the params file. + */ + virtual ApplicationReturnStatus Initialize(const char* params_file, bool allow_clobber = false) + { + return Initialize(std::string(params_file), allow_clobber); + } + /** Initialize method. This method reads the options file specified + * by the option_file_name option and initializes the journalists. + * You should call this method at some point before the first optimize + * call. + * It returns something other than Solve_Succeeded if there was a + * problem in the initialization (such as an invalid option). + * Set @par allow_clobber to true if you want to allow + * overwriting options that are set by the options file. + */ + virtual ApplicationReturnStatus Initialize(bool allow_clobber = false); + + /**@name Solve methods */ + //@{ + /** Solve a problem that inherits from TNLP */ + virtual ApplicationReturnStatus OptimizeTNLP(const SmartPtr<TNLP>& tnlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr<NLP>& nlp); + + /** Solve a problem that inherits from NLP */ + virtual ApplicationReturnStatus OptimizeNLP(const SmartPtr<NLP>& nlp, SmartPtr<AlgorithmBuilder>& alg_builder); + + /** Solve a problem (that inherits from TNLP) for a repeated time. + * The OptimizeTNLP method must have been called before. The + * TNLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeTNLP(const SmartPtr<TNLP>& tnlp); + + /** Solve a problem (that inherits from NLP) for a repeated time. + * The OptimizeNLP method must have been called before. The + * NLP must be the same object, and the structure (number of + * variables and constraints and position of nonzeros in Jacobian + * and Hessian must be the same). */ + virtual ApplicationReturnStatus ReOptimizeNLP(const SmartPtr<NLP>& nlp); + //@} + + /** Method for opening an output file with given print_level. + * Returns false if there was a problem. */ + virtual bool OpenOutputFile(std::string file_name, EJournalLevel print_level); + + /**@name Accessor methods */ + //@{ + /** Get the Journalist for printing output */ + virtual SmartPtr<Journalist> Jnlst() + { + return jnlst_; + } + + /** Get a pointer to RegisteredOptions object to + * add new options */ + virtual SmartPtr<RegisteredOptions> RegOptions() + { + return reg_options_; + } + + /** Get the options list for setting options */ + virtual SmartPtr<OptionsList> Options() + { + return options_; + } + + /** Get the options list for setting options (const version) */ + virtual SmartPtr<const OptionsList> Options() const + { + return ConstPtr(options_); + } + + /** Get the object with the statistics about the most recent + * optimization run. */ + virtual SmartPtr<SolveStatistics> Statistics(); + + /** Get the IpoptNLP Object */ + virtual SmartPtr<IpoptNLP> IpoptNLPObject(); + + /** Get the IpoptData Object */ + SmartPtr<IpoptData> IpoptDataObject(); + + /** Get the IpoptCQ Object */ + virtual SmartPtr<IpoptCalculatedQuantities> IpoptCQObject(); + + /** Get the Algorithm Object */ + SmartPtr<IpoptAlgorithm> AlgorithmObject(); + //@} + + /** Method for printing Ipopt copyright message now instead of + * just before the optimization. If you want to have the copy + * right message printed earlier than by default, call this + * method at the convenient time. */ + void PrintCopyrightMessage(); + + /** Method to set whether non-ipopt non-bad_alloc exceptions + * are rethrown by Ipopt. + * By default, non-Ipopt and non-std::bad_alloc exceptions are + * caught by Ipopts initialization and optimization methods + * and the status NonIpopt_Exception_Thrown is returned. + * This function allows to enable rethrowing of such exceptions. + */ + void RethrowNonIpoptException(bool dorethrow) + { + rethrow_nonipoptexception_ = dorethrow; + } + + /** @name Methods for IpoptTypeInfo */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Method to registering all Ipopt options. */ + static void + RegisterAllIpoptOptions(const SmartPtr<RegisteredOptions>& roptions); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // IpoptApplication(); + + /** Copy Constructor */ + IpoptApplication(const IpoptApplication&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptApplication&); + //@} + + /** Method for the actual optimize call of the Ipopt algorithm. + * This is used both for Optimize and ReOptimize */ + ApplicationReturnStatus call_optimize(); + + /**@name Variables that customize the application behavior */ + //@{ + /** Decide whether or not the ipopt.opt file should be read */ + bool read_params_dat_; + + /** Decide whether non-ipopt non-bad_alloc exceptions should be rethrown */ + bool rethrow_nonipoptexception_; + //@} + + /** Journalist for reporting output */ + SmartPtr<Journalist> jnlst_; + + /** RegisteredOptions */ + SmartPtr<RegisteredOptions> reg_options_; + + /** OptionsList used for the application */ + SmartPtr<OptionsList> options_; + + /** Object for storing statistics about the most recent + * optimization run. */ + SmartPtr<SolveStatistics> statistics_; + + /** Object with the algorithm sceleton. + */ + SmartPtr<IpoptAlgorithm> alg_; + + /** IpoptNLP Object for the NLP. We keep this around for a + * ReOptimize warm start. */ + SmartPtr<IpoptNLP> ip_nlp_; + + /** IpoptData Object for the NLP. We keep this around for a + * ReOptimize warm start. + */ + SmartPtr<IpoptData> ip_data_; + + /** IpoptCalculatedQuantities Object for the NLP. We keep this + * around for a ReOptimize warm start. + */ + SmartPtr<IpoptCalculatedQuantities> ip_cq_; + + /** Pointer to the TNLPAdapter used to convert the TNLP to an NLP. + * We keep this around for the ReOptimizerTNLP call. */ + SmartPtr<NLP> nlp_adapter_; + + /** @name Algorithmic parameters */ + //@{ + /** Flag indicating if we are to use the inexact linear solver option */ + bool inexact_algorithm_; + /** Flag indicating if all bounds should be replaced by inequality + * constraints. This is necessary for the inexact algorithm. */ + bool replace_bounds_; + //@} + }; + +} // namespace Ipopt + +extern "C" IPOPT_EXPORT(class Ipopt::IpoptApplication *) IpoptApplicationFactory(); + +#endif diff --git a/thirdparty/linux/include/coin1/IpIpoptCalculatedQuantities.hpp b/thirdparty/linux/include/coin1/IpIpoptCalculatedQuantities.hpp new file mode 100644 index 0000000..3b60b16 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIpoptCalculatedQuantities.hpp @@ -0,0 +1,751 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptCalculatedQuantities.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTCALCULATEDQUANTITIES_HPP__ +#define __IPIPOPTCALCULATEDQUANTITIES_HPP__ + +#include "IpSmartPtr.hpp" +#include "IpCachedResults.hpp" + +#include <string> + +namespace Ipopt +{ + class IpoptNLP; + class IpoptData; + class Vector; + class Matrix; + class SymMatrix; + class Journalist; + class OptionsList; + class RegisteredOptions; + + /** Norm types */ + enum ENormType { + NORM_1=0, + NORM_2, + NORM_MAX + }; + + /** Base class for additional calculated quantities that is special + * to a particular type of algorithm, such as the CG penalty + * function, or using iterative linear solvers. The regular + * IpoptCalculatedQuantities object should be given a derivation of + * this base class when it is created. */ + class IpoptAdditionalCq : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalCq() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalCq() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalCq(const IpoptAdditionalCq&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalCq&); + //@} + }; + + /** Class for all IPOPT specific calculated quantities. + * + */ + class IpoptCalculatedQuantities : public ReferencedObject + { + public: + + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptCalculatedQuantities(const SmartPtr<IpoptNLP>& ip_nlp, + const SmartPtr<IpoptData>& ip_data); + /** Default destructor */ + virtual ~IpoptCalculatedQuantities(); + //@} + + /** Method for setting pointer for additional calculated + * quantities. This needs to be called before Initialized. */ + void SetAddCq(SmartPtr<IpoptAdditionalCq> add_cq) + { + DBG_ASSERT(!HaveAddCq()); + add_cq_ = add_cq; + } + + /** Method detecting if additional object for calculated + * quantities has already been set */ + bool HaveAddCq() + { + return IsValid(add_cq_); + } + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Slacks */ + //@{ + /** Slacks for x_L (at current iterate) */ + SmartPtr<const Vector> curr_slack_x_L(); + /** Slacks for x_U (at current iterate) */ + SmartPtr<const Vector> curr_slack_x_U(); + /** Slacks for s_L (at current iterate) */ + SmartPtr<const Vector> curr_slack_s_L(); + /** Slacks for s_U (at current iterate) */ + SmartPtr<const Vector> curr_slack_s_U(); + /** Slacks for x_L (at trial point) */ + SmartPtr<const Vector> trial_slack_x_L(); + /** Slacks for x_U (at trial point) */ + SmartPtr<const Vector> trial_slack_x_U(); + /** Slacks for s_L (at trial point) */ + SmartPtr<const Vector> trial_slack_s_L(); + /** Slacks for s_U (at trial point) */ + SmartPtr<const Vector> trial_slack_s_U(); + /** Indicating whether or not we "fudged" the slacks */ + Index AdjustedTrialSlacks(); + /** Reset the flags for "fudged" slacks */ + void ResetAdjustedTrialSlacks(); + //@} + + /** @name Objective function */ + //@{ + /** Value of objective function (at current point) */ + virtual Number curr_f(); + /** Unscaled value of the objective function (at the current point) */ + virtual Number unscaled_curr_f(); + /** Value of objective function (at trial point) */ + virtual Number trial_f(); + /** Unscaled value of the objective function (at the trial point) */ + virtual Number unscaled_trial_f(); + /** Gradient of objective function (at current point) */ + SmartPtr<const Vector> curr_grad_f(); + /** Gradient of objective function (at trial point) */ + SmartPtr<const Vector> trial_grad_f(); + //@} + + /** @name Barrier Objective Function */ + //@{ + /** Barrier Objective Function Value + * (at current iterate with current mu) + */ + virtual Number curr_barrier_obj(); + /** Barrier Objective Function Value + * (at trial point with current mu) + */ + virtual Number trial_barrier_obj(); + + /** Gradient of barrier objective function with respect to x + * (at current point with current mu) */ + SmartPtr<const Vector> curr_grad_barrier_obj_x(); + /** Gradient of barrier objective function with respect to s + * (at current point with current mu) */ + SmartPtr<const Vector> curr_grad_barrier_obj_s(); + + /** Gradient of the damping term with respect to x (times + * kappa_d) */ + SmartPtr<const Vector> grad_kappa_times_damping_x(); + /** Gradient of the damping term with respect to s (times + * kappa_d) */ + SmartPtr<const Vector> grad_kappa_times_damping_s(); + //@} + + /** @name Constraints */ + //@{ + /** c(x) (at current point) */ + SmartPtr<const Vector> curr_c(); + /** unscaled c(x) (at current point) */ + SmartPtr<const Vector> unscaled_curr_c(); + /** c(x) (at trial point) */ + SmartPtr<const Vector> trial_c(); + /** unscaled c(x) (at trial point) */ + SmartPtr<const Vector> unscaled_trial_c(); + /** d(x) (at current point) */ + SmartPtr<const Vector> curr_d(); + /** unscaled d(x) (at current point) */ + SmartPtr<const Vector> unscaled_curr_d(); + /** d(x) (at trial point) */ + SmartPtr<const Vector> trial_d(); + /** d(x) - s (at current point) */ + SmartPtr<const Vector> curr_d_minus_s(); + /** d(x) - s (at trial point) */ + SmartPtr<const Vector> trial_d_minus_s(); + /** Jacobian of c (at current point) */ + SmartPtr<const Matrix> curr_jac_c(); + /** Jacobian of c (at trial point) */ + SmartPtr<const Matrix> trial_jac_c(); + /** Jacobian of d (at current point) */ + SmartPtr<const Matrix> curr_jac_d(); + /** Jacobian of d (at trial point) */ + SmartPtr<const Matrix> trial_jac_d(); + /** Product of Jacobian (evaluated at current point) of C + * transpose with general vector */ + SmartPtr<const Vector> curr_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with general vector */ + SmartPtr<const Vector> trial_jac_cT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * transpose with general vector */ + SmartPtr<const Vector> curr_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with general vector */ + SmartPtr<const Vector> trial_jac_dT_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of C + * transpose with current y_c */ + SmartPtr<const Vector> curr_jac_cT_times_curr_y_c(); + /** Product of Jacobian (evaluated at trial point) of C + * transpose with trial y_c */ + SmartPtr<const Vector> trial_jac_cT_times_trial_y_c(); + /** Product of Jacobian (evaluated at current point) of D + * transpose with current y_d */ + SmartPtr<const Vector> curr_jac_dT_times_curr_y_d(); + /** Product of Jacobian (evaluated at trial point) of D + * transpose with trial y_d */ + SmartPtr<const Vector> trial_jac_dT_times_trial_y_d(); + /** Product of Jacobian (evaluated at current point) of C + * with general vector */ + SmartPtr<const Vector> curr_jac_c_times_vec(const Vector& vec); + /** Product of Jacobian (evaluated at current point) of D + * with general vector */ + SmartPtr<const Vector> curr_jac_d_times_vec(const Vector& vec); + /** Constraint Violation (at current iterate). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number curr_constraint_violation(); + /** Constraint Violation (at trial point). This value should + * be used in the line search, and not curr_primal_infeasibility(). + * What type of norm is used depends on constr_viol_normtype */ + virtual Number trial_constraint_violation(); + /** Real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at current + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_curr_nlp_constraint_violation(ENormType NormType); + /** Unscaled real constraint violation in a given norm (at trial + * iterate). This considers the inequality constraints without + * slacks. */ + virtual Number unscaled_trial_nlp_constraint_violation(ENormType NormType); + //@} + + /** @name Hessian matrices */ + //@{ + /** exact Hessian at current iterate (uncached) */ + SmartPtr<const SymMatrix> curr_exact_hessian(); + //@} + + /** @name primal-dual error and its components */ + //@{ + /** x-part of gradient of Lagrangian function (at current point) */ + SmartPtr<const Vector> curr_grad_lag_x(); + /** x-part of gradient of Lagrangian function (at trial point) */ + SmartPtr<const Vector> trial_grad_lag_x(); + /** s-part of gradient of Lagrangian function (at current point) */ + SmartPtr<const Vector> curr_grad_lag_s(); + /** s-part of gradient of Lagrangian function (at trial point) */ + SmartPtr<const Vector> trial_grad_lag_s(); + /** x-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr<const Vector> curr_grad_lag_with_damping_x(); + /** s-part of gradient of Lagrangian function (at current point) + including linear damping term */ + SmartPtr<const Vector> curr_grad_lag_with_damping_s(); + /** Complementarity for x_L (for current iterate) */ + SmartPtr<const Vector> curr_compl_x_L(); + /** Complementarity for x_U (for current iterate) */ + SmartPtr<const Vector> curr_compl_x_U(); + /** Complementarity for s_L (for current iterate) */ + SmartPtr<const Vector> curr_compl_s_L(); + /** Complementarity for s_U (for current iterate) */ + SmartPtr<const Vector> curr_compl_s_U(); + /** Complementarity for x_L (for trial iterate) */ + SmartPtr<const Vector> trial_compl_x_L(); + /** Complementarity for x_U (for trial iterate) */ + SmartPtr<const Vector> trial_compl_x_U(); + /** Complementarity for s_L (for trial iterate) */ + SmartPtr<const Vector> trial_compl_s_L(); + /** Complementarity for s_U (for trial iterate) */ + SmartPtr<const Vector> trial_compl_s_U(); + /** Relaxed complementarity for x_L (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_x_L(); + /** Relaxed complementarity for x_U (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_x_U(); + /** Relaxed complementarity for s_L (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_s_L(); + /** Relaxed complementarity for s_U (for current iterate and current mu) */ + SmartPtr<const Vector> curr_relaxed_compl_s_U(); + + /** Primal infeasibility in a given norm (at current iterate). */ + virtual Number curr_primal_infeasibility(ENormType NormType); + /** Primal infeasibility in a given norm (at trial point) */ + virtual Number trial_primal_infeasibility(ENormType NormType); + + /** Dual infeasibility in a given norm (at current iterate) */ + virtual Number curr_dual_infeasibility(ENormType NormType); + /** Dual infeasibility in a given norm (at trial iterate) */ + virtual Number trial_dual_infeasibility(ENormType NormType); + /** Unscaled dual infeasibility in a given norm (at current iterate) */ + virtual Number unscaled_curr_dual_infeasibility(ENormType NormType); + + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) */ + virtual Number curr_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at trial iterate) */ + virtual Number trial_complementarity(Number mu, ENormType NormType); + /** Complementarity (for all complementarity conditions together) + * in a given norm (at current iterate) without NLP scaling. */ + virtual Number unscaled_curr_complementarity(Number mu, ENormType NormType); + + /** Centrality measure (in spirit of the -infinity-neighborhood. */ + Number CalcCentralityMeasure(const Vector& compl_x_L, + const Vector& compl_x_U, + const Vector& compl_s_L, + const Vector& compl_s_U); + /** Centrality measure at current point */ + virtual Number curr_centrality_measure(); + + /** Total optimality error for the original NLP at the current + * iterate, using scaling factors based on multipliers. Note + * that here the constraint violation is measured without slacks + * (nlp_constraint_violation) */ + virtual Number curr_nlp_error(); + /** Total optimality error for the original NLP at the current + * iterate, but using no scaling based on multipliers, and no + * scaling for the NLP. Note that here the constraint violation + * is measured without slacks (nlp_constraint_violation) */ + virtual Number unscaled_curr_nlp_error(); + + /** Total optimality error for the barrier problem at the + * current iterate, using scaling factors based on multipliers. */ + virtual Number curr_barrier_error(); + + /** Norm of the primal-dual system for a given mu (at current + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number curr_primal_dual_system_error(Number mu); + /** Norm of the primal-dual system for a given mu (at trial + * iterate). The norm is defined as the sum of the 1-norms of + * dual infeasibiliy, primal infeasibility, and complementarity, + * all divided by the number of elements of the vectors of which + * the norm is taken. + */ + virtual Number trial_primal_dual_system_error(Number mu); + //@} + + /** @name Computing fraction-to-the-boundary step sizes */ + //@{ + /** Fraction to the boundary from (current) primal variables x and s + * for a given step */ + Number primal_frac_to_the_bound(Number tau, + const Vector& delta_x, + const Vector& delta_s); + /** Fraction to the boundary from (current) primal variables x and s + * for internal (current) step */ + Number curr_primal_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step */ + Number dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for a given step, without caching */ + Number uncached_dual_frac_to_the_bound(Number tau, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + /** Fraction to the boundary from (current) dual variables z and v + * for internal (current) step */ + Number curr_dual_frac_to_the_bound(Number tau); + /** Fraction to the boundary from (current) slacks for a given + * step in the slacks. Usually, one will use the + * primal_frac_to_the_bound method to compute the primal fraction + * to the boundary step size, but if it is cheaper to provide the + * steps in the slacks directly (e.g. when the primal step sizes + * are only temporary), the this method is more efficient. This + * method does not cache computations. */ + Number uncached_slack_frac_to_the_bound(Number tau, + const Vector& delta_x_L, + const Vector& delta_x_U, + const Vector& delta_s_L, + const Vector& delta_s_U); + //@} + + /** @name Sigma matrices */ + //@{ + SmartPtr<const Vector> curr_sigma_x(); + SmartPtr<const Vector> curr_sigma_s(); + //@} + + /** average of current values of the complementarities */ + Number curr_avrg_compl(); + /** average of trial values of the complementarities */ + Number trial_avrg_compl(); + + /** inner_product of current barrier obj. fn. gradient with + * current search direction */ + Number curr_gradBarrTDelta(); + + /** Compute the norm of a specific type of a set of vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + std::vector<SmartPtr<const Vector> > vecs); + + /** Compute the norm of a specific type of two vectors (uncached) */ + Number + CalcNormOfType(ENormType NormType, + const Vector& vec1, const Vector& vec2); + + /** Norm type used for calculating constraint violation */ + ENormType constr_viol_normtype() const + { + return constr_viol_normtype_; + } + + /** Method returning true if this is a square problem */ + bool IsSquareProblem() const; + + /** Method returning the IpoptNLP object. This should only be + * used with care! */ + SmartPtr<IpoptNLP>& GetIpoptNLP() + { + return ip_nlp_; + } + + IpoptAdditionalCq& AdditionalCq() + { + DBG_ASSERT(IsValid(add_cq_)); + return *add_cq_; + } + + /** Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + IpoptCalculatedQuantities(); + + /** Copy Constructor */ + IpoptCalculatedQuantities(const IpoptCalculatedQuantities&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptCalculatedQuantities&); + //@} + + /** @name Pointers for easy access to data and NLP information */ + //@{ + /** Ipopt NLP object */ + SmartPtr<IpoptNLP> ip_nlp_; + /** Ipopt Data object */ + SmartPtr<IpoptData> ip_data_; + /** Chen-Goldfarb specific calculated quantities */ + SmartPtr<IpoptAdditionalCq> add_cq_; + //@} + + /** @name Algorithmic Parameters that can be set throught the + * options list. Those parameters are initialize by calling the + * Initialize method.*/ + //@{ + /** Parameter in formula for computing overall primal-dual + * optimality error */ + Number s_max_; + /** Weighting factor for the linear damping term added to the + * barrier objective funciton. */ + Number kappa_d_; + /** fractional movement allowed in bounds */ + Number slack_move_; + /** Norm type to be used when calculating the constraint violation */ + ENormType constr_viol_normtype_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Desired value of the barrier parameter */ + Number mu_target_; + //@} + + /** @name Caches for slacks */ + //@{ + CachedResults< SmartPtr<Vector> > curr_slack_x_L_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_x_U_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_s_L_cache_; + CachedResults< SmartPtr<Vector> > curr_slack_s_U_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_x_L_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_x_U_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_s_L_cache_; + CachedResults< SmartPtr<Vector> > trial_slack_s_U_cache_; + Index num_adjusted_slack_x_L_; + Index num_adjusted_slack_x_U_; + Index num_adjusted_slack_s_L_; + Index num_adjusted_slack_s_U_; + //@} + + /** @name Cached for objective function stuff */ + //@{ + CachedResults<Number> curr_f_cache_; + CachedResults<Number> trial_f_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_f_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_f_cache_; + //@} + + /** @name Caches for barrier function stuff */ + //@{ + CachedResults<Number> curr_barrier_obj_cache_; + CachedResults<Number> trial_barrier_obj_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_barrier_obj_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_barrier_obj_s_cache_; + CachedResults< SmartPtr<const Vector> > grad_kappa_times_damping_x_cache_; + CachedResults< SmartPtr<const Vector> > grad_kappa_times_damping_s_cache_; + //@} + + /** @name Caches for constraint stuff */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_c_cache_; + CachedResults< SmartPtr<const Vector> > trial_c_cache_; + CachedResults< SmartPtr<const Vector> > curr_d_cache_; + CachedResults< SmartPtr<const Vector> > trial_d_cache_; + CachedResults< SmartPtr<const Vector> > curr_d_minus_s_cache_; + CachedResults< SmartPtr<const Vector> > trial_d_minus_s_cache_; + CachedResults< SmartPtr<const Matrix> > curr_jac_c_cache_; + CachedResults< SmartPtr<const Matrix> > trial_jac_c_cache_; + CachedResults< SmartPtr<const Matrix> > curr_jac_d_cache_; + CachedResults< SmartPtr<const Matrix> > trial_jac_d_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_cT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > trial_jac_cT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_dT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > trial_jac_dT_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_c_times_vec_cache_; + CachedResults< SmartPtr<const Vector> > curr_jac_d_times_vec_cache_; + CachedResults<Number> curr_constraint_violation_cache_; + CachedResults<Number> trial_constraint_violation_cache_; + CachedResults<Number> curr_nlp_constraint_violation_cache_; + CachedResults<Number> unscaled_curr_nlp_constraint_violation_cache_; + CachedResults<Number> unscaled_trial_nlp_constraint_violation_cache_; + //@} + + /** Cache for the exact Hessian */ + CachedResults< SmartPtr<const SymMatrix> > curr_exact_hessian_cache_; + + /** @name Components of primal-dual error */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_grad_lag_x_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_lag_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_s_cache_; + CachedResults< SmartPtr<const Vector> > trial_grad_lag_s_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_with_damping_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_grad_lag_with_damping_s_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_compl_s_U_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > trial_compl_s_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_x_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_x_U_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_s_L_cache_; + CachedResults< SmartPtr<const Vector> > curr_relaxed_compl_s_U_cache_; + CachedResults<Number> curr_primal_infeasibility_cache_; + CachedResults<Number> trial_primal_infeasibility_cache_; + CachedResults<Number> curr_dual_infeasibility_cache_; + CachedResults<Number> trial_dual_infeasibility_cache_; + CachedResults<Number> unscaled_curr_dual_infeasibility_cache_; + CachedResults<Number> curr_complementarity_cache_; + CachedResults<Number> trial_complementarity_cache_; + CachedResults<Number> curr_centrality_measure_cache_; + CachedResults<Number> curr_nlp_error_cache_; + CachedResults<Number> unscaled_curr_nlp_error_cache_; + CachedResults<Number> curr_barrier_error_cache_; + CachedResults<Number> curr_primal_dual_system_error_cache_; + CachedResults<Number> trial_primal_dual_system_error_cache_; + //@} + + /** @name Caches for fraction to the boundary step sizes */ + //@{ + CachedResults<Number> primal_frac_to_the_bound_cache_; + CachedResults<Number> dual_frac_to_the_bound_cache_; + //@} + + /** @name Caches for sigma matrices */ + //@{ + CachedResults< SmartPtr<const Vector> > curr_sigma_x_cache_; + CachedResults< SmartPtr<const Vector> > curr_sigma_s_cache_; + //@} + + /** Cache for average of current complementarity */ + CachedResults<Number> curr_avrg_compl_cache_; + /** Cache for average of trial complementarity */ + CachedResults<Number> trial_avrg_compl_cache_; + + /** Cache for grad barrier obj. fn inner product with step */ + CachedResults<Number> curr_gradBarrTDelta_cache_; + + /** @name Indicator vectors required for the linear damping terms + * to handle unbounded solution sets. */ + //@{ + /** Indicator vector for selecting the elements in x that have + * only lower bounds. */ + SmartPtr<Vector> dampind_x_L_; + /** Indicator vector for selecting the elements in x that have + * only upper bounds. */ + SmartPtr<Vector> dampind_x_U_; + /** Indicator vector for selecting the elements in s that have + * only lower bounds. */ + SmartPtr<Vector> dampind_s_L_; + /** Indicator vector for selecting the elements in s that have + * only upper bounds. */ + SmartPtr<Vector> dampind_s_U_; + //@} + + /** @name Temporary vectors for intermediate calcuations. We keep + * these around to avoid unnecessarily many new allocations of + * Vectors. */ + //@{ + SmartPtr<Vector> tmp_x_; + SmartPtr<Vector> tmp_s_; + SmartPtr<Vector> tmp_c_; + SmartPtr<Vector> tmp_d_; + SmartPtr<Vector> tmp_x_L_; + SmartPtr<Vector> tmp_x_U_; + SmartPtr<Vector> tmp_s_L_; + SmartPtr<Vector> tmp_s_U_; + + /** Accessor methods for the temporary vectors */ + Vector& Tmp_x(); + Vector& Tmp_s(); + Vector& Tmp_c(); + Vector& Tmp_d(); + Vector& Tmp_x_L(); + Vector& Tmp_x_U(); + Vector& Tmp_s_L(); + Vector& Tmp_s_U(); + //@} + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** @name Auxiliary functions */ + //@{ + /** Compute new vector containing the slack to a lower bound + * (uncached) + */ + SmartPtr<Vector> CalcSlack_L(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute new vector containing the slack to a upper bound + * (uncached) + */ + SmartPtr<Vector> CalcSlack_U(const Matrix& P, + const Vector& x, + const Vector& x_bound); + /** Compute barrier term at given point + * (uncached) + */ + Number CalcBarrierTerm(Number mu, + const Vector& slack_x_L, + const Vector& slack_x_U, + const Vector& slack_s_L, + const Vector& slack_s_U); + + /** Compute complementarity for slack / multiplier pair */ + SmartPtr<const Vector> CalcCompl(const Vector& slack, + const Vector& mult); + + /** Compute fraction to the boundary parameter for lower and upper bounds */ + Number CalcFracToBound(const Vector& slack_L, + Vector& tmp_L, + const Matrix& P_L, + const Vector& slack_U, + Vector& tmp_U, + const Matrix& P_U, + const Vector& delta, + Number tau); + + /** Compute the scaling factors for the optimality error. */ + void ComputeOptimalityErrorScaling(const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U, + Number s_max, + Number& s_d, Number& s_c); + + /** Check if slacks are becoming too small. If slacks are + * becoming too small, they are change. The return value is the + * number of corrected slacks. */ + Index CalculateSafeSlack(SmartPtr<Vector>& slack, + const SmartPtr<const Vector>& bound, + const SmartPtr<const Vector>& curr_point, + const SmartPtr<const Vector>& multiplier); + + /** Computes the indicator vectors that can be used to filter out + * those entries in the slack_... variables, that correspond to + * variables with only lower and upper bounds. This is required + * for the linear damping term in the barrier objective function + * to handle unbounded solution sets. */ + void ComputeDampingIndicators(SmartPtr<const Vector>& dampind_x_L, + SmartPtr<const Vector>& dampind_x_U, + SmartPtr<const Vector>& dampind_s_L, + SmartPtr<const Vector>& dampind_s_U); + + /** Check if we are in the restoration phase. Returns true, if the + * ip_nlp is of the type RestoIpoptNLP. ToDo: We probably want to + * handle this more elegant and don't have an explicit dependency + * here. Now I added this because otherwise the caching doesn't + * work properly since the restoration phase objective function + * depends on the current barrier parameter. */ + bool in_restoration_phase(); + + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIpoptData.hpp b/thirdparty/linux/include/coin1/IpIpoptData.hpp new file mode 100644 index 0000000..6973bab --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIpoptData.hpp @@ -0,0 +1,819 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptData.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTDATA_HPP__ +#define __IPIPOPTDATA_HPP__ + +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpIteratesVector.hpp" +#include "IpRegOptions.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /* Forward declaration */ + class IpoptNLP; + + /** Base class for additional data that is special to a particular + * type of algorithm, such as the CG penalty function, or using + * iterative linear solvers. The regular IpoptData object should + * be given a derivation of this base class when it is created. */ + class IpoptAdditionalData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IpoptAdditionalData() + {} + + /** Default destructor */ + virtual ~IpoptAdditionalData() + {} + //@} + + /** This method is called to initialize the global algorithmic + * parameters. The parameters are taken from the OptionsList + * object. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) = 0; + + /** Initialize Data Structures at the beginning. */ + virtual bool InitializeDataStructures() = 0; + + /** Do whatever is necessary to accept a trial point as current + * iterate. This is also used to finish an iteration, i.e., to + * release memory, and to reset any flags for a new iteration. */ + virtual void AcceptTrialPoint() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptAdditionalData(const IpoptAdditionalData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptAdditionalData&); + //@} + }; + + /** Class to organize all the data required by the algorithm. + * Internally, once this Data object has been initialized, all + * internal curr_ vectors must always be set (so that prototyes are + * available). The current values can only be set from the trial + * values. The trial values can be set by copying from a vector or + * by adding some fraction of a step to the current values. This + * object also stores steps, which allows to easily communicate the + * step from the step computation object to the line search object. + */ + class IpoptData : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + IpoptData(SmartPtr<IpoptAdditionalData> add_data = NULL, + Number cpu_time_start = -1.); + + /** Default destructor */ + virtual ~IpoptData(); + //@} + + /** Initialize Data Structures */ + bool InitializeDataStructures(IpoptNLP& ip_nlp, + bool want_x, + bool want_y_c, + bool want_y_d, + bool want_z_L, + bool want_z_U); + + /** This method must be called to initialize the global + * algorithmic parameters. The parameters are taken from the + * OptionsList object. */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** @name Get Methods for Iterates */ + //@{ + /** Current point */ + inline + SmartPtr<const IteratesVector> curr() const; + + /** Get the current point in a copied container that is non-const. + The entries in the container cannot be modified, but + the container can be modified to point to new entries. + */ + // SmartPtr<IteratesVector> curr_container() const; + + /** Get Trial point */ + inline + SmartPtr<const IteratesVector> trial() const; + + /** Get Trial point in a copied container that is non-const. + * The entries in the container can not be modified, but + * the container can be modified to point to new entries. + */ + //SmartPtr<IteratesVector> trial_container() const; + + /** Set the trial point - this method copies the pointer for + * efficiency (no copy and to keep cache tags the same) so + * after you call set you cannot modify the data again + */ + inline + void set_trial(SmartPtr<IteratesVector>& trial); + + /** Set the values of the primal trial variables (x and s) from + * provided Step with step length alpha. + */ + void SetTrialPrimalVariablesFromStep(Number alpha, + const Vector& delta_x, + const Vector& delta_s); + /** Set the values of the trial values for the equality constraint + * multipliers (y_c and y_d) from provided step with step length + * alpha. + */ + void SetTrialEqMultipliersFromStep(Number alpha, + const Vector& delta_y_c, + const Vector& delta_y_d); + /** Set the value of the trial values for the bound multipliers + * (z_L, z_U, v_L, v_U) from provided step with step length + * alpha. + */ + void SetTrialBoundMultipliersFromStep(Number alpha, + const Vector& delta_z_L, + const Vector& delta_z_U, + const Vector& delta_v_L, + const Vector& delta_v_U); + + /** ToDo: I may need to add versions of set_trial like the + * following, but I am not sure + */ + // void set_trial(const SmartPtr<IteratesVector>& trial_iterates); + // void set_trial(SmartPtr<const IteratesVector>& trial_iterates); + + /** get the current delta */ + inline + SmartPtr<const IteratesVector> delta() const; + + /** Set the current delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta(SmartPtr<IteratesVector>& delta); + + /** Set the current delta - like the trial point, this method + * copies the pointer for efficiency (no copy and to keep cache + * tags the same) so after you call set, you cannot modify the + * data. This is the version that is happy with a pointer to + * const IteratesVector. + */ + inline + void set_delta(SmartPtr<const IteratesVector>& delta); + + /** Affine Delta */ + inline + SmartPtr<const IteratesVector> delta_aff() const; + + /** Set the affine delta - like the trial point, this method copies + * the pointer for efficiency (no copy and to keep cache tags the + * same) so after you call set, you cannot modify the data + */ + inline + void set_delta_aff(SmartPtr<IteratesVector>& delta_aff); + + /** Hessian or Hessian approximation (do not hold on to it, it might be changed) */ + SmartPtr<const SymMatrix> W() + { + DBG_ASSERT(IsValid(W_)); + return W_; + } + + /** Set Hessian approximation */ + void Set_W(SmartPtr<const SymMatrix> W) + { + W_ = W; + } + + /** @name ("Main") Primal-dual search direction. Those fields are + * used to store the search directions computed from solving the + * primal-dual system, and can be used in the line search. They + * are overwritten in every iteration, so do not hold on to the + * pointers (make copies instead) */ + //@{ + + /** Returns true, if the primal-dual step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the IpoptAlgorithm object that it + * doesn't need to recompute the primal-dual step. */ + bool HaveDeltas() const + { + return have_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveDeltas(bool have_deltas) + { + have_deltas_ = have_deltas; + } + //@} + + /** @name Affine-scaling step. Those fields can be used to store + * the affine scaling step. For example, if the method for + * computing the current barrier parameter computes the affine + * scaling steps, then the corrector step in the line search does + * not have to recompute those solutions of the linear system. */ + //@{ + + /** Returns true, if the affine-scaling step have been already + * computed for the current iteration. This flag is reset after + * every call of AcceptTrialPoint(). If the search direction is + * computed during the computation of the barrier parameter, the + * method computing the barrier parameter should call + * SetHaveDeltas(true) to tell the line search does not have to + * recompute them in case it wants to do a corrector step. */ + bool HaveAffineDeltas() const + { + return have_affine_deltas_; + } + + /** Method for setting the HaveDeltas flag. This method should be + * called if some method computes the primal-dual step (and + * stores it in the delta_ fields of IpoptData) at an early part + * of the iteration. If that flag is set to true, the + * IpoptAlgorithm object will not recompute the step. */ + void SetHaveAffineDeltas(bool have_affine_deltas) + { + have_affine_deltas_ = have_affine_deltas; + } + //@} + + /** @name Public Methods for updating iterates */ + //@{ + /** Copy the trial values to the current values */ + inline + void CopyTrialToCurrent(); + + /** Set the current iterate values from the + * trial values. */ + void AcceptTrialPoint(); + //@} + + /** @name General algorithmic data */ + //@{ + Index iter_count() const + { + return iter_count_; + } + void Set_iter_count(Index iter_count) + { + iter_count_ = iter_count; + } + + Number curr_mu() const + { + DBG_ASSERT(mu_initialized_); + return curr_mu_; + } + void Set_mu(Number mu) + { + curr_mu_ = mu; + mu_initialized_ = true; + } + bool MuInitialized() const + { + return mu_initialized_; + } + + Number curr_tau() const + { + DBG_ASSERT(tau_initialized_); + return curr_tau_; + } + void Set_tau(Number tau) + { + curr_tau_ = tau; + tau_initialized_ = true; + } + bool TauInitialized() const + { + return tau_initialized_; + } + + void SetFreeMuMode(bool free_mu_mode) + { + free_mu_mode_ = free_mu_mode; + } + bool FreeMuMode() const + { + return free_mu_mode_; + } + + /** Setting the flag that indicates if a tiny step (below machine + * precision) has been detected */ + void Set_tiny_step_flag(bool flag) + { + tiny_step_flag_ = flag; + } + bool tiny_step_flag() + { + return tiny_step_flag_; + } + //@} + + /** Overall convergence tolerance. It is used in the convergence + * test, but also in some other parts of the algorithm that + * depend on the specified tolerance, such as the minimum value + * for the barrier parameter. */ + //@{ + /** Obtain the tolerance. */ + Number tol() const + { + DBG_ASSERT(initialize_called_); + return tol_; + } + /** Set a new value for the tolerance. One should be very careful + * when using this, since changing the predefined tolerance might + * have unexpected consequences. This method is for example used + * in the restoration convergence checker to tighten the + * restoration phase convergence tolerance, if the restoration + * phase converged to a point that has not a large value for the + * constraint violation. */ + void Set_tol(Number tol) + { + tol_ = tol; + } + //@} + + /** Cpu time counter at the beginning of the optimization. This + * is useful to see how much CPU time has been spent in this + * optimization run. */ + Number cpu_time_start() const + { + return cpu_time_start_; + } + + /** @name Information gathered for iteration output */ + //@{ + Number info_regu_x() const + { + return info_regu_x_; + } + void Set_info_regu_x(Number regu_x) + { + info_regu_x_ = regu_x; + } + Number info_alpha_primal() const + { + return info_alpha_primal_; + } + void Set_info_alpha_primal(Number alpha_primal) + { + info_alpha_primal_ = alpha_primal; + } + char info_alpha_primal_char() const + { + return info_alpha_primal_char_; + } + void Set_info_alpha_primal_char(char info_alpha_primal_char) + { + info_alpha_primal_char_ = info_alpha_primal_char; + } + Number info_alpha_dual() const + { + return info_alpha_dual_; + } + void Set_info_alpha_dual(Number alpha_dual) + { + info_alpha_dual_ = alpha_dual; + } + Index info_ls_count() const + { + return info_ls_count_; + } + void Set_info_ls_count(Index ls_count) + { + info_ls_count_ = ls_count; + } + bool info_skip_output() const + { + return info_skip_output_; + } + void Append_info_string(const std::string& add_str) + { + info_string_ += add_str; + } + const std::string& info_string() const + { + return info_string_; + } + /** Set this to true, if the next time when output is written, the + * summary line should not be printed. */ + void Set_info_skip_output(bool info_skip_output) + { + info_skip_output_ = info_skip_output; + } + + /** gives time when the last summary output line was printed */ + Number info_last_output() + { + return info_last_output_; + } + /** sets time when the last summary output line was printed */ + void Set_info_last_output(Number info_last_output) + { + info_last_output_ = info_last_output; + } + + /** gives number of iteration summaries actually printed + * since last summary header was printed */ + int info_iters_since_header() + { + return info_iters_since_header_; + } + /** increases number of iteration summaries actually printed + * since last summary header was printed */ + void Inc_info_iters_since_header() + { + info_iters_since_header_++; + } + /** sets number of iteration summaries actually printed + * since last summary header was printed */ + void Set_info_iters_since_header(int info_iters_since_header) + { + info_iters_since_header_ = info_iters_since_header; + } + + /** Reset all info fields */ + void ResetInfo() + { + info_regu_x_ = 0; + info_alpha_primal_ = 0; + info_alpha_dual_ = 0.; + info_alpha_primal_char_ = ' '; + info_skip_output_ = false; + info_string_.erase(); + } + //@} + + /** Return Timing Statistics Object */ + TimingStatistics& TimingStats() + { + return timing_statistics_; + } + + /** Check if additional data has been set */ + bool HaveAddData() + { + return IsValid(add_data_); + } + + /** Get access to additional data object */ + IpoptAdditionalData& AdditionalData() + { + return *add_data_; + } + + /** Set a new pointer for additional Ipopt data */ + void SetAddData(SmartPtr<IpoptAdditionalData> add_data) + { + DBG_ASSERT(!HaveAddData()); + add_data_ = add_data; + } + + /** Set the perturbation of the primal-dual system */ + void setPDPert(Number pd_pert_x, Number pd_pert_s, + Number pd_pert_c, Number pd_pert_d) + { + pd_pert_x_ = pd_pert_x; + pd_pert_s_ = pd_pert_s; + pd_pert_c_ = pd_pert_c; + pd_pert_d_ = pd_pert_d; + } + + /** Get the current perturbation of the primal-dual system */ + void getPDPert(Number& pd_pert_x, Number& pd_pert_s, + Number& pd_pert_c, Number& pd_pert_d) + { + pd_pert_x = pd_pert_x_; + pd_pert_s = pd_pert_s_; + pd_pert_c = pd_pert_c_; + pd_pert_d = pd_pert_d_; + } + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(const SmartPtr<RegisteredOptions>& roptions); + //@} + + private: + /** @name Iterates */ + //@{ + /** Main iteration variables + * (current iteration) */ + SmartPtr<const IteratesVector> curr_; + + /** Main iteration variables + * (trial calculations) */ + SmartPtr<const IteratesVector> trial_; + + /** Hessian (approximation) - might be changed elsewhere! */ + SmartPtr<const SymMatrix> W_; + + /** @name Primal-dual Step */ + //@{ + SmartPtr<const IteratesVector> delta_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the primal-dual search + * direction. This flag is reset when the AcceptTrialPoint + * method is called. + * ToDo: we could cue off of a null delta_; + */ + bool have_deltas_; + //@} + + /** @name Affine-scaling step. This used to transfer the + * information about the affine-scaling step from the computation + * of the barrier parameter to the corrector (in the line + * search). */ + //@{ + SmartPtr<const IteratesVector> delta_aff_; + /** The following flag is set to true, if some other part of the + * algorithm (like the method for computing the barrier + * parameter) has already computed the affine-scaling step. This + * flag is reset when the AcceptTrialPoint method is called. + * ToDo: we could cue off of a null delta_aff_; + */ + bool have_affine_deltas_; + //@} + + /** iteration count */ + Index iter_count_; + + /** current barrier parameter */ + Number curr_mu_; + bool mu_initialized_; + + /** current fraction to the boundary parameter */ + Number curr_tau_; + bool tau_initialized_; + + /** flag indicating if Initialize method has been called (for + * debugging) */ + bool initialize_called_; + + /** flag for debugging whether we have already curr_ values + * available (from which new Vectors can be generated */ + bool have_prototypes_; + + /** @name Global algorithm parameters. Those are options that can + * be modified by the user and appear at different places in the + * algorithm. They are set using an OptionsList object in the + * Initialize method. */ + //@{ + /** Overall convergence tolerance */ + Number tol_; + //@} + + /** @name Status data **/ + //@{ + /** flag indicating whether the algorithm is in the free mu mode */ + bool free_mu_mode_; + /** flag indicating if a tiny step has been detected */ + bool tiny_step_flag_; + //@} + + /** @name Gathered information for iteration output */ + //@{ + /** Size of regularization for the Hessian */ + Number info_regu_x_; + /** Primal step size */ + Number info_alpha_primal_; + /** Info character for primal step size */ + char info_alpha_primal_char_; + /** Dual step size */ + Number info_alpha_dual_; + /** Number of backtracking trial steps */ + Index info_ls_count_; + /** true, if next summary output line should not be printed (eg + * after restoration phase. */ + bool info_skip_output_; + /** any string of characters for the end of the output line */ + std::string info_string_; + /** time when the last summary output line was printed */ + Number info_last_output_; + /** number of iteration summaries actually printed since last + * summary header was printed */ + int info_iters_since_header_; + //@} + + /** VectorSpace for all the iterates */ + SmartPtr<IteratesVectorSpace> iterates_space_; + + /** TimingStatistics object collecting all Ipopt timing + * statistics */ + TimingStatistics timing_statistics_; + + /** CPU time counter at initialization. */ + Number cpu_time_start_; + + /** Object for the data specific for the Chen-Goldfarb penalty + * method algorithm */ + SmartPtr<IpoptAdditionalData> add_data_; + + /** @name Information about the perturbation of the primal-dual + * system */ + //@{ + Number pd_pert_x_; + Number pd_pert_s_; + Number pd_pert_c_; + Number pd_pert_d_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IpoptData(const IpoptData&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptData&); + //@} + +#if COIN_IPOPT_CHECKLEVEL > 0 + /** Some debug flags to make sure vectors are not changed + * behind the IpoptData's back + */ + //@{ + TaggedObject::Tag debug_curr_tag_; + TaggedObject::Tag debug_trial_tag_; + TaggedObject::Tag debug_delta_tag_; + TaggedObject::Tag debug_delta_aff_tag_; + TaggedObject::Tag debug_curr_tag_sum_; + TaggedObject::Tag debug_trial_tag_sum_; + TaggedObject::Tag debug_delta_tag_sum_; + TaggedObject::Tag debug_delta_aff_tag_sum_; + //@} +#endif + + }; + + inline + SmartPtr<const IteratesVector> IpoptData::curr() const + { + DBG_ASSERT(IsNull(curr_) || (curr_->GetTag() == debug_curr_tag_ && curr_->GetTagSum() == debug_curr_tag_sum_) ); + + return curr_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::trial() const + { + DBG_ASSERT(IsNull(trial_) || (trial_->GetTag() == debug_trial_tag_ && trial_->GetTagSum() == debug_trial_tag_sum_) ); + + return trial_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::delta() const + { + DBG_ASSERT(IsNull(delta_) || (delta_->GetTag() == debug_delta_tag_ && delta_->GetTagSum() == debug_delta_tag_sum_) ); + + return delta_; + } + + inline + SmartPtr<const IteratesVector> IpoptData::delta_aff() const + { + DBG_ASSERT(IsNull(delta_aff_) || (delta_aff_->GetTag() == debug_delta_aff_tag_ && delta_aff_->GetTagSum() == debug_delta_aff_tag_sum_) ); + + return delta_aff_; + } + + inline + void IpoptData::CopyTrialToCurrent() + { + curr_ = trial_; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(curr_)) { + debug_curr_tag_ = curr_->GetTag(); + debug_curr_tag_sum_ = curr_->GetTagSum(); + } + else { + debug_curr_tag_ = 0; + debug_curr_tag_sum_ = 0; + } +#endif + + } + + inline + void IpoptData::set_trial(SmartPtr<IteratesVector>& trial) + { + trial_ = ConstPtr(trial); + +#if COIN_IPOPT_CHECKLEVEL > 0 + // verify the correct space + DBG_ASSERT(trial_->OwnerSpace() == (VectorSpace*)GetRawPtr(iterates_space_)); + if (IsValid(trial)) { + debug_trial_tag_ = trial->GetTag(); + debug_trial_tag_sum_ = trial->GetTagSum(); + } + else { + debug_trial_tag_ = 0; + debug_trial_tag_sum_ = 0; + } +#endif + + trial = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr<IteratesVector>& delta) + { + delta_ = ConstPtr(delta); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta(SmartPtr<const IteratesVector>& delta) + { + delta_ = delta; +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta)) { + debug_delta_tag_ = delta->GetTag(); + debug_delta_tag_sum_ = delta->GetTagSum(); + } + else { + debug_delta_tag_ = 0; + debug_delta_tag_sum_ = 0; + } +#endif + + delta = NULL; + } + + inline + void IpoptData::set_delta_aff(SmartPtr<IteratesVector>& delta_aff) + { + delta_aff_ = ConstPtr(delta_aff); +#if COIN_IPOPT_CHECKLEVEL > 0 + + if (IsValid(delta_aff)) { + debug_delta_aff_tag_ = delta_aff->GetTag(); + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } + else { + debug_delta_aff_tag_ = 0; + debug_delta_aff_tag_sum_ = delta_aff->GetTagSum(); + } +#endif + + delta_aff = NULL; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIpoptNLP.hpp b/thirdparty/linux/include/coin1/IpIpoptNLP.hpp new file mode 100644 index 0000000..21951c3 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIpoptNLP.hpp @@ -0,0 +1,261 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPIPOPTNLP_HPP__ +#define __IPIPOPTNLP_HPP__ + +#include "IpNLP.hpp" +#include "IpJournalist.hpp" +#include "IpNLPScaling.hpp" + +namespace Ipopt +{ + // forward declarations + class IteratesVector; + + /** This is the abstract base class for classes that map + * the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles cacheing, + * and (some day) takes care of addition of slacks. + */ + class IpoptNLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + IpoptNLP(const SmartPtr<NLPScalingObject> nlp_scaling) + : + nlp_scaling_(nlp_scaling) + {} + + /** Default destructor */ + virtual ~IpoptNLP() + {} + //@} + + /** Initialization method. Set the internal options and + * initialize internal data structures. */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + bool ret = true; + if (IsValid(nlp_scaling_)) { + ret = nlp_scaling_->Initialize(jnlst, options, prefix); + } + return ret; + } + + /**@name Possible Exceptions */ + //@{ + /** thrown if there is any error evaluating values from the nlp */ + DECLARE_STD_EXCEPTION(Eval_Error); + //@} + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr<Vector>& x, + bool init_x, + SmartPtr<Vector>& y_c, + bool init_y_c, + SmartPtr<Vector>& y_d, + bool init_y_d, + SmartPtr<Vector>& z_L, + bool init_z_L, + SmartPtr<Vector>& z_U, + bool init_z_U, + SmartPtr<Vector>& v_L, + SmartPtr<Vector>& v_U + ) = 0; + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate)=0; + + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x) = 0; + + /** Gradient of the objective */ + virtual SmartPtr<const Vector> grad_f(const Vector& x) = 0; + + /** Equality constraint residual */ + virtual SmartPtr<const Vector> c(const Vector& x) = 0; + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr<const Matrix> jac_c(const Vector& x) = 0; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr<const Vector> d(const Vector& x) = 0; + + /** Jacobian Matrix for inequality constraints */ + virtual SmartPtr<const Matrix> jac_d(const Vector& x) = 0; + + /** Hessian of the Lagrangian */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ) = 0; + + /** Lower bounds on x */ + virtual SmartPtr<const Vector> x_L() const = 0; + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr<const Matrix> Px_L() const = 0; + + /** Upper bounds on x */ + virtual SmartPtr<const Vector> x_U() const = 0; + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr<const Matrix> Px_U() const = 0; + + /** Lower bounds on d */ + virtual SmartPtr<const Vector> d_L() const = 0; + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr<const Matrix> Pd_L() const = 0; + + /** Upper bounds on d */ + virtual SmartPtr<const Vector> d_U() const = 0; + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr<const Matrix> Pd_U() const = 0; + + /** x_space */ + virtual SmartPtr<const VectorSpace> x_space() const = 0; + + /** Accessor method to obtain the MatrixSpace for the Hessian + * matrix (or it's approximation) */ + virtual SmartPtr<const SymMatrixSpace> HessianMatrixSpace() const = 0; + //@} + + /** Accessor method for vector/matrix spaces pointers. */ + virtual void GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space) = 0; + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U)=0; + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const = 0; + virtual Index grad_f_evals() const = 0; + virtual Index c_evals() const = 0; + virtual Index jac_c_evals() const = 0; + virtual Index d_evals() const = 0; + virtual Index jac_d_evals() const = 0; + virtual Index h_evals() const = 0; + //@} + + /** @name Special method for dealing with the fact that the + * restoration phase objective function depends on the barrier + * parameter */ + //@{ + /** Method for telling the IpoptCalculatedQuantities class whether + * the objective function depends on the barrier function. This + * is only used for the restoration phase NLP + * formulation. Probably only RestoIpoptNLP should overwrite + * this. */ + virtual bool objective_depends_on_mu() const + { + return false; + } + + /** Replacement for the default objective function method which + * knows about the barrier parameter */ + virtual Number f(const Vector& x, Number mu) = 0; + + /** Replacement for the default objective gradient method which + * knows about the barrier parameter */ + virtual SmartPtr<const Vector> grad_f(const Vector& x, Number mu) = 0; + + /** Replacement for the default Lagrangian Hessian method which + * knows about the barrier parameter */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu) = 0; + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr<const SymMatrix> uninitialized_h() = 0; + //@} + + /**@name solution routines */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq)=0; + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr<const IpoptData> ip_data, + SmartPtr<IpoptCalculatedQuantities> ip_cq)=0; + //@} + + /** Returns the scaling strategy object */ + SmartPtr<NLPScalingObject> NLP_scaling() const + { + DBG_ASSERT(IsValid(nlp_scaling_)); + return nlp_scaling_; + } + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + IpoptNLP(const IpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const IpoptNLP&); + //@} + + SmartPtr<NLPScalingObject> nlp_scaling_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIterateInitializer.hpp b/thirdparty/linux/include/coin1/IpIterateInitializer.hpp new file mode 100644 index 0000000..d179651 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIterateInitializer.hpp @@ -0,0 +1,64 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterateInitializer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-09-24 + +#ifndef __IPITERATEINITIALIZER_HPP__ +#define __IPITERATEINITIALIZER_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for all methods for initializing the iterates. + */ + class IterateInitializer: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterateInitializer() + {} + + /** Default destructor */ + virtual ~IterateInitializer() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Compute the initial iterates and set the into the curr field + * of the ip_data object. */ + virtual bool SetInitialIterates() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterateInitializer(const IterateInitializer&); + + /** Overloaded Equals Operator */ + void operator=(const IterateInitializer&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIteratesVector.hpp b/thirdparty/linux/include/coin1/IpIteratesVector.hpp new file mode 100644 index 0000000..2ed7580 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIteratesVector.hpp @@ -0,0 +1,689 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIteratesVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-06-06 + +#ifndef __IPITERATESVECTOR_HPP__ +#define __IPITERATESVECTOR_HPP__ + +#include "IpCompoundVector.hpp" + +namespace Ipopt +{ + /* forward declarations */ + class IteratesVectorSpace; + + /** Specialized CompoundVector class specifically for the algorithm + * iterates. This class inherits from CompoundVector and is a + * specialized class for handling the iterates of the Ipopt + * Algorithm, that is, x, s, y_c, y_d, z_L, z_U, v_L, and v_U. It + * inherits from CompoundVector so it can behave like a CV in most + * calculations, but it has fixed dimensions and cannot be + * customized + */ + class IteratesVector : public CompoundVector + { + public: + /** Constructors / Destructors */ + //@{ + IteratesVector(const IteratesVectorSpace* owner_space, bool create_new); + + virtual ~IteratesVector(); + //@} + + /** Make New methods */ + //@{ + /** Use this method to create a new iterates vector. The MakeNew + * method on the Vector class also works, but it does not give + * the create_new option. + */ + SmartPtr<IteratesVector> MakeNewIteratesVector(bool create_new = true) const; + + /** Use this method to create a new iterates vector with a copy of + * all the data. + */ + SmartPtr<IteratesVector> MakeNewIteratesVectorCopy() const + { + SmartPtr<IteratesVector> ret = MakeNewIteratesVector(true); + ret->Copy(*this); + return ret; + } + + /** Use this method to create a new iterates vector + * container. This creates a new NonConst container, but the + * elements inside the iterates vector may be const. Therefore, + * the container can be modified to point to new entries, but the + * existing entries may or may not be modifiable. + */ + SmartPtr<IteratesVector> MakeNewContainer() const; + //@} + + /** Iterates Set/Get Methods */ + //@{ + /** Get the x iterate (const) */ + SmartPtr<const Vector> x() const + { + return GetIterateFromComp(0); + } + + /** Get the x iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_x_NonConst method was + * used. */ + SmartPtr<Vector> x_NonConst() + { + return GetNonConstIterateFromComp(0); + } + + /** Create a new vector in the x entry */ + inline + SmartPtr<Vector> create_new_x(); + + /** Create a new vector in the x entry and copy the current values + * into it. */ + SmartPtr<Vector> create_new_x_copy() + { + SmartPtr<const Vector> curr_x = GetComp(0); + Set_x_NonConst(*curr_x->MakeNew()); + x_NonConst()->Copy(*curr_x); + return x_NonConst(); + } + + /** Set the x iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_x(const Vector& vec) + { + SetComp(0, vec); + } + + /** Set the x iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_x_NonConst(Vector& vec) + { + SetCompNonConst(0, vec); + } + + /** Get the s iterate (const) */ + SmartPtr<const Vector> s() const + { + return GetIterateFromComp(1); + } + + /** Get the s iterate (non-const) - this can only be called if the + * vector was created intenally, or the Set_s_NonConst method was + * used. */ + SmartPtr<Vector> s_NonConst() + { + return GetNonConstIterateFromComp(1); + } + + /** Create a new vector in the s entry */ + inline + SmartPtr<Vector> create_new_s(); + + /** Create a new vector in the s entry and copy the current values + * into it. */ + SmartPtr<Vector> create_new_s_copy() + { + SmartPtr<const Vector> curr_s = GetComp(1); + Set_s_NonConst(*curr_s->MakeNew()); + s_NonConst()->Copy(*curr_s); + return s_NonConst(); + } + + /** Set the s iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_s(const Vector& vec) + { + SetComp(1, vec); + } + + /** Set the s iterate (non-const). Sets the pointer, does NOT copy + * data. */ + void Set_s_NonConst(Vector& vec) + { + SetCompNonConst(1, vec); + } + + /** Get the y_c iterate (const) */ + SmartPtr<const Vector> y_c() const + { + return GetIterateFromComp(2); + } + + /** Get the y_c iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_c_NonConst + * method was used. */ + SmartPtr<Vector> y_c_NonConst() + { + return GetNonConstIterateFromComp(2); + } + + /** Create a new vector in the y_c entry */ + inline + SmartPtr<Vector> create_new_y_c(); + + /** Create a new vector in the y_c entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_y_c_copy() + { + SmartPtr<const Vector> curr_y_c = GetComp(2); + Set_y_c_NonConst(*curr_y_c->MakeNew()); + y_c_NonConst()->Copy(*curr_y_c); + return y_c_NonConst(); + } + + /** Set the y_c iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_c(const Vector& vec) + { + SetComp(2, vec); + } + + /** Set the y_c iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_c_NonConst(Vector& vec) + { + SetCompNonConst(2, vec); + } + + /** Get the y_d iterate (const) */ + SmartPtr<const Vector> y_d() const + { + return GetIterateFromComp(3); + } + + /** Get the y_d iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_y_d_NonConst + * method was used. */ + SmartPtr<Vector> y_d_NonConst() + { + return GetNonConstIterateFromComp(3); + } + + /** Create a new vector in the y_d entry */ + inline + SmartPtr<Vector> create_new_y_d(); + + /** Create a new vector in the y_d entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_y_d_copy() + { + SmartPtr<const Vector> curr_y_d = GetComp(3); + Set_y_d_NonConst(*curr_y_d->MakeNew()); + y_d_NonConst()->Copy(*curr_y_d); + return y_d_NonConst(); + } + + /** Set the y_d iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_y_d(const Vector& vec) + { + SetComp(3, vec); + } + + /** Set the y_d iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_y_d_NonConst(Vector& vec) + { + SetCompNonConst(3, vec); + } + + /** Get the z_L iterate (const) */ + SmartPtr<const Vector> z_L() const + { + return GetIterateFromComp(4); + } + + /** Get the z_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_L_NonConst + * method was used. */ + SmartPtr<Vector> z_L_NonConst() + { + return GetNonConstIterateFromComp(4); + } + + /** Create a new vector in the z_L entry */ + inline + SmartPtr<Vector> create_new_z_L(); + + /** Create a new vector in the z_L entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_z_L_copy() + { + SmartPtr<const Vector> curr_z_L = GetComp(4); + Set_z_L_NonConst(*curr_z_L->MakeNew()); + z_L_NonConst()->Copy(*curr_z_L); + return z_L_NonConst(); + } + + /** Set the z_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_L(const Vector& vec) + { + SetComp(4, vec); + } + + /** Set the z_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_L_NonConst(Vector& vec) + { + SetCompNonConst(4, vec); + } + + /** Get the z_U iterate (const) */ + SmartPtr<const Vector> z_U() const + { + return GetIterateFromComp(5); + } + + /** Get the z_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_z_U_NonConst + * method was used. */ + SmartPtr<Vector> z_U_NonConst() + { + return GetNonConstIterateFromComp(5); + } + + /** Create a new vector in the z_U entry */ + inline + SmartPtr<Vector> create_new_z_U(); + + /** Create a new vector in the z_U entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_z_U_copy() + { + SmartPtr<const Vector> curr_z_U = GetComp(5); + Set_z_U_NonConst(*curr_z_U->MakeNew()); + z_U_NonConst()->Copy(*curr_z_U); + return z_U_NonConst(); + } + + /** Set the z_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_z_U(const Vector& vec) + { + SetComp(5, vec); + } + + /** Set the z_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_z_U_NonConst(Vector& vec) + { + SetCompNonConst(5, vec); + } + + /** Get the v_L iterate (const) */ + SmartPtr<const Vector> v_L() const + { + return GetIterateFromComp(6); + } + + /** Get the v_L iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_L_NonConst + * method was used. */ + SmartPtr<Vector> v_L_NonConst() + { + return GetNonConstIterateFromComp(6); + } + + /** Create a new vector in the v_L entry */ + inline + SmartPtr<Vector> create_new_v_L(); + + /** Create a new vector in the v_L entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_v_L_copy() + { + SmartPtr<const Vector> curr_v_L = GetComp(6); + Set_v_L_NonConst(*curr_v_L->MakeNew()); + v_L_NonConst()->Copy(*curr_v_L); + return v_L_NonConst(); + } + + /** Set the v_L iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_L(const Vector& vec) + { + SetComp(6, vec); + } + + /** Set the v_L iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_L_NonConst(Vector& vec) + { + SetCompNonConst(6, vec); + } + + /** Get the v_U iterate (const) */ + SmartPtr<const Vector> v_U() const + { + return GetIterateFromComp(7); + } + + /** Get the v_U iterate (non-const) - this can only be called if + * the vector was created intenally, or the Set_v_U_NonConst + * method was used. */ + SmartPtr<Vector> v_U_NonConst() + { + return GetNonConstIterateFromComp(7); + } + + /** Create a new vector in the v_U entry */ + inline + SmartPtr<Vector> create_new_v_U(); + + /** Create a new vector in the v_U entry and copy the current + * values into it. */ + SmartPtr<Vector> create_new_v_U_copy() + { + SmartPtr<const Vector> curr_v_U = GetComp(7); + Set_v_U_NonConst(*curr_v_U->MakeNew()); + v_U_NonConst()->Copy(*curr_v_U); + return v_U_NonConst(); + } + + /** Set the v_U iterate (const). Sets the pointer, does NOT copy + * data. */ + void Set_v_U(const Vector& vec) + { + SetComp(7, vec); + } + + /** Set the v_U iterate (non-const). Sets the pointer, does NOT + * copy data. */ + void Set_v_U_NonConst(Vector& vec) + { + SetCompNonConst(7, vec); + } + + /** Set the primal variables all in one shot. Sets the pointers, + * does NOT copy data */ + void Set_primal(const Vector& x, const Vector& s) + { + SetComp(0, x); + SetComp(1, s); + } + void Set_primal_NonConst(Vector& x, Vector& s) + { + SetCompNonConst(0, x); + SetCompNonConst(1, s); + } + + /** Set the eq multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_eq_mult(const Vector& y_c, const Vector& y_d) + { + SetComp(2, y_c); + SetComp(3, y_d); + } + void Set_eq_mult_NonConst(Vector& y_c, Vector& y_d) + { + SetCompNonConst(2, y_c); + SetCompNonConst(3, y_d); + } + + /** Set the bound multipliers all in one shot. Sets the pointers, + * does not copy data. */ + void Set_bound_mult(const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U) + { + SetComp(4, z_L); + SetComp(5, z_U); + SetComp(6, v_L); + SetComp(7, v_U); + } + void Set_bound_mult_NonConst(Vector& z_L, Vector& z_U, Vector& v_L, Vector& v_U) + { + SetCompNonConst(4, z_L); + SetCompNonConst(5, z_U); + SetCompNonConst(6, v_L); + SetCompNonConst(7, v_U); + } + + /** Get a sum of the tags of the contained items. There is no + * guarantee that this is unique, but there is a high chance it + * is unique and it can be used for debug checks relatively + * reliably. + */ + TaggedObject::Tag GetTagSum() const + { + TaggedObject::Tag tag = 0; + + if (IsValid(x())) { + tag += x()->GetTag(); + } + if (IsValid(s())) { + tag += s()->GetTag(); + } + if (IsValid(y_c())) { + tag += y_c()->GetTag(); + } + if (IsValid(y_d())) { + tag += y_d()->GetTag(); + } + if (IsValid(z_L())) { + tag += z_L()->GetTag(); + } + if (IsValid(z_U())) { + tag += z_U()->GetTag(); + } + if (IsValid(v_L())) { + tag += v_L()->GetTag(); + } + if (IsValid(v_U())) { + tag += v_U()->GetTag(); + } + + return tag; + } + //@} + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. + */ + //@{ + /** Default Constructor */ + IteratesVector(); + + /** Copy Constructor */ + IteratesVector(const IteratesVector&); + + /** Overloaded Equals Operator */ + void operator=(const IteratesVector&); + //@} + + const IteratesVectorSpace* owner_space_; + + /** private method to return the const element from the compound + * vector. This method will return NULL if none is currently + * set. + */ + SmartPtr<const Vector> GetIterateFromComp(Index i) const + { + if (IsCompNull(i)) { + return NULL; + } + return GetComp(i); + } + + /** private method to return the non-const element from the + * compound vector. This method will return NULL if none is + * currently set. + */ + SmartPtr<Vector> GetNonConstIterateFromComp(Index i) + { + if (IsCompNull(i)) { + return NULL; + } + return GetCompNonConst(i); + } + + }; + + /** Vector Space for the IteratesVector class. This is a + * specialized vector space for the IteratesVector class. + */ + class IteratesVectorSpace : public CompoundVectorSpace + { + public: + /** @name Constructors/Destructors. */ + //@{ + /** Constructor that takes the spaces for each of the iterates. + * Warning! None of these can be NULL ! + */ + IteratesVectorSpace(const VectorSpace& x_space, const VectorSpace& s_space, + const VectorSpace& y_c_space, const VectorSpace& y_d_space, + const VectorSpace& z_L_space, const VectorSpace& z_U_space, + const VectorSpace& v_L_space, const VectorSpace& v_U_space + ); + + virtual ~IteratesVectorSpace(); + //@} + + /** Method for creating vectors . */ + //@{ + /** Use this to create a new IteratesVector. You can pass-in + * create_new = false if you only want a container and do not + * want vectors allocated. + */ + virtual IteratesVector* MakeNewIteratesVector(bool create_new = true) const + { + return new IteratesVector(this, create_new); + } + + /** Use this method to create a new const IteratesVector. You must pass in + * valid pointers for all of the entries. + */ + const SmartPtr<const IteratesVector> MakeNewIteratesVector(const Vector& x, const Vector& s, + const Vector& y_c, const Vector& y_d, + const Vector& z_L, const Vector& z_U, + const Vector& v_L, const Vector& v_U) + { + SmartPtr<IteratesVector> newvec = MakeNewIteratesVector(false); + newvec->Set_x(x); + newvec->Set_s(s); + newvec->Set_y_c(y_c); + newvec->Set_y_d(y_d); + newvec->Set_z_L(z_L); + newvec->Set_z_U(z_U); + newvec->Set_v_L(v_L); + newvec->Set_v_U(v_U); + return ConstPtr(newvec); + } + + + /** This method overloads + * ComooundVectorSpace::MakeNewCompoundVector to make sure that + * we get a vector of the correct type + */ + virtual CompoundVector* MakeNewCompoundVector(bool create_new = true) const + { + return MakeNewIteratesVector(create_new); + } + + /** This method creates a new vector (and allocates space in all + * the contained vectors. This is really only used for code that + * does not know what type of vector it is dealing with - for + * example, this method is called from Vector::MakeNew() + */ + virtual Vector* MakeNew() const + { + return MakeNewIteratesVector(); + } + //@} + + /** This method hides the CompoundVectorSpace::SetCompSpace method + * since the components of the Iterates are fixed at + * construction. + */ + virtual void SetCompSpace(Index icomp, const VectorSpace& vec_space) + { + DBG_ASSERT(false && "This is an IteratesVectorSpace - a special compound vector for Ipopt iterates. The contained spaces should not be modified."); + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + IteratesVectorSpace(); + + /** Copy Constructor */ + IteratesVectorSpace(const IteratesVectorSpace&); + + /** Overloaded Equals Operator */ + IteratesVectorSpace& operator=(const IteratesVectorSpace&); + //@} + + /** Contained Spaces */ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> s_space_; + SmartPtr<const VectorSpace> y_c_space_; + SmartPtr<const VectorSpace> y_d_space_; + SmartPtr<const VectorSpace> z_L_space_; + SmartPtr<const VectorSpace> z_U_space_; + SmartPtr<const VectorSpace> v_L_space_; + SmartPtr<const VectorSpace> v_U_space_; + }; + + + inline + SmartPtr<Vector> IteratesVector::create_new_x() + { + Set_x_NonConst(*owner_space_->GetCompSpace(0)->MakeNew()); + return x_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_s() + { + Set_s_NonConst(*owner_space_->GetCompSpace(1)->MakeNew()); + return s_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_y_c() + { + Set_y_c_NonConst(*owner_space_->GetCompSpace(2)->MakeNew()); + return y_c_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_y_d() + { + Set_y_d_NonConst(*owner_space_->GetCompSpace(3)->MakeNew()); + return y_d_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_z_L() + { + Set_z_L_NonConst(*owner_space_->GetCompSpace(4)->MakeNew()); + return z_L_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_z_U() + { + Set_z_U_NonConst(*owner_space_->GetCompSpace(5)->MakeNew()); + return z_U_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_v_L() + { + Set_v_L_NonConst(*owner_space_->GetCompSpace(6)->MakeNew()); + return v_L_NonConst(); + } + inline + SmartPtr<Vector> IteratesVector::create_new_v_U() + { + Set_v_U_NonConst(*owner_space_->GetCompSpace(7)->MakeNew()); + return v_U_NonConst(); + } +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpIterationOutput.hpp b/thirdparty/linux/include/coin1/IpIterationOutput.hpp new file mode 100644 index 0000000..95fd650 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpIterationOutput.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpIterationOutput.hpp 2020 2011-06-16 20:46:16Z andreasw $ +// +// Authors: Andreas Waechter, Carl Laird IBM 2004-09-27 + +#ifndef __IPITERATIONOUTPUT_HPP__ +#define __IPITERATIONOUTPUT_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptNLP.hpp" +#include "IpIpoptData.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for objects that do the output summary per iteration. + */ + class IterationOutput: public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + IterationOutput() + {} + + /** Default destructor */ + virtual ~IterationOutput() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method to do all the summary output per iteration. This + * include the one-line summary output as well as writing the + * details about the iterates if desired */ + virtual void WriteOutput() = 0; + + protected: + /** enumeration for different inf_pr output options */ + enum InfPrOutput + { + INTERNAL=0, + ORIGINAL + }; + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + IterationOutput(const IterationOutput&); + + /** Overloaded Equals Operator */ + void operator=(const IterationOutput&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpJournalist.hpp b/thirdparty/linux/include/coin1/IpJournalist.hpp new file mode 100644 index 0000000..266130a --- /dev/null +++ b/thirdparty/linux/include/coin1/IpJournalist.hpp @@ -0,0 +1,497 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpJournalist.hpp 2204 2013-04-13 13:49:26Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPJOURNALIST_HPP__ +#define __IPJOURNALIST_HPP__ + +#include "IpoptConfig.h" +#include "IpTypes.hpp" +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +#ifdef HAVE_CSTDARG +# include <cstdarg> +#else +# ifdef HAVE_STDARG_H +# include <stdarg.h> +# else +# include <cstdarg> // if this header is included by someone who does not define HAVE_CSTDARG or HAVE_STDARG, let's hope that cstdarg is available +# endif +#endif + +#ifdef HAVE_CSTDIO +# include <cstdio> +#else +# ifdef HAVE_STDIO_H +# include <stdio.h> +# else +# include <cstdio> // if this header is included by someone who does not define HAVE_CSTDIO or HAVE_STDIO, let's hope that cstdio is available +# endif +#endif + +#include <string> +#include <vector> +#include <ostream> + +namespace Ipopt +{ + + // forward declarations + class Journal; + class FileJournal; + + /**@name Journalist Enumerations. */ + //@{ + /** Print Level Enum. */ + enum EJournalLevel { + J_INSUPPRESSIBLE=-1, + J_NONE=0, + J_ERROR, + J_STRONGWARNING, + J_SUMMARY, + J_WARNING, + J_ITERSUMMARY, + J_DETAILED, + J_MOREDETAILED, + J_VECTOR, + J_MOREVECTOR, + J_MATRIX, + J_MOREMATRIX, + J_ALL, + J_LAST_LEVEL + }; + + /** Category Selection Enum. */ + enum EJournalCategory { + J_DBG=0, + J_STATISTICS, + J_MAIN, + J_INITIALIZATION, + J_BARRIER_UPDATE, + J_SOLVE_PD_SYSTEM, + J_FRAC_TO_BOUND, + J_LINEAR_ALGEBRA, + J_LINE_SEARCH, + J_HESSIAN_APPROXIMATION, + J_SOLUTION, + J_DOCUMENTATION, + J_NLP, + J_TIMING_STATISTICS, + J_USER_APPLICATION /** This can be used by the user's application*/ , + J_USER1 /** This can be used by the user's application*/ , + J_USER2 /** This can be used by the user's application*/ , + J_USER3 /** This can be used by the user's application*/ , + J_USER4 /** This can be used by the user's application*/ , + J_USER5 /** This can be used by the user's application*/ , + J_USER6 /** This can be used by the user's application*/ , + J_USER7 /** This can be used by the user's application*/ , + J_USER8 /** This can be used by the user's application*/ , + J_USER9 /** This can be used by the user's application*/ , + J_USER10 /** This can be used by the user's application*/ , + J_USER11 /** This can be used by the user's application*/ , + J_USER12 /** This can be used by the user's application*/ , + J_USER13 /** This can be used by the user's application*/ , + J_USER14 /** This can be used by the user's application*/ , + J_USER15 /** This can be used by the user's application*/ , + J_USER16 /** This can be used by the user's application*/ , + J_USER17 /** This can be used by the user's application*/ , + J_LAST_CATEGORY + }; + //@} + + /** Class responsible for all message output. + * This class is responsible for all messaging and output. + * The "printing" code or "author" should send ALL messages to the + * Journalist, indicating an appropriate category and print level. + * The journalist then decides, based on reader specified + * acceptance criteria, which message is actually printed in which + * journals. + * This allows the printing code to send everything, while the + * "reader" can decide what they really want to see. + * + * Authors: + * Authors use the + * Journals: You can add as many Journals as you like to the + * Journalist with the AddJournal or the AddFileJournal methods. + * Each one represents a different printing location (or file). + * Then, you can call the "print" methods of the Journalist to output + * information to each of the journals. + * + * Acceptance Criteria: Each print message should be flagged + * appropriately with an EJournalCategory and EJournalLevel. + * + * The AddFileJournal + * method returns a pointer to the newly created Journal object + * (if successful) so you can set Acceptance criteria for that + * particular location. + * + */ + class Journalist : public ReferencedObject + { + public: + /**@name Constructor / Desructor. */ + //@{ + /** Constructor. */ + Journalist(); + + /** Destructor... */ + virtual ~Journalist(); + //@} + + /**@name Author Methods. + * These methods are used by authoring code, or code that wants + * to report some information. + */ + //@{ + /** Method to print a formatted string */ + virtual void Printf(EJournalLevel level, EJournalCategory category, + const char* format, ...) const; + + /** Method to print a long string including indentation. The + * string is printed starting at the current position. If the + * position (counting started at the current position) exceeds + * max_length, a new line is inserted, and indent_spaces many + * spaces are printed before the string is continued. This is + * for example used during the printing of the option + * documentation. */ + virtual void PrintStringOverLines(EJournalLevel level, EJournalCategory category, + Index indent_spaces, Index max_length, + const std::string& line) const; + + /** Method to print a formatted string with indentation */ + virtual void PrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* format, ...) const; + + /** Method to print a formatted string + * using the va_list argument. */ + virtual void VPrintf(EJournalLevel level, + EJournalCategory category, + const char* pformat, + va_list ap) const; + + /** Method to print a formatted string with indentation, + * using the va_list argument. */ + virtual void VPrintfIndented(EJournalLevel level, + EJournalCategory category, + Index indent_level, + const char* pformat, + va_list ap) const; + + /** Method that returns true if there is a Journal that would + * write output for the given JournalLevel and JournalCategory. + * This is useful if expensive computation would be required for + * a particular output. The author code can check with this + * method if the computations are indeed required. + */ + virtual bool ProduceOutput(EJournalLevel level, + EJournalCategory category) const; + + + /** Method that flushes the current buffer for all Journalists. + Calling this method after one optimization run helps to avoid + cluttering output with that produced by other parts of the + program (e.g. written in Fortran) */ + virtual void FlushBuffer() const; + //@} + + /**@name Reader Methods. + * These methods are used by the reader. The reader will setup the + * journalist with each output file and the acceptance + * criteria for that file. + * + * Use these methods to setup the journals (files or other output). + * These are the internal objects that keep track of the print levels + * for each category. Then use the internal Journal objects to + * set specific print levels for each category (or keep defaults). + * + */ + //@{ + /** Add a new journal. The location_name is a string identifier, + * which can be used to obtain the pointer to the new Journal at + * a later point using the GetJournal method. + * The default_level is + * used to initialize the * printing level for all categories. + */ + virtual bool AddJournal(const SmartPtr<Journal> jrnl); + + /** Add a new FileJournal. fname is the name + * of the * file to which this Journal corresponds. Use + * fname="stdout" * for stdout, and use fname="stderr" for + * stderr. This method * returns the Journal pointer so you can + * set specific acceptance criteria. It returns NULL if there + * was a problem creating a new Journal. + */ + virtual SmartPtr<Journal> AddFileJournal( + const std::string& location_name, /**< journal identifier */ + const std::string& fname, /**< file name */ + EJournalLevel default_level = J_WARNING /**< default journal level */ + ); + + /** Get an existing journal. You can use this method to change + * the acceptance criteria at runtime. + */ + virtual SmartPtr<Journal> GetJournal(const std::string& location_name); + + /** Delete all journals curently known by the journalist. */ + virtual void DeleteAllJournals(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Journalist(const Journalist&); + + /** Overloaded Equals Operator */ + void operator=(const Journalist&); + //@} + + //** Private Data Members. */ + //@{ + std::vector< SmartPtr<Journal> > journals_; + //@} + }; + + /** Journal class (part of the Journalist implementation.). This + * class is the base class for all Journals. It controls the + * acceptance criteria for print statements etc. Derived classes + * like the FileJournal - output those messages to specific locations + */ + class Journal : public ReferencedObject + { + public: + /** Constructor. */ + Journal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~Journal(); + + /** Get the name of the Journal */ + virtual std::string Name(); + + /** Set the print level for a particular category. */ + virtual void SetPrintLevel( + EJournalCategory category, EJournalLevel level + ); + + /** Set the print level for all category. */ + virtual void SetAllPrintLevels( + EJournalLevel level + ); + + /**@name Journal Output Methods. These methods are called by the + * Journalist who first checks if the output print level and category + * are acceptable. + * Calling the Print methods explicitly (instead of through the + * Journalist will output the message regardless of print level + * and category. You should use the Journalist to print & flush instead + */ + //@{ + /** Ask if a particular print level/category is accepted by the + * journal. + */ + virtual bool IsAccepted( + EJournalCategory category, EJournalLevel level + ) const; + + /** Print to the designated output location */ + virtual void Print(EJournalCategory category, EJournalLevel level, + const char* str) + { + PrintImpl(category, level, str); + } + + /** Printf to the designated output location */ + virtual void Printf(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap) + { + PrintfImpl(category, level, pformat, ap); + } + + /** Flush output buffer.*/ + virtual void FlushBuffer() + { + FlushBufferImpl(); + } + //@} + + protected: + /**@name Implementation version of Print methods. Derived classes + * should overload the Impl methods. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str)=0; + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap)=0; + + /** Flush output buffer.*/ + virtual void FlushBufferImpl()=0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + Journal(); + + /** Copy Constructor */ + Journal(const Journal&); + + /** Overloaded Equals Operator */ + void operator=(const Journal&); + //@} + + /** Name of the output location */ + std::string name_; + + /** vector of integers indicating the level for each category */ + Index print_levels_[J_LAST_CATEGORY]; + }; + + + /** FileJournal class. This is a particular Journal implementation that + * writes to a file for output. It can write to (stdout, stderr, or disk) + * by using "stdout" and "stderr" as filenames. + */ + class FileJournal : public Journal + { + public: + /** Constructor. */ + FileJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~FileJournal(); + + /** Open a new file for the output location. + * Special Names: stdout means stdout, + * : stderr means stderr. + * + * Return code is false only if the file with the given name + * could not be opened. + */ + virtual bool Open(const char* fname); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + FileJournal(); + + /** Copy Constructor */ + FileJournal(const FileJournal&); + + /** Overloaded Equals Operator */ + void operator=(const FileJournal&); + //@} + + /** FILE pointer for the output destination */ + FILE* file_; + }; + + /** StreamJournal class. This is a particular Journal implementation that + * writes to a stream for output. + */ + class StreamJournal : public Journal + { + public: + /** Constructor. */ + StreamJournal(const std::string& name, EJournalLevel default_level); + + /** Destructor. */ + virtual ~StreamJournal() + {} + + /** Setting the output stream pointer */ + void SetOutputStream(std::ostream* os); + + protected: + /**@name Implementation version of Print methods - Overloaded from + * Journal base class. + */ + //@{ + /** Print to the designated output location */ + virtual void PrintImpl(EJournalCategory category, EJournalLevel level, + const char* str); + + /** Printf to the designated output location */ + virtual void PrintfImpl(EJournalCategory category, EJournalLevel level, + const char* pformat, va_list ap); + + /** Flush output buffer.*/ + virtual void FlushBufferImpl(); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + StreamJournal(); + + /** Copy Constructor */ + StreamJournal(const StreamJournal&); + + /** Overloaded Equals Operator */ + void operator=(const StreamJournal&); + //@} + + /** pointer to output stream for the output destination */ + std::ostream* os_; + + /** buffer for sprintf. Being generous in size here... */ + char buffer_[32768]; + }; +} + +#endif diff --git a/thirdparty/linux/include/coin1/IpLapack.hpp b/thirdparty/linux/include/coin1/IpLapack.hpp new file mode 100644 index 0000000..ef8883c --- /dev/null +++ b/thirdparty/linux/include/coin1/IpLapack.hpp @@ -0,0 +1,55 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLapack.hpp 2449 2013-12-16 00:25:42Z ghackebeil $ +// +// Authors: Andreas Waechter IBM 2005-12-25 + +#ifndef __IPLAPACK_HPP__ +#define __IPLAPACK_HPP__ + +#include "IpUtils.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + DECLARE_STD_EXCEPTION(LAPACK_NOT_INCLUDED); + + /** Wrapper for LAPACK subroutine DPOTRS. Solving a linear system + * given a Cholesky factorization. We assume that the Cholesky + * factor is lower traiangular. */ + void IpLapackDpotrs(Index ndim, Index nrhs, const Number *a, Index lda, + Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPOTRF. Compute Cholesky + * factorization (lower triangular factor). info is the return + * value from the LAPACK routine. */ + void IpLapackDpotrf(Index ndim, Number *a, Index lda, Index& info); + + /** Wrapper for LAPACK subroutine DSYEV. Compute the Eigenvalue + * decomposition for a given matrix. If compute_eigenvectors is + * true, a will contain the eigenvectors in its columns on + * return. */ + void IpLapackDsyev(bool compute_eigenvectors, Index ndim, Number *a, + Index lda, Number *w, Index& info); + + /** Wrapper for LAPACK subroutine DGETRF. Compute LU factorization. + * info is the return value from the LAPACK routine. */ + void IpLapackDgetrf(Index ndim, Number *a, Index* pivot, Index lda, + Index& info); + + /** Wrapper for LAPACK subroutine DGETRS. Solving a linear system + * given a LU factorization. */ + void IpLapackDgetrs(Index ndim, Index nrhs, const Number *a, Index lda, + Index* ipiv, Number *b, Index ldb); + + /** Wrapper for LAPACK subroutine DPPSV. Solves a symmetric positive + * definite linear system in packed storage format (upper triangular). + * info is the return value from the LAPACK routine. */ + void IpLapackDppsv(Index ndim, Index nrhs, const Number *a, + Number *b, Index ldb, Index& info); + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpLineSearch.hpp b/thirdparty/linux/include/coin1/IpLineSearch.hpp new file mode 100644 index 0000000..70c11f1 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpLineSearch.hpp @@ -0,0 +1,96 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpLineSearch.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPLINESEARCH_HPP__ +#define __IPLINESEARCH_HPP__ + +#include "IpAlgStrategy.hpp" +#include "IpIpoptCalculatedQuantities.hpp" + +namespace Ipopt +{ + + /** Base class for line search objects. + */ + class LineSearch : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + LineSearch() + {} + + /** Default destructor */ + virtual ~LineSearch() + {} + //@} + + /** Perform the line search. As search direction the delta + * in the data object is used + */ + virtual void FindAcceptableTrialPoint() = 0; + + /** Reset the line search. + * This function should be called if all previous information + * should be discarded when the line search is performed the + * next time. For example, this method should be called after + * the barrier parameter is changed. + */ + virtual void Reset() = 0; + + /** Set flag indicating whether a very rigorous line search should + * be performed. If this flag is set to true, the line search + * algorithm might decide to abort the line search and not to + * accept a new iterate. If the line search decided not to + * accept a new iterate, the return value of + * CheckSkippedLineSearch() is true at the next call. For + * example, in the non-monotone barrier parameter update + * procedure, the filter algorithm should not switch to the + * restoration phase in the free mode; instead, the algorithm + * should swtich to the fixed mode. + */ + virtual void SetRigorousLineSearch(bool rigorous) = 0; + + /** Check if the line search procedure didn't accept a new iterate + * during the last call of FindAcceptableTrialPoint(). + * + */ + virtual bool CheckSkippedLineSearch() = 0; + + /** This method should be called if the optimization process + * requires the line search object to switch to some fallback + * mechanism (like the restoration phase), when the regular + * optimization procedure cannot be continued (for example, + * because the search direction could not be computed). This + * will cause the line search object to immediately proceed with + * this mechanism when FindAcceptableTrialPoint() is call. This + * method returns false if no fallback mechanism is available. */ + virtual bool ActivateFallbackMechanism() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + LineSearch(const LineSearch&); + + /** Overloaded Equals Operator */ + void operator=(const LineSearch&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpMatrix.hpp b/thirdparty/linux/include/coin1/IpMatrix.hpp new file mode 100644 index 0000000..79018da --- /dev/null +++ b/thirdparty/linux/include/coin1/IpMatrix.hpp @@ -0,0 +1,345 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMatrix.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMATRIX_HPP__ +#define __IPMATRIX_HPP__ + +#include "IpVector.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class MatrixSpace; + + /** Matrix Base Class. This is the base class for all derived matrix + * types. All Matrices, such as Jacobian and Hessian matrices, as + * well as possibly the iteration matrices needed for the step + * computation, are of this type. + * + * Deriving from Matrix: Overload the protected XXX_Impl method. + */ + class Matrix : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding MatrixSpace. + */ + Matrix(const MatrixSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + valid_cache_tag_(0) + {} + + /** Destructor */ + virtual ~Matrix() + {} + //@} + + /**@name Operations of the Matrix on a Vector */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y. Do not overload. Overload MultVectorImpl instead. + */ + void MultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + MultVectorImpl(alpha, x, beta, y); + } + + /** Matrix(transpose) vector multiply. Computes y = alpha * + * Matrix^T * x + beta * y. Do not overload. Overload + * TransMultVectorImpl instead. + */ + void TransMultVector(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + TransMultVectorImpl(alpha, x, beta, y); + } + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** X = X + alpha*(Matrix S^{-1} Z). Should be implemented + * efficiently for the ExansionMatrix + */ + void AddMSinvZ(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExansionMatrix + */ + void SinvBlrmZMTdBr(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + bool HasValidNumbers() const; + + /** @name Information about the size of the matrix */ + //@{ + /** Number of rows */ + inline + Index NRows() const; + + /** Number of columns */ + inline + Index NCols() const; + //@} + + /** @name Norms of the individual rows and columns */ + //@{ + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be initialized + * of init is false. */ + void ComputeRowAMax(Vector& rows_norms, bool init=true) const + { + DBG_ASSERT(NRows() == rows_norms.Dim()); + if (init) rows_norms.Set(0.); + ComputeRowAMaxImpl(rows_norms, init); + } + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms The vector is assumed to be initialized + * of init is false. */ + void ComputeColAMax(Vector& cols_norms, bool init=true) const + { + DBG_ASSERT(NCols() == cols_norms.Dim()); + if (init) cols_norms.Set(0.); + ComputeColAMaxImpl(cols_norms, init); + } + //@} + + /** Print detailed information about the matrix. Do not overload. + * Overload PrintImpl instead. + */ + //@{ + virtual void Print(SmartPtr<const Journalist> jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + virtual void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + /** Return the owner MatrixSpace*/ + inline + SmartPtr<const MatrixSpace> OwnerSpace() const; + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods. + */ + //@{ + /** Matrix-vector multiply. Computes y = alpha * Matrix * x + + * beta * y + */ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** Matrix(transpose) vector multiply. + * Computes y = alpha * Matrix^T * x + beta * y + */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, Vector& y) const =0; + + /** X = X + alpha*(Matrix S^{-1} Z). Prototype for this + * specialize method is provided, but for efficient + * implementation it should be overloaded for the expansion matrix. + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Should be implemented + * efficiently for the ExpansionMatrix. + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation always returning true + * is provided, but if possible it should be implemented. */ + virtual bool HasValidNumbersImpl() const + { + return true; + } + + /** Compute the max-norm of the rows in the matrix. The result is + * stored in rows_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const = 0; + /** Compute the max-norm of the columns in the matrix. The result + * is stored in cols_norms. The vector is assumed to be + * initialized. */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const = 0; + + /** Print detailed information about the matrix. */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + Matrix(); + + /** Copy constructor */ + Matrix(const Matrix&); + + /** Overloaded Equals Operator */ + Matrix& operator=(const Matrix&); + //@} + + const SmartPtr<const MatrixSpace> owner_space_; + + /**@name CachedResults data members */ + //@{ + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + //@} + }; + + + /** MatrixSpace base class, corresponding to the Matrix base class. + * For each Matrix implementation, a corresponding MatrixSpace has + * to be implemented. A MatrixSpace is able to create new Matrices + * of a specific type. The MatrixSpace should also store + * information that is common to all Matrices of that type. For + * example, the dimensions of a Matrix is stored in the MatrixSpace + * base class. + */ + class MatrixSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the number rows and columns of all matrices + * generated by this MatrixSpace. + */ + MatrixSpace(Index nRows, Index nCols) + : + nRows_(nRows), + nCols_(nCols) + {} + + /** Destructor */ + virtual ~MatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new Matrix of the + * corresponding type. + */ + virtual Matrix* MakeNew() const=0; + + /** Accessor function for the number of rows. */ + Index NRows() const + { + return nRows_; + } + /** Accessor function for the number of columns. */ + Index NCols() const + { + return nCols_; + } + + /** Method to test if a given matrix belongs to a particular + * matrix space. + */ + bool IsMatrixFromSpace(const Matrix& matrix) const + { + return (matrix.OwnerSpace() == this); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + MatrixSpace(); + + /** Copy constructor */ + MatrixSpace(const MatrixSpace&); + + /** Overloaded Equals Operator */ + MatrixSpace& operator=(const MatrixSpace&); + //@} + + /** Number of rows for all matrices of this type. */ + const Index nRows_; + /** Number of columns for all matrices of this type. */ + const Index nCols_; + }; + + + /* Inline Methods */ + inline + Index Matrix::NRows() const + { + return owner_space_->NRows(); + } + + inline + Index Matrix::NCols() const + { + return owner_space_->NCols(); + } + + inline + SmartPtr<const MatrixSpace> Matrix::OwnerSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +// Macro definitions for debugging matrices +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) +#else +# define DBG_PRINT_MATRIX(__verbose_level, __mat_name, __mat) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__mat).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __mat_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif // #if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin1/IpMuUpdate.hpp b/thirdparty/linux/include/coin1/IpMuUpdate.hpp new file mode 100644 index 0000000..b6c1d9c --- /dev/null +++ b/thirdparty/linux/include/coin1/IpMuUpdate.hpp @@ -0,0 +1,69 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpMuUpdate.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPMUUPDATE_HPP__ +#define __IPMUUPDATE_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + /** Abstract Base Class for classes that implement methods for computing + * the barrier and fraction-to-the-boundary rule parameter for the + * current iteration. + */ + class MuUpdate : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + MuUpdate() + {} + + /** Default destructor */ + virtual ~MuUpdate() + {} + //@} + + /** Initialize method - overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Method for determining the barrier parameter for the next + * iteration. A LineSearch object is passed, so that this method + * can call the Reset method in the LineSearch object, for + * example when then barrier parameter is changed. This method is + * also responsible for setting the fraction-to-the-boundary + * parameter tau. This method returns false if the update could + * not be performed and the algorithm should revert to an + * emergency fallback mechanism. */ + virtual bool UpdateBarrierParameter() = 0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + MuUpdate(const MuUpdate&); + + /** Overloaded Equals Operator */ + void operator=(const MuUpdate&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpNLP.hpp b/thirdparty/linux/include/coin1/IpNLP.hpp new file mode 100644 index 0000000..1063c01 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpNLP.hpp @@ -0,0 +1,243 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLP.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLP_HPP__ +#define __IPNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpVector.hpp" +#include "IpSmartPtr.hpp" +#include "IpMatrix.hpp" +#include "IpSymMatrix.hpp" +#include "IpOptionsList.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Brief Class Description. + * Detailed Class Description. + */ + class NLP : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + NLP() + {} + + /** Default destructor */ + virtual ~NLP() + {} + //@} + + /** Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED); + DECLARE_STD_EXCEPTION(INVALID_NLP); + //@} + + /** @name NLP Initialization (overload in + * derived classes).*/ + //@{ + /** Overload if you want the chance to process options or parameters that + * may be specific to the NLP */ + virtual bool ProcessOptions(const OptionsList& options, + const std::string& prefix) + { + return true; + } + + /** Method for creating the derived vector / matrix types. The + * Hess_lagrangian_space pointer can be NULL if a quasi-Newton + * options is chosen. */ + virtual bool GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space)=0; + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& Px_L, + Vector& x_L, + const Matrix& Px_U, + Vector& x_U, + const Matrix& Pd_L, + Vector& d_L, + const Matrix& Pd_U, + Vector& d_U)=0; + + /** Method for obtaining the starting point for all the + * iterates. ToDo it might not make sense to ask for initial + * values for v_L and v_U? */ + virtual bool GetStartingPoint( + SmartPtr<Vector> x, + bool need_x, + SmartPtr<Vector> y_c, + bool need_y_c, + SmartPtr<Vector> y_d, + bool need_y_d, + SmartPtr<Vector> z_L, + bool need_z_L, + SmartPtr<Vector> z_U, + bool need_z_U + )=0; + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. The default + * dummy implementation returns false. */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate) + { + return false; + } + //@} + + /** @name NLP evaluation routines (overload + * in derived classes. */ + //@{ + virtual bool Eval_f(const Vector& x, Number& f) = 0; + + virtual bool Eval_grad_f(const Vector& x, Vector& g_f) = 0; + + virtual bool Eval_c(const Vector& x, Vector& c) = 0; + + virtual bool Eval_jac_c(const Vector& x, Matrix& jac_c) = 0; + + virtual bool Eval_d(const Vector& x, Vector& d) = 0; + + virtual bool Eval_jac_d(const Vector& x, Matrix& jac_d) = 0; + + virtual bool Eval_h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + SymMatrix& h) = 0; + //@} + + /** @name NLP solution routines. Have default dummy + * implementations that can be overloaded. */ + //@{ + /** This method is called at the very end of the optimization. It + * provides the final iterate to the user, so that it can be + * stored as the solution. The status flag indicates the outcome + * of the optimization, where SolverReturn is defined in + * IpAlgTypes.hpp. */ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, + const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + {} + + /** This method is called once per iteration, after the iteration + * summary output has been printed. It provides the current + * information to the user to do with it anything she wants. It + * also allows the user to ask for a premature termination of the + * optimization by returning false, in which case Ipopt will + * terminate with a corresponding return status. The basic + * information provided in the argument list has the quantities + * values printed in the iteration summary line. If more + * information is required, a user can obtain it from the IpData + * and IpCalculatedQuantities objects. However, note that the + * provided quantities are all for the problem that Ipopt sees, + * i.e., the quantities might be scaled, fixed variables might be + * sorted out, etc. The status indicates things like whether the + * algorithm is in the restoration phase... In the restoration + * phase, the dual variables are probably not not changing. */ + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + { + return true; + } + //@} + + /** Routines to get the scaling parameters. These do not need to + * be overloaded unless the options are set for User scaling + */ + //@{ + virtual void GetScalingParameters( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + Number& obj_scaling, + SmartPtr<Vector>& x_scaling, + SmartPtr<Vector>& c_scaling, + SmartPtr<Vector>& d_scaling) const + { + THROW_EXCEPTION(USER_SCALING_NOT_IMPLEMENTED, + "You have set options for user provided scaling, but have" + " not implemented GetScalingParameters in the NLP interface"); + } + //@} + + /** Method for obtaining the subspace in which the limited-memory + * Hessian approximation should be done. This is only called if + * the limited-memory Hessian approximation is chosen. Since the + * Hessian is zero in the space of all variables that appear in + * the problem functions only linearly, this allows the user to + * provide a VectorSpace for all nonlinear variables, and an + * ExpansionMatrix to lift from this VectorSpace to the + * VectorSpace of the primal variables x. If the returned values + * are NULL, it is assumed that the Hessian is to be approximated + * in the space of all x variables. The default instantiation of + * this method returns NULL, and a user only has to overwrite + * this method if the approximation is to be done only in a + * subspace. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr<VectorSpace>& approx_space, + SmartPtr<Matrix>& P_approx) + { + approx_space = NULL; + P_approx = NULL; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + NLP(const NLP&); + + /** Overloaded Equals Operator */ + void operator=(const NLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpNLPScaling.hpp b/thirdparty/linux/include/coin1/IpNLPScaling.hpp new file mode 100644 index 0000000..be5f13d --- /dev/null +++ b/thirdparty/linux/include/coin1/IpNLPScaling.hpp @@ -0,0 +1,451 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpNLPScaling.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPNLPSCALING_HPP__ +#define __IPNLPSCALING_HPP__ + +#include "IpOptionsList.hpp" +#include "IpRegOptions.hpp" + +namespace Ipopt +{ + // forward declarations + class Vector; + class VectorSpace; + class Matrix; + class MatrixSpace; + class SymMatrix; + class SymMatrixSpace; + class ScaledMatrixSpace; + class SymScaledMatrixSpace; + + /** This is the abstract base class for problem scaling. + * It is repsonsible for determining the scaling factors + * and mapping quantities in and out of scaled and unscaled + * versions + */ + class NLPScalingObject : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + NLPScalingObject(); + + /** Default destructor */ + virtual ~NLPScalingObject(); + //@} + + /** Method to initialize the options */ + bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix) + { + jnlst_ = &jnlst; + return InitializeImpl(options, prefix); + } + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f)=0; + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_x(const SmartPtr<const Vector>& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_c(const SmartPtr<const Vector>& v)=0; + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_d(const SmartPtr<const Vector>& v)=0; + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v)=0; + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_c_scaling(SmartPtr<const Matrix> matrix)=0; + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_d_scaling(SmartPtr<const Matrix> matrix)=0; + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const SymMatrix> + apply_hessian_scaling(SmartPtr<const SymMatrix> matrix)=0; + //@} + + /** Methods for scaling bounds - these wrap those above */ + //@{ + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr<Vector> apply_vector_scaling_x_LU_NonConst( + const Matrix& Px_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& x_space); + /** Returns an x-scaled vector in the x_L or x_U space */ + SmartPtr<const Vector> apply_vector_scaling_x_LU( + const Matrix& Px_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& x_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr<Vector> apply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-scaled vector in the d_L or d_U space */ + SmartPtr<const Vector> apply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr<Vector> unapply_vector_scaling_d_LU_NonConst( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + /** Returns an d-unscaled vector in the d_L or d_U space */ + SmartPtr<const Vector> unapply_vector_scaling_d_LU( + const Matrix& Pd_LU, + const SmartPtr<const Vector>& lu, + const VectorSpace& d_space); + //@} + + /** Methods for scaling the gradient of the objective - wraps the + * virtual methods above + */ + //@{ + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr<Vector> + apply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); + /** Returns a grad_f scaled version (d_f * D_x^{-1}) of the given vector */ + virtual SmartPtr<const Vector> + apply_grad_obj_scaling(const SmartPtr<const Vector>& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr<Vector> + unapply_grad_obj_scaling_NonConst(const SmartPtr<const Vector>& v); + /** Returns a grad_f unscaled version (d_f * D_x^{-1}) of the + * given vector */ + virtual SmartPtr<const Vector> + unapply_grad_obj_scaling(const SmartPtr<const Vector>& v); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + /** Returns true if the primal x variables are scaled. */ + virtual bool have_x_scaling()=0; + /** Returns true if the equality constraints are scaled. */ + virtual bool have_c_scaling()=0; + /** Returns true if the inequality constraints are scaled. */ + virtual bool have_d_scaling()=0; + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + SmartPtr<const MatrixSpace>& new_jac_c_space, + SmartPtr<const MatrixSpace>& new_jac_d_space, + SmartPtr<const SymMatrixSpace>& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U)=0; + protected: + /** Implementation of the initialization method that has to be + * overloaded by for each derived class. */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix)=0; + + /** Accessor method for the journalist */ + const Journalist& Jnlst() const + { + return *jnlst_; + } + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NLPScalingObject(const NLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NLPScalingObject&); + //@} + + SmartPtr<const Journalist> jnlst_; + }; + + /** This is a base class for many standard scaling + * techniques. The overloaded classes only need to + * provide the scaling parameters + */ + class StandardScalingBase : public NLPScalingObject + { + public: + /**@name Constructors/Destructors */ + //@{ + StandardScalingBase(); + + /** Default destructor */ + virtual ~StandardScalingBase(); + //@} + + /** Methods to map scaled and unscaled matrices */ + //@{ + /** Returns an obj-scaled version of the given scalar */ + virtual Number apply_obj_scaling(const Number& f); + /** Returns an obj-unscaled version of the given scalar */ + virtual Number unapply_obj_scaling(const Number& f); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v); + /** Returns an x-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_x(const SmartPtr<const Vector>& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_x_NonConst(const SmartPtr<const Vector>& v); + /** Returns an x-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_x(const SmartPtr<const Vector>& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_c(const SmartPtr<const Vector>& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_c(const SmartPtr<const Vector>& v); + /** Returns an c-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v); + /** Returns an c-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_c_NonConst(const SmartPtr<const Vector>& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<const Vector> + apply_vector_scaling_d(const SmartPtr<const Vector>& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<const Vector> + unapply_vector_scaling_d(const SmartPtr<const Vector>& v); + /** Returns an d-scaled version of the given vector */ + virtual SmartPtr<Vector> + apply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v); + /** Returns an d-unscaled version of the given vector */ + virtual SmartPtr<Vector> + unapply_vector_scaling_d_NonConst(const SmartPtr<const Vector>& v); + /** Returns a scaled version of the jacobian for c. If the + * overloaded method does not make a new matrix, make sure to set + * the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_c_scaling(SmartPtr<const Matrix> matrix); + /** Returns a scaled version of the jacobian for d If the + * overloaded method does not create a new matrix, make sure to + * set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const Matrix> + apply_jac_d_scaling(SmartPtr<const Matrix> matrix); + /** Returns a scaled version of the hessian of the lagrangian If + * the overloaded method does not create a new matrix, make sure + * to set the matrix ptr passed in to NULL. + */ + virtual SmartPtr<const SymMatrix> + apply_hessian_scaling(SmartPtr<const SymMatrix> matrix); + //@} + + /** @name Methods for determining whether scaling for entities is + * done */ + //@{ + virtual bool have_x_scaling(); + virtual bool have_c_scaling(); + virtual bool have_d_scaling(); + //@} + + /** This method is called by the IpoptNLP's at a convenient time to + * compute and/or read scaling factors + */ + virtual void DetermineScaling(const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + SmartPtr<const MatrixSpace>& new_jac_c_space, + SmartPtr<const MatrixSpace>& new_jac_d_space, + SmartPtr<const SymMatrixSpace>& new_h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U); + + /** Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + protected: + /** Overloaded initialization method */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix); + + /** This is the method that has to be overloaded by a particular + * scaling method that somehow computes the scaling vectors dx, + * dc, and dd. The pointers to those vectors can be NULL, in + * which case no scaling for that item will be done later. */ + virtual void DetermineScalingParametersImpl( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr<Vector>& dx, + SmartPtr<Vector>& dc, + SmartPtr<Vector>& dd)=0; + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + StandardScalingBase(const StandardScalingBase&); + + /** Overloaded Equals Operator */ + void operator=(const StandardScalingBase&); + //@} + + /** Scaling parameters - we only need to keep copies of + * the objective scaling and the x scaling - the others we can + * get from the scaled matrix spaces. + */ + //@{ + /** objective scaling parameter */ + Number df_; + /** x scaling */ + SmartPtr<Vector> dx_; + //@} + + /** Scaled Matrix Spaces */ + //@{ + /** Scaled jacobian of c space */ + SmartPtr<ScaledMatrixSpace> scaled_jac_c_space_; + /** Scaled jacobian of d space */ + SmartPtr<ScaledMatrixSpace> scaled_jac_d_space_; + /** Scaled hessian of lagrangian spacea */ + SmartPtr<SymScaledMatrixSpace> scaled_h_space_; + //@} + + /** @name Algorithmic parameters */ + //@{ + /** Additional scaling value for the objective function */ + Number obj_scaling_factor_; + //@} + }; + + /** Class implementing the scaling object that doesn't to any scaling */ + class NoNLPScalingObject : public StandardScalingBase + { + public: + /**@name Constructors/Destructors */ + //@{ + NoNLPScalingObject() + {} + + /** Default destructor */ + virtual ~NoNLPScalingObject() + {} + //@} + + + protected: + /** Overloaded from StandardScalingBase */ + virtual void DetermineScalingParametersImpl( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + const SmartPtr<const MatrixSpace> jac_c_space, + const SmartPtr<const MatrixSpace> jac_d_space, + const SmartPtr<const SymMatrixSpace> h_space, + const Matrix& Px_L, const Vector& x_L, + const Matrix& Px_U, const Vector& x_U, + Number& df, + SmartPtr<Vector>& dx, + SmartPtr<Vector>& dc, + SmartPtr<Vector>& dd); + + private: + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + + /** Copy Constructor */ + NoNLPScalingObject(const NoNLPScalingObject&); + + /** Overloaded Equals Operator */ + void operator=(const NoNLPScalingObject&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpObserver.hpp b/thirdparty/linux/include/coin1/IpObserver.hpp new file mode 100644 index 0000000..b16f599 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpObserver.hpp @@ -0,0 +1,366 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpObserver.hpp 2161 2013-01-01 20:39:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOBSERVER_HPP__ +#define __IPOBSERVER_HPP__ + +#include "IpUtils.hpp" +#include <vector> +#include <algorithm> + +//#define IP_DEBUG_OBSERVER +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_OBSERVER +#endif +#ifdef IP_DEBUG_OBSERVER +# include "IpDebug.hpp" +#endif + +namespace Ipopt +{ + /** Forward declarations */ + class Subject; + + /** Slight Variation of the Observer Design Pattern. + * This class implements the Observer class of the + * Observer Design Pattern. An Observer "Attach"es + * to a Subject, indicating that it would like to + * be notified of changes in the Subject. + * Any derived class wishing to recieve notifications + * from a Subject should inherit off of + * Observer and overload the protected method, + * RecieveNotification_(...). + */ + class Observer + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Observer() + {} + + /** Default destructor */ + inline + virtual ~Observer(); + //@} + + /** Enumeration specifying the type of notification */ + enum NotifyType + { + NT_All, + NT_BeingDestroyed, + NT_Changed + }; + + protected: + /** Derived classes should call this method + * to request an "Attach" to a Subject. Do + * not call "Attach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestAttach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should call this method + * to request a "Detach" to a Subject. Do + * not call "Detach" explicitly on the Subject + * since further processing is done here + */ + inline + void RequestDetach(NotifyType notify_type, const Subject* subject); + + /** Derived classes should overload this method to + * recieve the requested notification from + * attached Subjects + */ + virtual void RecieveNotification(NotifyType notify_type, const Subject* subject)=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Observer(const Observer&); + + /** Overloaded Equals Operator */ + void operator=(const Observer&); + //@} + + /** A list of the subjects currently being + * observed. */ + std::vector<const Subject*> subjects_; + + /** Private Method for Recieving Notification + * should only be called by the friend class + * Subject. This method will, in turn, call + * the overloaded RecieveNotification method + * for the derived class to process. + */ + inline + void ProcessNotification(NotifyType notify_type, const Subject* subject); + + friend class Subject; + }; + + /** Slight Variation of the Observer Design Pattern (Subject part). + * This class implements the Subject class of the Observer Design + * Pattern. An Observer "Attach"es to a Subject, indicating that it + * would like to be notified of changes in the Subject. Any + * derived class that is to be observed has to inherit off the + * Subject base class. If the subject needs to notify the + * Observer, it calls the Notify method. + */ + class Subject + { + public: +#ifdef IP_DEBUG_OBSERVER + + static const Index dbg_verbosity; +#endif + + /**@name Constructors/Destructors */ + //@{ + /** Default Constructor */ + Subject() + {} + + /** Default destructor */ + inline + virtual ~Subject(); + //@} + + /**@name Methods to Add and Remove Observers. + * Currently, the notify_type flags are not used, + * and Observers are attached in general and will + * recieve all notifications (of the type requested + * and possibly of types not requested). It is + * up to the observer to ignore the types they + * are not interested in. The NotifyType in the + * parameter list is so a more efficient mechanism + * depending on type could be implemented later if + * necessary.*/ + //@{ + + /** Attach the specified observer + * (i.e., begin recieving notifications). */ + inline + void AttachObserver(Observer::NotifyType notify_type, Observer* observer) const; + + /** Detach the specified observer + * (i.e., no longer recieve notifications). */ + inline + void DetachObserver(Observer::NotifyType notify_type, Observer* observer) const; + //@} + + protected: + + inline + void Notify(Observer::NotifyType notify_type) const; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + Subject(const Subject&); + + /** Overloaded Equals Operator */ + void operator=(const Subject&); + //@} + + mutable std::vector<Observer*> observers_; + + }; + + /* inline methods */ + inline + Observer::~Observer() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::~Observer", dbg_verbosity); + if (DBG_VERBOSITY()>=1) { + for (Index i=0; i<(Index)subjects_.size(); i++) { + DBG_PRINT((1,"subjects_[%d] = 0x%x\n", i, subjects_[i])); + } + } +#endif + // Detach all subjects + for (Int i=(Int)(subjects_.size()-1); i>=0; i--) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1,"About to detach subjects_[%d] = 0x%x\n", i, subjects_[i])); +#endif + + RequestDetach(NT_All, subjects_[i]); + } + } + + inline + void Observer::RequestAttach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestAttach", dbg_verbosity); + + // Add the subject to the list if it does not already exist + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + DBG_ASSERT(attached_subject == subjects_.end()); + DBG_ASSERT(subject); +#endif + + // add the subject to the list + subjects_.push_back(subject); + // Attach the observer to the subject + subject->AttachObserver(notify_type, this); + } + + inline + void Observer::RequestDetach(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::RequestDetach", dbg_verbosity); + DBG_PRINT((1, "Requesting detach of subject: 0x%x\n", subject)); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + if (attached_subject != subjects_.end()) { +#ifdef IP_DEBUG_OBSERVER + DBG_PRINT((1, "Removing subject: 0x%x from the list\n", subject)); +#endif + + subjects_.erase(attached_subject); + } + + // Detach the observer from the subject + subject->DetachObserver(notify_type, this); + } + } + + inline + void Observer::ProcessNotification(NotifyType notify_type, const Subject* subject) + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Observer::ProcessNotification", dbg_verbosity); + DBG_ASSERT(subject); +#endif + + if (subject) { + std::vector<const Subject*>::iterator attached_subject; + attached_subject = std::find(subjects_.begin(), subjects_.end(), subject); + + // We must be processing a notification for a + // subject that was previously attached. +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_subject != subjects_.end()); +#endif + + this->RecieveNotification(notify_type, subject); + + if (notify_type == NT_BeingDestroyed) { + // the subject is going away, remove it from our list + subjects_.erase(attached_subject); + } + } + } + + inline + Subject::~Subject() + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::~Subject", dbg_verbosity); +#endif + + std::vector<Observer*>::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(Observer::NT_BeingDestroyed, this); + } + } + + inline + void Subject::AttachObserver(Observer::NotifyType notify_type, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::AttachObserver", dbg_verbosity); + // current implementation notifies all observers of everything + // they must filter the notifications that they are not interested + // in (i.e. a hub, not a router) + DBG_ASSERT(observer); + + std::vector<Observer*>::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); + DBG_ASSERT(attached_observer == observers_.end()); + + DBG_ASSERT(observer); +#endif + + observers_.push_back(observer); + } + + inline + void Subject::DetachObserver(Observer::NotifyType notify_type, Observer* observer) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::DetachObserver", dbg_verbosity); + DBG_ASSERT(observer); +#endif + + if (observer) { + std::vector<Observer*>::iterator attached_observer; + attached_observer = std::find(observers_.begin(), observers_.end(), observer); +#ifdef IP_DEBUG_OBSERVER + + DBG_ASSERT(attached_observer != observers_.end()); +#endif + + if (attached_observer != observers_.end()) { + observers_.erase(attached_observer); + } + } + } + + inline + void Subject::Notify(Observer::NotifyType notify_type) const + { +#ifdef IP_DEBUG_OBSERVER + DBG_START_METH("Subject::Notify", dbg_verbosity); +#endif + + std::vector<Observer*>::iterator iter; + for (iter = observers_.begin(); iter != observers_.end(); iter++) { + (*iter)->ProcessNotification(notify_type, this); + } + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpOptionsList.hpp b/thirdparty/linux/include/coin1/IpOptionsList.hpp new file mode 100644 index 0000000..a17863f --- /dev/null +++ b/thirdparty/linux/include/coin1/IpOptionsList.hpp @@ -0,0 +1,289 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOptionsList.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPOPTLIST_HPP__ +#define __IPOPTLIST_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpRegOptions.hpp" + +#include <iostream> +#include <map> + +namespace Ipopt +{ + /** Exception that can be used to indicate errors with options */ + DECLARE_STD_EXCEPTION(OPTION_INVALID); + + /** This class stores a list of user set options. Each options is + * identified by a case-insensitive keyword (tag). Its value is + * stored internally as a string (always lower case), but for + * convenience set and get methods are provided to obtain Index and + * Number type values. For each keyword we also keep track of how + * often the value of an option has been requested by a get method. + */ + class OptionsList : public ReferencedObject + { + /** Class for storing the value and counter for each option in + * OptionsList. */ + class OptionValue + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor (needed for the map) */ + OptionValue() + : + initialized_(false) + {} + + /** Constructor given the value */ + OptionValue(std::string value, bool allow_clobber, bool dont_print) + : + value_(value), + counter_(0), + initialized_(true), + allow_clobber_(allow_clobber), + dont_print_(dont_print) + {} + + /** Copy Constructor */ + OptionValue(const OptionValue& copy) + : + value_(copy.value_), + counter_(copy.counter_), + initialized_(copy.initialized_), + allow_clobber_(copy.allow_clobber_), + dont_print_(copy.dont_print_) + {} + + /** Equals operator */ + void operator=(const OptionValue& copy) + { + value_=copy.value_; + counter_=copy.counter_; + initialized_=copy.initialized_; + allow_clobber_=copy.allow_clobber_; + dont_print_=copy.dont_print_; + } + + /** Default Destructor */ + ~OptionValue() + {} + //@} + + /** Method for retrieving the value of an option. Calling this + * method will increase the counter by one. */ + std::string GetValue() const + { + DBG_ASSERT(initialized_); + counter_++; + return value_; + } + + /** Method for retrieving the value without increasing the + * counter */ + std::string Value() const + { + DBG_ASSERT(initialized_); + return value_; + } + + /** Method for accessing current value of the request counter */ + Index Counter() const + { + DBG_ASSERT(initialized_); + return counter_; + } + + /** True if the option can be overwritten */ + bool AllowClobber() const + { + DBG_ASSERT(initialized_); + return allow_clobber_; + } + + /** True if this option is not to show up in the + * print_user_options output */ + bool DontPrint() const + { + DBG_ASSERT(initialized_); + return dont_print_; + } + + private: + /** Value for this option */ + std::string value_; + + /** Counter for requests */ + mutable Index counter_; + + /** for debugging */ + bool initialized_; + + /** True if the option can be overwritten */ + bool allow_clobber_; + + /** True if this option is not to show up in the + * print_user_options output */ + bool dont_print_; + }; + + public: + /**@name Constructors/Destructors */ + //@{ + OptionsList(SmartPtr<RegisteredOptions> reg_options, SmartPtr<Journalist> jnlst) + : reg_options_(reg_options), jnlst_(jnlst) + {} + + OptionsList() + {} + + /** Copy Constructor */ + OptionsList(const OptionsList& copy) + { + // copy all the option strings and values + options_ = copy.options_; + // copy the registered options pointer + reg_options_ = copy.reg_options_; + } + + /** Default destructor */ + virtual ~OptionsList() + {} + + /** Overloaded Equals Operator */ + virtual void operator=(const OptionsList& source) + { + options_ = source.options_; + reg_options_ = source.reg_options_; + jnlst_ = source.jnlst_; + } + //@} + + /** Method for clearing all previously set options */ + virtual void clear() + { + options_.clear(); + } + + /** @name Get / Set Methods */ + //@{ + virtual void SetRegisteredOptions(const SmartPtr<RegisteredOptions> reg_options) + { + reg_options_ = reg_options; + } + virtual void SetJournalist(const SmartPtr<Journalist> jnlst) + { + jnlst_ = jnlst; + } + //@} + /** @name Methods for setting options */ + //@{ + virtual bool SetStringValue(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValue(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValue(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for setting options only if they have not been + * set before*/ + //@{ + virtual bool SetStringValueIfUnset(const std::string& tag, const std::string& value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetNumericValueIfUnset(const std::string& tag, Number value, + bool allow_clobber = true, bool dont_print = false); + virtual bool SetIntegerValueIfUnset(const std::string& tag, Index value, + bool allow_clobber = true, bool dont_print = false); + //@} + + /** @name Methods for retrieving values from the options list. If + * a tag is not found, the methods return false, and value is set + * to the default value defined in the registered options. */ + //@{ + virtual bool GetStringValue(const std::string& tag, std::string& value, + const std::string& prefix) const; + virtual bool GetEnumValue(const std::string& tag, Index& value, + const std::string& prefix) const; + virtual bool GetBoolValue(const std::string& tag, bool& value, + const std::string& prefix) const; + virtual bool GetNumericValue(const std::string& tag, Number& value, + const std::string& prefix) const; + virtual bool GetIntegerValue(const std::string& tag, Index& value, + const std::string& prefix) const; + //@} + + /** Get a string with the list of all options (tag, value, counter) */ + virtual void PrintList(std::string& list) const; + + /** Get a string with the list of all options set by the user + * (tag, value, use/notused). Here, options with dont_print flag + * set to true are not printed. */ + virtual void PrintUserOptions(std::string& list) const; + + /** Read options from the stream is. Returns false if + * an error was encountered. */ + virtual bool ReadFromStream(const Journalist& jnlst, std::istream& is, bool allow_clobber = false); + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // OptionsList(); + + //@} + + /** map for storing the options */ + std::map< std::string, OptionValue > options_; + + /** list of all the registered options to validate against */ + SmartPtr<RegisteredOptions> reg_options_; + + /** Journalist for writing error messages, etc. */ + SmartPtr<Journalist> jnlst_; + + /** auxilliary method for converting sting to all lower-case + * letters */ + const std::string& lowercase(const std::string tag) const; + + /** auxilliary method for finding the value for a tag in the + * options list. This method first looks for the concatenated + * string prefix+tag (if prefix is not ""), and if this is not + * found, it looks for tag. The return value is true iff + * prefix+tag or tag is found. In that case, the corresponding + * string value is copied into value. */ + bool find_tag(const std::string& tag, const std::string& prefix, + std::string& value) const; + + /** tells whether or not we can clobber a particular option. + * returns true if the option does not already exist, or if + * the option exists but is set to allow_clobber + */ + bool will_allow_clobber(const std::string& tag) const; + + /** read the next token from stream is. Returns false, if EOF was + * reached before a tokens was ecountered. */ + bool readnexttoken(std::istream& is, std::string& token); + + /** auxilliary string set by lowercase method */ + mutable std::string lowercase_buffer_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpOrigIpoptNLP.hpp b/thirdparty/linux/include/coin1/IpOrigIpoptNLP.hpp new file mode 100644 index 0000000..41b10fa --- /dev/null +++ b/thirdparty/linux/include/coin1/IpOrigIpoptNLP.hpp @@ -0,0 +1,488 @@ +// Copyright (C) 2004, 2010 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpOrigIpoptNLP.hpp 2594 2015-08-09 14:31:05Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPORIGIPOPTNLP_HPP__ +#define __IPORIGIPOPTNLP_HPP__ + +#include "IpIpoptNLP.hpp" +#include "IpException.hpp" +#include "IpTimingStatistics.hpp" + +namespace Ipopt +{ + + /** enumeration for the Hessian information type. */ + enum HessianApproximationType { + EXACT=0, + LIMITED_MEMORY + }; + + /** enumeration for the Hessian approximation space. */ + enum HessianApproximationSpace { + NONLINEAR_VARS=0, + ALL_VARS + }; + + /** This class maps the traditional NLP into + * something that is more useful by Ipopt. + * This class takes care of storing the + * calculated model results, handles caching, + * and (some day) takes care of addition of slacks. + */ + class OrigIpoptNLP : public IpoptNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + OrigIpoptNLP(const SmartPtr<const Journalist>& jnlst, + const SmartPtr<NLP>& nlp, + const SmartPtr<NLPScalingObject>& nlp_scaling); + + /** Default destructor */ + virtual ~OrigIpoptNLP(); + //@} + + /** Initialize - overloaded from IpoptNLP */ + virtual bool Initialize(const Journalist& jnlst, + const OptionsList& options, + const std::string& prefix); + + /** Initialize (create) structures for + * the iteration data */ + virtual bool InitializeStructures(SmartPtr<Vector>& x, + bool init_x, + SmartPtr<Vector>& y_c, + bool init_y_c, + SmartPtr<Vector>& y_d, + bool init_y_d, + SmartPtr<Vector>& z_L, + bool init_z_L, + SmartPtr<Vector>& z_U, + bool init_z_U, + SmartPtr<Vector>& v_L, + SmartPtr<Vector>& v_U + ); + + /** Method accessing the GetWarmStartIterate of the NLP */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate) + { + return nlp_->GetWarmStartIterate(warm_start_iterate); + } + /** Accessor methods for model data */ + //@{ + /** Objective value */ + virtual Number f(const Vector& x); + + /** Objective value (depending in mu) - incorrect version for + * OrigIpoptNLP */ + virtual Number f(const Vector& x, Number mu); + + /** Gradient of the objective */ + virtual SmartPtr<const Vector> grad_f(const Vector& x); + + /** Gradient of the objective (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr<const Vector> grad_f(const Vector& x, Number mu); + + /** Equality constraint residual */ + virtual SmartPtr<const Vector> c(const Vector& x); + + /** Jacobian Matrix for equality constraints */ + virtual SmartPtr<const Matrix> jac_c(const Vector& x); + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + virtual SmartPtr<const Vector> d(const Vector& x); + + /** Jacobian Matrix for inequality constraints*/ + virtual SmartPtr<const Matrix> jac_d(const Vector& x); + + /** Hessian of the Lagrangian */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd + ); + + /** Hessian of the Lagrangian (depending in mu) - incorrect + * version for OrigIpoptNLP */ + virtual SmartPtr<const SymMatrix> h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + Number mu); + + /** Provides a Hessian matrix from the correct matrix space with + * uninitialized values. This can be used in LeastSquareMults to + * obtain a "zero Hessian". */ + virtual SmartPtr<const SymMatrix> uninitialized_h(); + + /** Lower bounds on x */ + virtual SmartPtr<const Vector> x_L() const + { + return x_L_; + } + + /** Permutation matrix (x_L_ -> x) */ + virtual SmartPtr<const Matrix> Px_L() const + { + return Px_L_; + } + + /** Upper bounds on x */ + virtual SmartPtr<const Vector> x_U() const + { + return x_U_; + } + + /** Permutation matrix (x_U_ -> x */ + virtual SmartPtr<const Matrix> Px_U() const + { + return Px_U_; + } + + /** Lower bounds on d */ + virtual SmartPtr<const Vector> d_L() const + { + return d_L_; + } + + /** Permutation matrix (d_L_ -> d) */ + virtual SmartPtr<const Matrix> Pd_L() const + { + return Pd_L_; + } + + /** Upper bounds on d */ + virtual SmartPtr<const Vector> d_U() const + { + return d_U_; + } + + /** Permutation matrix (d_U_ -> d */ + virtual SmartPtr<const Matrix> Pd_U() const + { + return Pd_U_; + } + + virtual SmartPtr<const SymMatrixSpace> HessianMatrixSpace() const + { + return h_space_; + } + + virtual SmartPtr<const VectorSpace> x_space() const + { + return x_space_; + } + //@} + + /** Accessor method for vector/matrix spaces pointers */ + virtual void GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space); + + /** Method for adapting the variable bounds. This is called if + * slacks are becoming too small */ + virtual void AdjustVariableBounds(const Vector& new_x_L, + const Vector& new_x_U, + const Vector& new_d_L, + const Vector& new_d_U); + + /** @name Counters for the number of function evaluations. */ + //@{ + virtual Index f_evals() const + { + return f_evals_; + } + virtual Index grad_f_evals() const + { + return grad_f_evals_; + } + virtual Index c_evals() const + { + return c_evals_; + } + virtual Index jac_c_evals() const + { + return jac_c_evals_; + } + virtual Index d_evals() const + { + return d_evals_; + } + virtual Index jac_d_evals() const + { + return jac_d_evals_; + } + virtual Index h_evals() const + { + return h_evals_; + } + //@} + + /** Solution Routines - overloaded from IpoptNLP*/ + //@{ + void FinalizeSolution(SolverReturn status, + const Vector& x, const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + SmartPtr<const IpoptData> ip_data, + SmartPtr<IpoptCalculatedQuantities> ip_cq); + //@} + + /** @name Methods for IpoptType */ + //@{ + /** Called by IpoptType to register the options */ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Accessor method to the underlying NLP */ + SmartPtr<NLP> nlp() + { + return nlp_; + } + + /**@name Methods related to function evaluation timing. */ + //@{ + + /** Reset the timing statistics */ + void ResetTimes(); + + void PrintTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + const TimedTask& f_eval_time() const + { + return f_eval_time_; + } + const TimedTask& grad_f_eval_time() const + { + return grad_f_eval_time_; + } + const TimedTask& c_eval_time() const + { + return c_eval_time_; + } + const TimedTask& jac_c_eval_time() const + { + return jac_c_eval_time_; + } + const TimedTask& d_eval_time() const + { + return d_eval_time_; + } + const TimedTask& jac_d_eval_time() const + { + return jac_d_eval_time_; + } + const TimedTask& h_eval_time() const + { + return h_eval_time_; + } + + Number TotalFunctionEvaluationCpuTime() const; + Number TotalFunctionEvaluationSysTime() const; + Number TotalFunctionEvaluationWallclockTime() const; + //@} + + private: + /** journalist */ + SmartPtr<const Journalist> jnlst_; + + /** Pointer to the NLP */ + SmartPtr<NLP> nlp_; + + /** Necessary Vector/Matrix spaces */ + //@{ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> c_space_; + SmartPtr<const VectorSpace> d_space_; + SmartPtr<const VectorSpace> x_l_space_; + SmartPtr<const MatrixSpace> px_l_space_; + SmartPtr<const VectorSpace> x_u_space_; + SmartPtr<const MatrixSpace> px_u_space_; + SmartPtr<const VectorSpace> d_l_space_; + SmartPtr<const MatrixSpace> pd_l_space_; + SmartPtr<const VectorSpace> d_u_space_; + SmartPtr<const MatrixSpace> pd_u_space_; + SmartPtr<const MatrixSpace> jac_c_space_; + SmartPtr<const MatrixSpace> jac_d_space_; + SmartPtr<const SymMatrixSpace> h_space_; + + SmartPtr<const MatrixSpace> scaled_jac_c_space_; + SmartPtr<const MatrixSpace> scaled_jac_d_space_; + SmartPtr<const SymMatrixSpace> scaled_h_space_; + //@} + /**@name Storage for Model Quantities */ + //@{ + /** Objective function */ + CachedResults<Number> f_cache_; + + /** Gradient of the objective function */ + CachedResults<SmartPtr<const Vector> > grad_f_cache_; + + /** Equality constraint residuals */ + CachedResults<SmartPtr<const Vector> > c_cache_; + + /** Jacobian Matrix for equality constraints + * (current iteration) */ + CachedResults<SmartPtr<const Matrix> > jac_c_cache_; + + /** Inequality constraint residual (reformulated + * as equalities with slacks */ + CachedResults<SmartPtr<const Vector> > d_cache_; + + /** Jacobian Matrix for inequality constraints + * (current iteration) */ + CachedResults<SmartPtr<const Matrix> > jac_d_cache_; + + /** Hessian of the lagrangian + * (current iteration) */ + CachedResults<SmartPtr<const SymMatrix> > h_cache_; + + /** Unscaled version of x vector */ + CachedResults<SmartPtr<const Vector> > unscaled_x_cache_; + + /** Lower bounds on x */ + SmartPtr<const Vector> x_L_; + + /** Permutation matrix (x_L_ -> x) */ + SmartPtr<const Matrix> Px_L_; + + /** Upper bounds on x */ + SmartPtr<const Vector> x_U_; + + /** Permutation matrix (x_U_ -> x */ + SmartPtr<const Matrix> Px_U_; + + /** Lower bounds on d */ + SmartPtr<const Vector> d_L_; + + /** Permutation matrix (d_L_ -> d) */ + SmartPtr<const Matrix> Pd_L_; + + /** Upper bounds on d */ + SmartPtr<const Vector> d_U_; + + /** Permutation matrix (d_U_ -> d */ + SmartPtr<const Matrix> Pd_U_; + + /** Original unmodified lower bounds on x */ + SmartPtr<const Vector> orig_x_L_; + + /** Original unmodified upper bounds on x */ + SmartPtr<const Vector> orig_x_U_; + //@} + + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + OrigIpoptNLP(); + + /** Copy Constructor */ + OrigIpoptNLP(const OrigIpoptNLP&); + + /** Overloaded Equals Operator */ + void operator=(const OrigIpoptNLP&); + //@} + + /** @name auxilliary functions */ + //@{ + /** relax the bounds by a relative move of relax_bound_factor. + * Here, relax_bound_factor should be negative (or zero) for + * lower bounds, and positive (or zero) for upper bounds. + */ + void relax_bounds(Number bound_relax_factor, Vector& bounds); + /** Method for getting the unscaled version of the x vector */ + SmartPtr<const Vector> get_unscaled_x(const Vector& x); + //@} + + /** @name Algorithmic parameters */ + //@{ + /** relaxation factor for the bounds */ + Number bound_relax_factor_; + /** Flag indicating whether the primal variables should be + * projected back into original bounds are optimization. */ + bool honor_original_bounds_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Flag indicating in which space Hessian is to be approximated. */ + HessianApproximationSpace hessian_approximation_space_; + /** Flag indicating whether it is desired to check if there are + * Nan or Inf entries in first and second derivative matrices. */ + bool check_derivatives_for_naninf_; + /** Flag indicating if we need to ask for equality constraint + * Jacobians only once */ + bool jac_c_constant_; + /** Flag indicating if we need to ask for inequality constraint + * Jacobians only once */ + bool jac_d_constant_; + /** Flag indicating if we need to ask for Hessian only once */ + bool hessian_constant_; + //@} + + /** @name Counters for the function evaluations */ + //@{ + Index f_evals_; + Index grad_f_evals_; + Index c_evals_; + Index jac_c_evals_; + Index d_evals_; + Index jac_d_evals_; + Index h_evals_; + //@} + + /** Flag indicating if initialization method has been called */ + bool initialized_; + + /**@name Timing statistics for the function evaluations. */ + //@{ + TimedTask f_eval_time_; + TimedTask grad_f_eval_time_; + TimedTask c_eval_time_; + TimedTask jac_c_eval_time_; + TimedTask d_eval_time_; + TimedTask jac_d_eval_time_; + TimedTask h_eval_time_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpPDSystemSolver.hpp b/thirdparty/linux/include/coin1/IpPDSystemSolver.hpp new file mode 100644 index 0000000..b436e67 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpPDSystemSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpPDSystemSolver.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPPDSYSTEMSOLVER_HPP__ +#define __IPPDSYSTEMSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include "IpIteratesVector.hpp" + +namespace Ipopt +{ + + /** Pure Primal Dual System Solver Base Class. + * This is the base class for all derived Primal-Dual System Solver Types. + * + * Here, we understand the primal-dual system as the following linear + * system: + * + * \f$ + * \left[\begin{array}{cccccccc} + * W & 0 & J_c^T & J_d^T & -P^x_L & P^x_U & 0 & 0 \\ + * 0 & 0 & 0 & -I & 0 & 0 & -P_L^d & P_U^d \\ + * J_c & 0 & 0 & 0 & 0 & 0 & 0 & 0\\ + * J_d & -I & 0 & 0 & 0 & 0 & 0 & 0\\ + * Z_L(P_L^x)^T & 0 & 0 & 0 & Sl^x_L & 0 & 0 & 0\\ + * -Z_U(P_U^x)^T & 0 & 0 & 0 & 0 & Sl^x_U & 0 & 0\\ + * 0 & V_L(P_L^d)^T & 0 & 0 & 0 & 0 & Sl^s_L & 0 \\ + * 0 & -V_U(P_U^d)^T & 0 & 0 & 0 & 0 & 0 & Sl^s_U \\ + * \end{array}\right] + * \left(\begin{array}{c} + * sol_x\\ sol_s\\ sol_c\\ sol_d\\ sol^z_L\\ sol^z_U\\ sol^v_L\\ + * sol^v_U + * \end{array}\right) = + * \left(\begin{array}{c} + * rhs_x\\ rhs_s\\ rhs_c\\ rhs_d\\ rhs^z_L\\ rhs^z_U\\ rhs^v_L\\ + * rhs^v_U + * \end{array}\right) + * \f$ + * + * Here, \f$Sl^x_L = (P^x_L)^T x - x_L\f$, + * \f$Sl^x_U = x_U - (P^x_U)^T x\f$, \f$Sl^d_L = (P^d_L)^T d(x) - d_L\f$, + * \f$Sl^d_U = d_U - (P^d_U)^T d(x)\f$. The results returned to the + * caller is \f$res = \alpha * sol + \beta * res\f$. + * + * The solution of this linear system (in order to compute the search + * direction of the algorthim) usually requires a considerable amount of + * computation time. Therefore, it is important to tailor the solution + * of this system to the characteristics of the problem. The purpose of + * this base class is to provide a generic interface to the algorithm + * that it can use whenever it requires a solution of the above system. + * Particular implementation can then be written to provide the methods + * defined here. + * + * It is implicitly assumed here, that the upper left 2 by 2 block + * is possibly modified (implicitly or explicitly) so that its + * projection onto the null space of the overall constraint + * Jacobian \f$\left[\begin{array}{cc}J_c & 0\\J_d & + * -I\end{array}\right]\f$ is positive definite. This is necessary + * to guarantee certain descent properties of the resulting search + * direction. For example, in the full space implementation, a + * multiple of the identity might be added to the upper left 2 by 2 + * block. + * + * Note that the Solve method might be called several times for different + * right hand sides, but with identical data. Therefore, if possible, + * an implemetation of PDSystem should check whether the incoming data has + * changed, and not redo factorization etc. unless necessary. + */ + class PDSystemSolver: public AlgorithmStrategyObject + { + public: + /** @name /Destructor */ + //@{ + /** Default Constructor */ + PDSystemSolver() + {} + + /** Default destructor */ + virtual ~PDSystemSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Solve the primal dual system, given one right hand side. If + * the flag allow_inexact is set to true, it is not necessary to + * solve the system to best accuracy; for example, we don't want + * iterative refinement during the computation of the second + * order correction. On the other hand, if improve_solution is + * true, the solution given in res should be improved (here beta + * has to be zero, and res is assume to be the solution for the + * system using rhs, without the factor alpha...). THe return + * value is false, if a solution could not be computed (for + * example, when the Hessian regularization parameter becomes too + * large.) + */ + virtual bool Solve(Number alpha, + Number beta, + const IteratesVector& rhs, + IteratesVector& res, + bool allow_inexact=false, + bool improve_solution=false) =0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Overloaded Equals Operator */ + PDSystemSolver& operator=(const PDSystemSolver&); + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpReferenced.hpp b/thirdparty/linux/include/coin1/IpReferenced.hpp new file mode 100644 index 0000000..996beda --- /dev/null +++ b/thirdparty/linux/include/coin1/IpReferenced.hpp @@ -0,0 +1,258 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReferenced.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPREFERENCED_HPP__ +#define __IPREFERENCED_HPP__ + +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +#include <list> + +#if COIN_IPOPT_CHECKLEVEL > 3 + #define IP_DEBUG_REFERENCED +#endif + +namespace Ipopt +{ + + /** Psydo-class, from which everything has to inherit that wants to + * use be registered as a Referencer for a ReferencedObject. + */ + class Referencer + {} + ; + + /** ReferencedObject class. + * This is part of the implementation of an intrusive smart pointer + * design. This class stores the reference count of all the smart + * pointers that currently reference it. See the documentation for + * the SmartPtr class for more details. + * + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * For every most derived object only one ReferencedObject may exist, + * that is multiple inheritance requires virtual inheritance, see also + * the 2nd point in ticket #162. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + class ReferencedObject + { + public: + ReferencedObject() + : + reference_count_(0) + {} + + virtual ~ReferencedObject() + { + DBG_ASSERT(reference_count_ == 0); + } + + inline + Index ReferenceCount() const; + + inline + void AddRef(const Referencer* referencer) const; + + inline + void ReleaseRef(const Referencer* referencer) const; + + private: + mutable Index reference_count_; + +# ifdef IP_DEBUG_REFERENCED + mutable std::list<const Referencer*> referencers_; +# endif + + }; + + /* inline methods */ + inline + Index ReferencedObject::ReferenceCount() const + { + // DBG_START_METH("ReferencedObject::ReferenceCount()", 0); + // DBG_PRINT((1,"Returning reference_count_ = %d\n", reference_count_)); + return reference_count_; + } + + inline + void ReferencedObject::AddRef(const Referencer* referencer) const + { + // DBG_START_METH("ReferencedObject::AddRef(const Referencer* referencer)", 0); + reference_count_++; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); +# ifdef IP_DEBUG_REFERENCED + referencers_.push_back(referencer); +# endif + + } + + inline + void ReferencedObject::ReleaseRef(const Referencer* referencer) const + { + // DBG_START_METH("ReferencedObject::ReleaseRef(const Referencer* referencer)", + // 0); + reference_count_--; + // DBG_PRINT((1, "New reference_count_ = %d\n", reference_count_)); + +# ifdef IP_DEBUG_REFERENCED + + bool found = false; + std::list<const Referencer*>::iterator iter; + for (iter = referencers_.begin(); iter != referencers_.end(); iter++) { + if ((*iter) == referencer) { + found = true; + break; + } + } + + // cannot call release on a reference that was never added... + DBG_ASSERT(found); + + if (found) { + referencers_.erase(iter); + } +# endif + + } + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpRegOptions.hpp b/thirdparty/linux/include/coin1/IpRegOptions.hpp new file mode 100644 index 0000000..5859493 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpRegOptions.hpp @@ -0,0 +1,658 @@ +// Copyright (C) 2004, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpRegOptions.hpp 2189 2013-03-31 15:06:11Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-06-18 + +#ifndef __IPREGOPTIONS_HPP__ +#define __IPREGOPTIONS_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpSmartPtr.hpp" + +#include <map> + +namespace Ipopt +{ + + enum RegisteredOptionType + { + OT_Number, + OT_Integer, + OT_String, + OT_Unknown + }; + + /** Base class for registered options. The derived types are more + * specific to a string option or a Number (real) option, etc. + */ + class RegisteredOption : public ReferencedObject + { + public: + /** class to hold the valid string settings for a string option */ + class string_entry + { + public: + string_entry(const std::string& value, const std::string& description) + : value_(value), description_(description) + {} + std::string value_; + std::string description_; + }; + + /** Constructors / Destructors */ + //@{ + RegisteredOption(Index counter) + : + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const std::string& name, + const std::string& short_description, + const std::string& long_description, + const std::string& registering_category, + Index counter) + : + name_(name), + short_description_(short_description), + long_description_(long_description), + registering_category_(registering_category), + type_(OT_Unknown), + has_lower_(false), + has_upper_(false), + counter_(counter) + {} + + RegisteredOption(const RegisteredOption& copy) + : + name_(copy.name_), + short_description_(copy.short_description_), + long_description_(copy.long_description_), + registering_category_(copy.registering_category_), + type_(copy.type_), + has_lower_(copy.has_lower_), + lower_(copy.lower_), + has_upper_(copy.has_upper_), + upper_(copy.upper_), + valid_strings_(copy.valid_strings_), + counter_(copy.counter_) + {} + + virtual ~RegisteredOption() + {} + //@} + + DECLARE_STD_EXCEPTION(ERROR_CONVERTING_STRING_TO_ENUM); + + /** Standard Get / Set Methods */ + //@{ + /** Get the option's name (tag in the input file) */ + virtual const std::string& Name() const + { + return name_; + } + /** Set the option's name (tag in the input file) */ + virtual void SetName(const std::string& name) + { + name_ = name; + } + /** Get the short description */ + virtual const std::string& ShortDescription() const + { + return short_description_; + } + /** Get the long description */ + virtual const std::string& LongDescription() const + { + return long_description_; + } + /** Set the short description */ + virtual void SetShortDescription(const std::string& short_description) + { + short_description_ = short_description; + } + /** Set the long description */ + virtual void SetLongDescription(const std::string& long_description) + { + long_description_ = long_description; + } + /** Get the registering class */ + virtual const std::string& RegisteringCategory() const + { + return registering_category_; + } + /** Set the registering class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + registering_category_ = registering_category; + } + /** Get the Option's type */ + virtual const RegisteredOptionType& Type() const + { + return type_; + } + /** Get the Option's type */ + virtual void SetType(const RegisteredOptionType& type) + { + type_ = type; + } + /** Counter */ + virtual Index Counter() const + { + return counter_; + } + //@} + + /** @name Get / Set methods valid for specific types - NOTE: the Type + * must be set before calling these methods. + */ + //@{ + /** check if the option has a lower bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasLower() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_lower_; + } + /** check if the lower bound is strict - can be called for + OT_Number */ + virtual const bool& LowerStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_lower_ == true); + return lower_strict_; + } + /** get the Number version of the lower bound - can be called for + * OT_Number */ + virtual Number LowerNumber() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Number); + return lower_; + } + /** set the Number version of the lower bound - can be called for + * OT_Number */ + virtual void SetLowerNumber(const Number& lower, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + lower_ = lower; + lower_strict_ = strict, has_lower_ = true; + } + /** get the Integer version of the lower bound can be called for + * OT_Integer*/ + virtual Index LowerInteger() const + { + DBG_ASSERT(has_lower_ == true && type_ == OT_Integer); + return (Index)lower_; + } + /** set the Integer version of the lower bound - can be called for + * OT_Integer */ + virtual void SetLowerInteger(const Index& lower) + { + DBG_ASSERT(type_ == OT_Integer); + lower_ = (Number)lower; + has_lower_ = true; + } + /** check if the option has an upper bound - can be called for + * OT_Number & OT_Integer*/ + virtual const bool& HasUpper() const + { + DBG_ASSERT(type_ == OT_Number || type_ == OT_Integer); + return has_upper_; + } + /** check if the upper bound is strict - can be called for + * OT_Number */ + virtual const bool& UpperStrict() const + { + DBG_ASSERT(type_ == OT_Number && has_upper_ == true); + return upper_strict_; + } + /** get the Number version of the upper bound - can be called for + * OT_Number */ + virtual Number UpperNumber() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Number); + return upper_; + } + /** set the Number version of the upper bound - can be called for + * OT_Number */ + virtual void SetUpperNumber(const Number& upper, const bool& strict) + { + DBG_ASSERT(type_ == OT_Number); + upper_ = upper; + upper_strict_ = strict; + has_upper_ = true; + } + /** get the Integer version of the upper bound - can be called for + * OT_Integer*/ + virtual Index UpperInteger() const + { + DBG_ASSERT(has_upper_ == true && type_ == OT_Integer); + return (Index)upper_; + } + /** set the Integer version of the upper bound - can be called for + * OT_Integer */ + virtual void SetUpperInteger(const Index& upper) + { + DBG_ASSERT(type_ == OT_Integer); + upper_ = (Number)upper; + has_upper_ = true; + } + /** method to add valid string entries - can be called for + * OT_String */ + virtual void AddValidStringSetting(const std::string value, + const std::string description) + { + DBG_ASSERT(type_ == OT_String); + valid_strings_.push_back(string_entry(value, description)); + } + /** get the default as a Number - can be called for OT_Number */ + virtual Number DefaultNumber() const + { + DBG_ASSERT(type_ == OT_Number); + return default_number_; + } + /** Set the default as a Number - can be called for OT_Number */ + virtual void SetDefaultNumber(const Number& default_value) + { + DBG_ASSERT(type_ == OT_Number); + default_number_ = default_value; + } + /** get the default as an Integer - can be called for OT_Integer*/ + virtual Index DefaultInteger() const + { + DBG_ASSERT(type_ == OT_Integer); + return (Index)default_number_; + } + /** Set the default as an Integer - can be called for + OT_Integer */ + virtual void SetDefaultInteger(const Index& default_value) + { + DBG_ASSERT(type_ == OT_Integer); + default_number_ = (Number)default_value; + } + /** get the default as a string - can be called for OT_String */ + virtual std::string DefaultString() const + { + DBG_ASSERT(type_ == OT_String); + return default_string_; + } + /** get the default as a string, but as the index of the string in + * the list - helps map from a string to an enum- can be called + * for OT_String */ + virtual Index DefaultStringAsEnum() const + { + DBG_ASSERT(type_ == OT_String); + return MapStringSettingToEnum(default_string_); + } + /** Set the default as a string - can be called for OT_String */ + virtual void SetDefaultString(const std::string& default_value) + { + DBG_ASSERT(type_ == OT_String); + default_string_ = default_value; + } + /** get the valid string settings - can be called for OT_String */ + virtual std::vector<string_entry> GetValidStrings() const + { + DBG_ASSERT(type_ == OT_String); + return valid_strings_; + } + /** Check if the Number value is a valid setting - can be called + * for OT_Number */ + virtual bool IsValidNumberSetting(const Number& value) const + { + DBG_ASSERT(type_ == OT_Number); + if (has_lower_ && ((lower_strict_ == true && value <= lower_) || + (lower_strict_ == false && value < lower_))) { + return false; + } + if (has_upper_ && ((upper_strict_ == true && value >= upper_) || + (upper_strict_ == false && value > upper_))) { + return false; + } + return true; + } + /** Check if the Integer value is a valid setting - can be called + * for OT_Integer */ + virtual bool IsValidIntegerSetting(const Index& value) const + { + DBG_ASSERT(type_ == OT_Integer); + if (has_lower_ && value < lower_) { + return false; + } + if (has_upper_ && value > upper_) { + return false; + } + return true; + } + /** Check if the String value is a valid setting - can be called + * for OT_String */ + virtual bool IsValidStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the case used when + * the setting was registered. + */ + virtual std::string MapStringSetting(const std::string& value) const; + + /** Map a user setting (allowing any case) to the index of the + * matched setting in the list of string settings. Helps map a + * string setting to an enumeration. + */ + virtual Index MapStringSettingToEnum(const std::string& value) const; + //@} + + /** output a description of the option */ + virtual void OutputDescription(const Journalist& jnlst) const; + /** output a more concise version */ + virtual void OutputShortDescription(const Journalist& jnlst) const; + /** output a latex version */ + virtual void OutputLatexDescription(const Journalist& jnlst) const; + + private: + std::string name_; + std::string short_description_; + std::string long_description_; + std::string registering_category_; + RegisteredOptionType type_; + + bool has_lower_; + bool lower_strict_; + Number lower_; + bool has_upper_; + bool upper_strict_; + Number upper_; + Number default_number_; + + void MakeValidLatexString(std::string source, std::string& dest) const; + std::string MakeValidLatexNumber(Number value) const; + + /** Compare two strings and return true if they are equal (case + insensitive comparison) */ + bool string_equal_insensitive(const std::string& s1, + const std::string& s2) const; + + std::vector<string_entry> valid_strings_; + std::string default_string_; + + /** Has the information as how many-th option this one was + * registered. */ + const Index counter_; + }; + + /** Class for storing registered options. Used for validation and + * documentation. + */ + class RegisteredOptions : public ReferencedObject + { + public: + /** Constructors / Destructors */ + //@{ + /** Standard Constructor */ + RegisteredOptions() + : + next_counter_(0), + current_registering_category_("Uncategorized") + {} + + /** Standard Destructor */ + virtual ~RegisteredOptions() + {} + //@} + + DECLARE_STD_EXCEPTION(OPTION_ALREADY_REGISTERED); + + /** Methods to interact with registered options */ + //@{ + /** set the registering class. All subsequent options will be + * added with the registered class */ + virtual void SetRegisteringCategory(const std::string& registering_category) + { + current_registering_category_ = registering_category; + } + + /** retrieve the value of the current registering category */ + virtual std::string RegisteringCategory() + { + return current_registering_category_; + } + + /** Add a Number option (with no restrictions) */ + virtual void AddNumberOption(const std::string& name, + const std::string& short_description, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a lower bound) */ + virtual void AddLowerBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a upper bound) */ + virtual void AddUpperBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number upper, bool strict, + Number default_value, + const std::string& long_description=""); + /** Add a Number option (with a both bounds) */ + virtual void AddBoundedNumberOption(const std::string& name, + const std::string& short_description, + Number lower, bool lower_strict, + Number upper, bool upper_strict, + Number default_value, + const std::string& long_description=""); + /** Add a Integer option (with no restrictions) */ + virtual void AddIntegerOption(const std::string& name, + const std::string& short_description, + Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a lower bound) */ + virtual void AddLowerBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a upper bound) */ + virtual void AddUpperBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index upper, Index default_value, + const std::string& long_description=""); + /** Add a Integer option (with a both bounds) */ + virtual void AddBoundedIntegerOption(const std::string& name, + const std::string& short_description, + Index lower, Index upper, + Index default_value, + const std::string& long_description=""); + + /** Add a String option (with no restrictions) */ + virtual void AddStringOption(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::vector<std::string>& settings, + const std::vector<std::string>& descriptions, + const std::string& long_description=""); + /** Methods that make adding string options with only a few + * entries easier */ + virtual void AddStringOption1(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& long_description=""); + virtual void AddStringOption2(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& long_description=""); + virtual void AddStringOption3(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& long_description=""); + virtual void AddStringOption4(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& long_description=""); + virtual void AddStringOption5(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& long_description=""); + virtual void AddStringOption6(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& long_description=""); + virtual void AddStringOption7(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& long_description=""); + virtual void AddStringOption8(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& long_description=""); + virtual void AddStringOption9(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& long_description=""); + virtual void AddStringOption10(const std::string& name, + const std::string& short_description, + const std::string& default_value, + const std::string& setting1, + const std::string& description1, + const std::string& setting2, + const std::string& description2, + const std::string& setting3, + const std::string& description3, + const std::string& setting4, + const std::string& description4, + const std::string& setting5, + const std::string& description5, + const std::string& setting6, + const std::string& description6, + const std::string& setting7, + const std::string& description7, + const std::string& setting8, + const std::string& description8, + const std::string& setting9, + const std::string& description9, + const std::string& setting10, + const std::string& description10, + const std::string& long_description=""); + + /** Get a registered option - this will return NULL if the option + * does not exist */ + virtual SmartPtr<const RegisteredOption> GetOption(const std::string& name); + + /** Output documentation for the options - gives a description, + * etc. */ + virtual void OutputOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories); + + /** Output documentation in Latex format to include in a latex file */ + virtual void OutputLatexOptionDocumentation(const Journalist& jnlst, std::list<std::string>& categories); + //@} + + typedef std::map<std::string, SmartPtr<RegisteredOption> > RegOptionsList; + + /** Giving access to iteratable representation of the registered + * options */ + virtual const RegOptionsList& RegisteredOptionsList () const + { + return registered_options_; + } + + private: + Index next_counter_; + std::string current_registering_category_; + std::map<std::string, SmartPtr<RegisteredOption> > registered_options_; + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpReturnCodes.h b/thirdparty/linux/include/coin1/IpReturnCodes.h new file mode 100644 index 0000000..b16d2c6 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpReturnCodes.h @@ -0,0 +1,18 @@ +/*********************************************************************** +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.h 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +#ifndef __IPRETURNCODES_H__ +#define __IPRETURNCODES_H__ + +/* include from a common include file */ + +#include "IpReturnCodes_inc.h" + +#endif diff --git a/thirdparty/linux/include/coin1/IpReturnCodes.hpp b/thirdparty/linux/include/coin1/IpReturnCodes.hpp new file mode 100644 index 0000000..36dd7d7 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpReturnCodes.hpp @@ -0,0 +1,21 @@ +/*********************************************************************** +// Copyright (C) 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2006-03-01 +************************************************************************/ + +#ifndef __IPRETURNCODES_HPP__ +#define __IPRETURNCODES_HPP__ + +/* include from a common include file */ + +namespace Ipopt +{ +#include "IpReturnCodes_inc.h" +} + +#endif diff --git a/thirdparty/linux/include/coin1/IpReturnCodes.inc b/thirdparty/linux/include/coin1/IpReturnCodes.inc new file mode 100644 index 0000000..c6bf70a --- /dev/null +++ b/thirdparty/linux/include/coin1/IpReturnCodes.inc @@ -0,0 +1,70 @@ +C Copyright (C) 2005, 2009 International Business Machines and others. +C All Rights Reserved. +C This code is published under the Eclipse Public License. +C +C $Id: IpReturnCodes.inc 1861 2010-12-21 21:34:47Z andreasw $ +C +C Author: Andreas Waechter IBM 2005-08-11 +C + INTEGER IP_SOLVE_SUCCEEDED + PARAMETER( IP_SOLVE_SUCCEEDED = 0 ) + + INTEGER IP_ACCEPTABLE_LEVEL + PARAMETER( IP_ACCEPTABLE_LEVEL = 1 ) + + INTEGER IP_INFEASIBLE_PROBLEM + PARAMETER( IP_INFEASIBLE_PROBLEM = 2 ) + + INTEGER IP_SEARCH_DIRECTION_TOO_SMALL + PARAMETER( IP_SEARCH_DIRECTION_TOO_SMALL = 3 ) + + INTEGER IP_DIVERGING_ITERATES + PARAMETER( IP_DIVERGING_ITERATES = 4 ) + + INTEGER IP_USER_REQUESTED_STOP + PARAMETER( IP_USER_REQUESTED_STOP = 5 ) + + INTEGER IP_FEASIBLE_POINT_FOUND + PARAMETER( IP_FEASIBLE_POINT_FOUND = 6 ) + + INTEGER IP_ITERATION_EXCEEDED + PARAMETER( IP_ITERATION_EXCEEDED = -1 ) + + INTEGER IP_RESTORATION_FAILED + PARAMETER( IP_RESTORATION_FAILED = -2 ) + + INTEGER IP_ERROR_IN_STEP_COMPUTATION + PARAMETER( IP_ERROR_IN_STEP_COMPUTATION = -3 ) + + INTEGER IP_CPUTIME_EXCEEDED + PARAMETER( IP_CPUTIME_EXCEEDED = -4 ) + + INTEGER IP_NOT_ENOUGH_DEGREES_OF_FRE + PARAMETER( IP_NOT_ENOUGH_DEGREES_OF_FRE = -10 ) + + INTEGER IP_INVALID_PROBLEM_DEFINITION + PARAMETER( IP_INVALID_PROBLEM_DEFINITION = -11) + + INTEGER IP_INVALID_OPTION + PARAMETER( IP_INVALID_OPTION = -12 ) + + INTEGER IP_INVALID_NUMBER_DETECTED + PARAMETER( IP_INVALID_NUMBER_DETECTED = -13 ) + + INTEGER IP_UNRECOVERABLE_EXCEPTION + PARAMETER( IP_UNRECOVERABLE_EXCEPTION = -100 ) + + INTEGER IP_NON_IPOPT_EXCEPTION + PARAMETER( IP_NON_IPOPT_EXCEPTION = -101 ) + + INTEGER IP_INSUFFICIENT_MEMORY + PARAMETER( IP_INSUFFICIENT_MEMORY = -102 ) + + INTEGER IP_INTERNAL_ERROR + PARAMETER( IP_INTERNAL_ERROR = -199 ) + + INTEGER IP_REGULAR_MODE + PARAMETER( IP_REGULAR_MODE = 0 ) + + INTEGER IP_RESTORATION_PHASE_MODE + PARAMETER( IP_RESTORATION_PHASE_MODE = 1 ) diff --git a/thirdparty/linux/include/coin1/IpReturnCodes_inc.h b/thirdparty/linux/include/coin1/IpReturnCodes_inc.h new file mode 100644 index 0000000..80190ed --- /dev/null +++ b/thirdparty/linux/include/coin1/IpReturnCodes_inc.h @@ -0,0 +1,46 @@ +/*********************************************************************** +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpReturnCodes_inc.h 2216 2013-04-14 17:06:00Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 +************************************************************************/ + +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ +/* !!!!!!!!! REMEMBER TO UPDATE IpReturnCodes.inc and Ipopt.java !!!!!!!! */ +/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ + +/** Return codes for the Optimize call for an application */ +enum ApplicationReturnStatus + { + Solve_Succeeded=0, + Solved_To_Acceptable_Level=1, + Infeasible_Problem_Detected=2, + Search_Direction_Becomes_Too_Small=3, + Diverging_Iterates=4, + User_Requested_Stop=5, + Feasible_Point_Found=6, + + Maximum_Iterations_Exceeded=-1, + Restoration_Failed=-2, + Error_In_Step_Computation=-3, + Maximum_CpuTime_Exceeded=-4, + Not_Enough_Degrees_Of_Freedom=-10, + Invalid_Problem_Definition=-11, + Invalid_Option=-12, + Invalid_Number_Detected=-13, + + Unrecoverable_Exception=-100, + NonIpopt_Exception_Thrown=-101, + Insufficient_Memory=-102, + Internal_Error=-199 + }; + +/** enum to indicate the mode in which the algorithm is */ +enum AlgorithmMode + { + RegularMode=0, + RestorationPhaseMode=1 + }; diff --git a/thirdparty/linux/include/coin1/IpScaledMatrix.hpp b/thirdparty/linux/include/coin1/IpScaledMatrix.hpp new file mode 100644 index 0000000..c182a05 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpScaledMatrix.hpp @@ -0,0 +1,254 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSCALEDMATRIX_HPP__ +#define __IPSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class ScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class ScaledMatrix : public Matrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + ScaledMatrix(const ScaledMatrixSpace* owner_space); + + /** Destructor */ + ~ScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr<const Matrix> unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr<Matrix>& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr<const Matrix> GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr<Matrix> GetUnscaledMatrixNonConst(); + + /** return the vector for the row scaling */ + SmartPtr<const Vector> RowScaling() const; + + /** return the vector for the column scaling */ + SmartPtr<const Vector> ColumnScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed that the scaling factors are + * valid. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + + /** X = beta*X + alpha*(Matrix S^{-1} Z). Specialized + * implementation missing so far! + */ + virtual void AddMSinvZImpl(Number alpha, const Vector& S, const Vector& Z, + Vector& X) const; + + /** X = S^{-1} (r + alpha*Z*M^Td). Specialized implementation + * missing so far! + */ + virtual void SinvBlrmZMTdBrImpl(Number alpha, const Vector& S, + const Vector& R, const Vector& Z, + const Vector& D, Vector& X) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ScaledMatrix(); + + /** Copy Constructor */ + ScaledMatrix(const ScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr<const Matrix> matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr<Matrix> nonconst_matrix_; + + /** Matrix space stored as a ScaledMatrixSpace */ + SmartPtr<const ScaledMatrixSpace> owner_space_; + }; + + /** This is the matrix space for ScaledMatrix. + */ + class ScaledMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + ScaledMatrixSpace(const SmartPtr<const Vector>& row_scaling, + bool row_scaling_reciprocal, + const SmartPtr<const MatrixSpace>& unscaled_matrix_space, + const SmartPtr<const Vector>& column_scaling, + bool column_scaling_reciprocal); + + /** Destructor */ + ~ScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + ScaledMatrix* MakeNewScaledMatrix(bool allocate_unscaled_matrix = false) const + { + ScaledMatrix* ret = new ScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr<Matrix> unscaled_matrix = unscaled_matrix_space_->MakeNew(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewScaledMatrix(); + } + + /** return the vector for the row scaling */ + SmartPtr<const Vector> RowScaling() const + { + return ConstPtr(row_scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr<const MatrixSpace> UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + /** return the vector for the column scaling */ + SmartPtr<const Vector> ColumnScaling() const + { + return ConstPtr(column_scaling_); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + ScaledMatrixSpace(); + + /** Copy Constructor */ + ScaledMatrixSpace(const ScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + ScaledMatrixSpace& operator=(const ScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr<Vector> row_scaling_; + /** unscaled matrix space */ + SmartPtr<const MatrixSpace> unscaled_matrix_space_; + /** column scaling vector */ + SmartPtr<Vector> column_scaling_; + }; + + inline + void ScaledMatrix::SetUnscaledMatrix(const SmartPtr<const Matrix> unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void ScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr<Matrix>& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr<const Matrix> ScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr<Matrix> ScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline + SmartPtr<const Vector> ScaledMatrix::RowScaling() const + { + return ConstPtr(owner_space_->RowScaling()); + } + + inline + SmartPtr<const Vector> ScaledMatrix::ColumnScaling() const + { + return ConstPtr(owner_space_->ColumnScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpSearchDirCalculator.hpp b/thirdparty/linux/include/coin1/IpSearchDirCalculator.hpp new file mode 100644 index 0000000..3425c43 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSearchDirCalculator.hpp @@ -0,0 +1,65 @@ +// Copyright (C) 2005, 2007 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSearchDirCalculator.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-10-13 + +#ifndef __IPSEARCHDIRCALCULATOR_HPP__ +#define __IPSEARCHDIRCALCULATOR_HPP__ + +#include "IpAlgStrategy.hpp" + +namespace Ipopt +{ + + /** Base class for computing the search direction for the line + * search. + */ + class SearchDirectionCalculator : public AlgorithmStrategyObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor */ + SearchDirectionCalculator() + {} + + /** Default destructor */ + virtual ~SearchDirectionCalculator() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** Pure virtual method for computing the search direction. The + * computed direction is stored in IpData().delta().*/ + virtual bool ComputeSearchDirection()=0; + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + // SearchDirectionCalculator(); + + /** Copy Constructor */ + SearchDirectionCalculator(const SearchDirectionCalculator&); + + /** Overloaded Equals Operator */ + void operator=(const SearchDirectionCalculator&); + //@} + + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpSmartPtr.hpp b/thirdparty/linux/include/coin1/IpSmartPtr.hpp new file mode 100644 index 0000000..dec0ab5 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSmartPtr.hpp @@ -0,0 +1,734 @@ +// Copyright (C) 2004, 2011 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSmartPtr.hpp 2182 2013-03-30 20:02:18Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSMARTPTR_HPP__ +#define __IPSMARTPTR_HPP__ + +#include "IpReferenced.hpp" + +#include "IpDebug.hpp" +#if COIN_IPOPT_CHECKLEVEL > 2 +# define IP_DEBUG_SMARTPTR +#endif +#ifndef IPOPT_UNUSED +# if defined(__GNUC__) +# define IPOPT_UNUSED __attribute__((unused)) +# else +# define IPOPT_UNUSED +# endif +#endif + +namespace Ipopt +{ + + /** Template class for Smart Pointers. + * A SmartPtr behaves much like a raw pointer, but manages the lifetime + * of an object, deleting the object automatically. This class implements + * a reference-counting, intrusive smart pointer design, where all + * objects pointed to must inherit off of ReferencedObject, which + * stores the reference count. Although this is intrusive (native types + * and externally authored classes require wrappers to be referenced + * by smart pointers), it is a safer design. A more detailed discussion of + * these issues follows after the usage information. + * + * Usage Example: + * Note: to use the SmartPtr, all objects to which you point MUST + * inherit off of ReferencedObject. + * + * \verbatim + * + * In MyClass.hpp... + * + * #include "IpReferenced.hpp" + + * namespace Ipopt { + * + * class MyClass : public ReferencedObject // must derive from ReferencedObject + * { + * ... + * } + * } // namespace Ipopt + * + * + * In my_usage.cpp... + * + * #include "IpSmartPtr.hpp" + * #include "MyClass.hpp" + * + * void func(AnyObject& obj) + * { + * SmartPtr<MyClass> ptr_to_myclass = new MyClass(...); + * // ptr_to_myclass now points to a new MyClass, + * // and the reference count is 1 + * + * ... + * + * obj.SetMyClass(ptr_to_myclass); + * // Here, let's assume that AnyObject uses a + * // SmartPtr<MyClass> internally here. + * // Now, both ptr_to_myclass and the internal + * // SmartPtr in obj point to the same MyClass object + * // and its reference count is 2. + * + * ... + * + * // No need to delete ptr_to_myclass, this + * // will be done automatically when the + * // reference count drops to zero. + * + * } + * + * \endverbatim + * + * It is not necessary to use SmartPtr's in all cases where an + * object is used that has been allocated "into" a SmartPtr. It is + * possible to just pass objects by reference or regular pointers, + * even if lower down in the stack a SmartPtr is to be held on to. + * Everything should work fine as long as a pointer created by "new" + * is immediately passed into a SmartPtr, and if SmartPtr's are used + * to hold on to objects. + * + * Other Notes: + * The SmartPtr implements both dereference operators -> & *. + * The SmartPtr does NOT implement a conversion operator to + * the raw pointer. Use the GetRawPtr() method when this + * is necessary. Make sure that the raw pointer is NOT + * deleted. + * The SmartPtr implements the comparison operators == & != + * for a variety of types. Use these instead of + * \verbatim + * if (GetRawPtr(smrt_ptr) == ptr) // Don't use this + * \endverbatim + * SmartPtr's, as currently implemented, do NOT handle circular references. + * For example: consider a higher level object using SmartPtrs to point to + * A and B, but A and B also point to each other (i.e. A has a SmartPtr + * to B and B has a SmartPtr to A). In this scenario, when the higher + * level object is finished with A and B, their reference counts will + * never drop to zero (since they reference each other) and they + * will not be deleted. This can be detected by memory leak tools like + * valgrind. If the circular reference is necessary, the problem can be + * overcome by a number of techniques: + * + * 1) A and B can have a method that "releases" each other, that is + * they set their internal SmartPtrs to NULL. + * \verbatim + * void AClass::ReleaseCircularReferences() + * { + * smart_ptr_to_B = NULL; + * } + * \endverbatim + * Then, the higher level class can call these methods before + * it is done using A & B. + * + * 2) Raw pointers can be used in A and B to reference each other. + * Here, an implicit assumption is made that the lifetime is + * controlled by the higher level object and that A and B will + * both exist in a controlled manner. Although this seems + * dangerous, in many situations, this type of referencing + * is very controlled and this is reasonably safe. + * + * 3) This SmartPtr class could be redesigned with the Weak/Strong + * design concept. Here, the SmartPtr is identified as being + * Strong (controls lifetime of the object) or Weak (merely + * referencing the object). The Strong SmartPtr increments + * (and decrements) the reference count in ReferencedObject + * but the Weak SmartPtr does not. In the example above, + * the higher level object would have Strong SmartPtrs to + * A and B, but A and B would have Weak SmartPtrs to each + * other. Then, when the higher level object was done with + * A and B, they would be deleted. The Weak SmartPtrs in A + * and B would not decrement the reference count and would, + * of course, not delete the object. This idea is very similar + * to item (2), where it is implied that the sequence of events + * is controlled such that A and B will not call anything using + * their pointers following the higher level delete (i.e. in + * their destructors!). This is somehow safer, however, because + * code can be written (however expensive) to perform run-time + * detection of this situation. For example, the ReferencedObject + * could store pointers to all Weak SmartPtrs that are referencing + * it and, in its destructor, tell these pointers that it is + * dying. They could then set themselves to NULL, or set an + * internal flag to detect usage past this point. + * + * Comments on Non-Intrusive Design: + * In a non-intrusive design, the reference count is stored somewhere other + * than the object being referenced. This means, unless the reference + * counting pointer is the first referencer, it must get a pointer to the + * referenced object from another smart pointer (so it has access to the + * reference count location). In this non-intrusive design, if we are + * pointing to an object with a smart pointer (or a number of smart + * pointers), and we then give another smart pointer the address through + * a RAW pointer, we will have two independent, AND INCORRECT, reference + * counts. To avoid this pitfall, we use an intrusive reference counting + * technique where the reference count is stored in the object being + * referenced. + */ + template<class T> + class SmartPtr : public Referencer + { + public: +#define ipopt_dbg_smartptr_verbosity 0 + + /**@name Constructors/Destructors */ + //@{ + /** Default constructor, initialized to NULL */ + SmartPtr(); + + /** Copy constructor, initialized from copy of type T */ + SmartPtr(const SmartPtr<T>& copy); + + /** Copy constructor, initialized from copy of type U */ + template <class U> + SmartPtr(const SmartPtr<U>& copy); + + /** Constructor, initialized from T* ptr */ + SmartPtr(T* ptr); + + /** Destructor, automatically decrements the + * reference count, deletes the object if + * necessary.*/ + ~SmartPtr(); + //@} + + /**@name Overloaded operators. */ + //@{ + /** Overloaded arrow operator, allows the user to call + * methods using the contained pointer. */ + T* operator->() const; + + /** Overloaded dereference operator, allows the user + * to dereference the contained pointer. */ + T& operator*() const; + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from a raw pointer */ + SmartPtr<T>& operator=(T* rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr */ + SmartPtr<T>& operator=(const SmartPtr<T>& rhs); + + /** Overloaded equals operator, allows the user to + * set the value of the SmartPtr from another + * SmartPtr of a different type */ + template <class U> + SmartPtr<T>& operator=(const SmartPtr<U>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded equality comparison operator, allows the + * user to compare the value of a raw pointer with a SmartPtr. */ + template <class U1, class U2> + friend + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + /** Overloaded in-equality comparison operator, allows the + * user to compare the value of a SmartPtr with a raw pointer. */ + template <class U1, class U2> + friend + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + + /** Overloaded less-than comparison operator, allows the + * user to compare the value of two SmartPtrs */ + template <class U> + friend + bool operator<(const SmartPtr<U>& lhs, const SmartPtr<U>& rhs); + //@} + + /**@name friend method declarations. */ + //@{ + /** Returns the raw pointer contained. + * Use to get the value of + * the raw ptr (i.e. to pass to other + * methods/functions, etc.) + * Note: This method does NOT copy, + * therefore, modifications using this + * value modify the underlying object + * contained by the SmartPtr, + * NEVER delete this returned value. + */ + template <class U> + friend + U* GetRawPtr(const SmartPtr<U>& smart_ptr); + + /** Returns a const pointer */ + template <class U> + friend + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr); + + /** Returns true if the SmartPtr is NOT NULL. + * Use this to check if the SmartPtr is not null + * This is preferred to if(GetRawPtr(sp) != NULL) + */ + template <class U> + friend + bool IsValid(const SmartPtr<U>& smart_ptr); + + /** Returns true if the SmartPtr is NULL. + * Use this to check if the SmartPtr IsNull. + * This is preferred to if(GetRawPtr(sp) == NULL) + */ + template <class U> + friend + bool IsNull(const SmartPtr<U>& smart_ptr); + //@} + + private: + /**@name Private Data/Methods */ + //@{ + /** Actual raw pointer to the object. */ + T* ptr_; + + /** Set the value of the internal raw pointer + * from another raw pointer, releasing the + * previously referenced object if necessary. */ + SmartPtr<T>& SetFromRawPtr_(T* rhs); + + /** Set the value of the internal raw pointer + * from a SmartPtr, releasing the previously referenced + * object if necessary. */ + SmartPtr<T>& SetFromSmartPtr_(const SmartPtr<T>& rhs); + + /** Release the currently referenced object. */ + void ReleasePointer_(); + //@} + }; + + /**@name SmartPtr friend function declarations.*/ + //@{ + template <class U> + U* GetRawPtr(const SmartPtr<U>& smart_ptr); + + template <class U> + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr); + + template <class U> + bool IsNull(const SmartPtr<U>& smart_ptr); + + template <class U> + bool IsValid(const SmartPtr<U>& smart_ptr); + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs); + + template <class U1, class U2> + bool operator==(U1* lhs, const SmartPtr<U2>& raw_rhs); + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs); + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs); + + template <class U1, class U2> + bool operator!=(U1* lhs, const SmartPtr<U2>& raw_rhs); + + //@} + + + template <class T> + SmartPtr<T>::SmartPtr() + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr()", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + } + + + template <class T> + SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<T>& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(copy); + } + + + template <class T> + template <class U> + SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(const SmartPtr<U>& copy)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromSmartPtr_(GetRawPtr(copy)); + } + + + template <class T> + SmartPtr<T>::SmartPtr(T* ptr) + : + ptr_(0) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + +#ifndef NDEBUG + const ReferencedObject* IPOPT_UNUSED trying_to_use_SmartPtr_with_an_object_that_does_not_inherit_from_ReferencedObject_ = ptr_; +#endif + + (void) SetFromRawPtr_(ptr); + } + + template <class T> + SmartPtr<T>::~SmartPtr() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>::~SmartPtr(T* ptr)", ipopt_dbg_smartptr_verbosity); +#endif + + ReleasePointer_(); + } + + + template <class T> + T* SmartPtr<T>::operator->() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T* SmartPtr<T>::operator->()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot deref a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return ptr_; + } + + + template <class T> + T& SmartPtr<T>::operator*() const + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("T& SmartPtr<T>::operator*()", ipopt_dbg_smartptr_verbosity); +#endif + + // cannot dereference a null pointer +#if COIN_IPOPT_CHECKLEVEL > 0 + assert(ptr_); +#endif + + return *ptr_; + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::operator=(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH("SmartPtr<T>& SmartPtr<T>::operator=(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromRawPtr_(rhs); + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<T>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(rhs); + } + + + template <class T> + template <class U> + SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::operator=(const SmartPtr<U>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + return SetFromSmartPtr_(GetRawPtr(rhs)); + } + + + template <class T> + SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::SetFromRawPtr_(T* rhs)", ipopt_dbg_smartptr_verbosity); +#endif + + if (rhs != 0) + rhs->AddRef(this); + + // Release any old pointer + ReleasePointer_(); + + ptr_ = rhs; + + return *this; + } + + template <class T> + SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "SmartPtr<T>& SmartPtr<T>::SetFromSmartPtr_(const SmartPtr<T>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + SetFromRawPtr_(GetRawPtr(rhs)); + + return (*this); + } + + + template <class T> + void SmartPtr<T>::ReleasePointer_() + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_METH( + "void SmartPtr<T>::ReleasePointer()", + ipopt_dbg_smartptr_verbosity); +#endif + + if (ptr_) { + ptr_->ReleaseRef(this); + if (ptr_->ReferenceCount() == 0) + delete ptr_; + } + } + + + template <class U> + U* GetRawPtr(const SmartPtr<U>& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "T* GetRawPtr(const SmartPtr<T>& smart_ptr)", + 0); +#endif + + return smart_ptr.ptr_; + } + + template <class U> + SmartPtr<const U> ConstPtr(const SmartPtr<U>& smart_ptr) + { + // compiler should implicitly cast + return GetRawPtr(smart_ptr); + } + + template <class U> + bool IsValid(const SmartPtr<U>& smart_ptr) + { + return !IsNull(smart_ptr); + } + + template <class U> + bool IsNull(const SmartPtr<U>& smart_ptr) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool IsNull(const SmartPtr<T>& smart_ptr)", + 0); +#endif + + return (smart_ptr.ptr_ == 0); + } + + + template <class U1, class U2> + bool ComparePointers(const U1* lhs, const U2* rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool ComparePtrs(const U1* lhs, const U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + // Even if lhs and rhs point to the same object + // with different interfaces U1 and U2, we cannot guarantee that + // the value of the pointers will be equivalent. We can + // guarantee this if we convert to ReferencedObject* (see also #162) + const ReferencedObject* v_lhs = lhs; + const ReferencedObject* v_rhs = rhs; + + return v_lhs == v_rhs; + } + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator==(const SmartPtr<U1>& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(SmartPtr<U1>& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + U1* raw_lhs = GetRawPtr(lhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator==(U1* raw_lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator==(U1* raw_lhs, SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + const U2* raw_rhs = GetRawPtr(rhs); + return ComparePointers(raw_lhs, raw_rhs); + } + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(const SmartPtr<U1>& lhs, const SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, rhs); + return !retValue; + } + + template <class U1, class U2> + bool operator!=(const SmartPtr<U1>& lhs, U2* raw_rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(SmartPtr<U1>& lhs, U2* rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(lhs, raw_rhs); + return !retValue; + } + + template <class U1, class U2> + bool operator!=(U1* raw_lhs, const SmartPtr<U2>& rhs) + { +#ifdef IP_DEBUG_SMARTPTR + DBG_START_FUN( + "bool operator!=(U1* raw_lhs, SmartPtr<U2>& rhs)", + ipopt_dbg_smartptr_verbosity); +#endif + + bool retValue = operator==(raw_lhs, rhs); + return !retValue; + } + + template <class T> + void swap(SmartPtr<T>& a, SmartPtr<T>& b) + { +#ifdef IP_DEBUG_REFERENCED + SmartPtr<T> tmp(a); + a = b; + b = tmp; +#else + std::swap(a.prt_, b.ptr_); +#endif + } + + template <class T> + bool operator<(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return lhs.ptr_ < rhs.ptr_; + } + + template <class T> + bool operator> (const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return rhs < lhs; + } + + template <class T> bool + operator<=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return !( rhs < lhs ); + } + + template <class T> bool + operator>=(const SmartPtr<T>& lhs, const SmartPtr<T>& rhs) + { + return !( lhs < rhs ); + } +} // namespace Ipopt + +#undef ipopt_dbg_smartptr_verbosity + +#endif diff --git a/thirdparty/linux/include/coin1/IpSolveStatistics.hpp b/thirdparty/linux/include/coin1/IpSolveStatistics.hpp new file mode 100644 index 0000000..625ddfb --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSolveStatistics.hpp @@ -0,0 +1,150 @@ +// Copyright (C) 2005, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSolveStatistics.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2005-08-15 + +#ifndef __IPSOLVESTATISTICS_HPP__ +#define __IPSOLVESTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpSmartPtr.hpp" + +namespace Ipopt +{ + // forward declaration (to avoid inclusion of too many header files) + class IpoptNLP; + class IpoptData; + class IpoptCalculatedQuantities; + + /** This class collects statistics about an optimziation run, such + * as iteration count, final infeasibilities etc. It is meant to + * provide such information to a user of Ipopt during the + * finalize_solution call. + */ + class SolveStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. It takes in those collecting Ipopt + * objects that can provide the statistics information. Those + * statistics are retrieved at the time of the constructor + * call. */ + SolveStatistics(const SmartPtr<IpoptNLP>& ip_nlp, + const SmartPtr<IpoptData>& ip_data, + const SmartPtr<IpoptCalculatedQuantities>& ip_cq); + + /** Default destructor */ + virtual ~SolveStatistics() + {} + //@} + + /** @name Accessor methods for retrieving different kind of solver + * statistics information */ + //@{ + /** Iteration counts. */ + virtual Index IterationCount() const; + /** Total CPU time, including function evaluations. */ + virtual Number TotalCpuTime() const; + /** Total CPU time, including function evaluations. Included for + * backward compatibility. */ + Number TotalCPUTime() const + { + return TotalCpuTime(); + } + /** Total System time, including function evaluations. */ + virtual Number TotalSysTime() const; + /** Total wall clock time, including function evaluations. */ + virtual Number TotalWallclockTime() const; + /** Number of NLP function evaluations. */ + virtual void NumberOfEvaluations(Index& num_obj_evals, + Index& num_constr_evals, + Index& num_obj_grad_evals, + Index& num_constr_jac_evals, + Index& num_hess_evals) const; + /** Unscaled solution infeasibilities */ + virtual void Infeasibilities(Number& dual_inf, + Number& constr_viol, + Number& complementarity, + Number& kkt_error) const; + /** Scaled solution infeasibilities */ + virtual void ScaledInfeasibilities(Number& scaled_dual_inf, + Number& scaled_constr_viol, + Number& scaled_complementarity, + Number& scaled_kkt_error) const; + /** Final value of objective function */ + virtual Number FinalObjective() const; + /** Final scaled value of objective function */ + virtual Number FinalScaledObjective() const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SolveStatistics(); + + /** Copy Constructor */ + SolveStatistics(const SolveStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const SolveStatistics&); + //@} + + /** @name Fields for storing the statistics data */ + //@{ + /** Number of iterations. */ + Index num_iters_; + /* Total CPU time */ + Number total_cpu_time_; + /* Total system time */ + Number total_sys_time_; + /* Total wall clock time */ + Number total_wallclock_time_; + /** Number of objective function evaluations. */ + Index num_obj_evals_; + /** Number of constraints evaluations (max of equality and + * inequality) */ + Index num_constr_evals_; + /** Number of objective gradient evaluations. */ + Index num_obj_grad_evals_; + /** Number of constraint Jacobian evaluations. */ + Index num_constr_jac_evals_; + /** Number of Lagrangian Hessian evaluations. */ + Index num_hess_evals_; + + /** Final scaled value of objective function */ + Number scaled_obj_val_; + /** Final unscaled value of objective function */ + Number obj_val_; + /** Final scaled dual infeasibility (max-norm) */ + Number scaled_dual_inf_; + /** Final unscaled dual infeasibility (max-norm) */ + Number dual_inf_; + /** Final scaled constraint violation (max-norm) */ + Number scaled_constr_viol_; + /** Final unscaled constraint violation (max-norm) */ + Number constr_viol_; + /** Final scaled complementarity error (max-norm) */ + Number scaled_compl_; + /** Final unscaled complementarity error (max-norm) */ + Number compl_; + /** Final overall scaled KKT error (max-norm) */ + Number scaled_kkt_error_; + /** Final overall unscaled KKT error (max-norm) */ + Number kkt_error_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpStdCInterface.h b/thirdparty/linux/include/coin1/IpStdCInterface.h new file mode 100644 index 0000000..4f11336 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpStdCInterface.h @@ -0,0 +1,271 @@ +/************************************************************************* + Copyright (C) 2004, 2010 International Business Machines and others. + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: IpStdCInterface.h 2082 2012-02-16 03:00:34Z andreasw $ + + Authors: Carl Laird, Andreas Waechter IBM 2004-09-02 + *************************************************************************/ + +#ifndef __IPSTDCINTERFACE_H__ +#define __IPSTDCINTERFACE_H__ + +#ifndef IPOPT_EXPORT +#ifdef _MSC_VER +#ifdef IPOPT_DLL +#define IPOPT_EXPORT(type) __declspec(dllexport) type __cdecl +#else +#define IPOPT_EXPORT(type) type __cdecl +#endif +#else +#define IPOPT_EXPORT(type) type +#endif +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** Type for all number. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef double Number; + + /** Type for all incides. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Index; + + /** Type for all integers. We need to make sure that this is + identical with what is defined in Common/IpTypes.hpp */ + typedef int Int; + + /* This includes the SolverReturn enum type */ +#include "IpReturnCodes.h" + + /** Structure collecting all information about the problem + * definition and solve statistics etc. This is defined in the + * source file. */ + struct IpoptProblemInfo; + + /** Pointer to a Ipopt Problem. */ + typedef struct IpoptProblemInfo* IpoptProblem; + + /** define a boolean type for C */ + typedef int Bool; +#ifndef TRUE +# define TRUE (1) +#endif +#ifndef FALSE +# define FALSE (0) +#endif + + /** A pointer for anything that is to be passed between the called + * and individual callback function */ + typedef void * UserDataPtr; + + /** Type defining the callback function for evaluating the value of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_F_CB)(Index n, Number* x, Bool new_x, + Number* obj_value, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the gradient of + * the objective function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Grad_F_CB)(Index n, Number* x, Bool new_x, + Number* grad_f, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the value of + * the constraint functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_G_CB)(Index n, Number* x, Bool new_x, + Index m, Number* g, UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Jacobian of + * the constrant functions. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_Jac_G_CB)(Index n, Number *x, Bool new_x, + Index m, Index nele_jac, + Index *iRow, Index *jCol, Number *values, + UserDataPtr user_data); + + /** Type defining the callback function for evaluating the Hessian of + * the Lagrangian function. Return value should be set to false if + * there was a problem doing the evaluation. */ + typedef Bool (*Eval_H_CB)(Index n, Number *x, Bool new_x, Number obj_factor, + Index m, Number *lambda, Bool new_lambda, + Index nele_hess, Index *iRow, Index *jCol, + Number *values, UserDataPtr user_data); + + /** Type defining the callback function for giving intermediate + * execution control to the user. If set, it is called once per + * iteration, providing the user with some information on the state + * of the optimization. This can be used to print some + * user-defined output. It also gives the user a way to terminate + * the optimization prematurely. If this method returns false, + * Ipopt will terminate the optimization. */ + typedef Bool (*Intermediate_CB)(Index alg_mod, /* 0 is regular, 1 is resto */ + Index iter_count, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, UserDataPtr user_data); + + /** Function for creating a new Ipopt Problem object. This function + * returns an object that can be passed to the IpoptSolve call. It + * contains the basic definition of the optimization problem, such + * as number of variables and constraints, bounds on variables and + * constraints, information about the derivatives, and the callback + * function for the computation of the optimization problem + * functions and derivatives. During this call, the options file + * PARAMS.DAT is read as well. + * + * If NULL is returned, there was a problem with one of the inputs + * or reading the options file. */ + IPOPT_EXPORT(IpoptProblem) CreateIpoptProblem( + Index n /** Number of optimization variables */ + , Number* x_L /** Lower bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* x_U /** Upper bounds on variables. This array of + size n is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index m /** Number of constraints. */ + , Number* g_L /** Lower bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value less or equal than + the number specified by option + 'nlp_lower_bound_inf' is interpreted to + be minus infinity. */ + , Number* g_U /** Upper bounds on constraints. This array of + size m is copied internally, so that the + caller can change the incoming data after + return without that IpoptProblem is + modified. Any value greater or equal + than the number specified by option + 'nlp_upper_bound_inf' is interpreted to + be plus infinity. */ + , Index nele_jac /** Number of non-zero elements in constraint + Jacobian. */ + , Index nele_hess /** Number of non-zero elements in Hessian of + Lagrangian. */ + , Index index_style /** indexing style for iRow & jCol, + 0 for C style, 1 for Fortran style */ + , Eval_F_CB eval_f /** Callback function for evaluating + objective function */ + , Eval_G_CB eval_g /** Callback function for evaluating + constraint functions */ + , Eval_Grad_F_CB eval_grad_f + /** Callback function for evaluating gradient + of objective function */ + , Eval_Jac_G_CB eval_jac_g + /** Callback function for evaluating Jacobian + of constraint functions */ + , Eval_H_CB eval_h /** Callback function for evaluating Hessian + of Lagrangian function */ + ); + + /** Method for freeing a previously created IpoptProblem. After + freeing an IpoptProblem, it cannot be used anymore. */ + IPOPT_EXPORT(void) FreeIpoptProblem(IpoptProblem ipopt_problem); + + + /** Function for adding a string option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptStrOption(IpoptProblem ipopt_problem, char* keyword, char* val); + + /** Function for adding a Number option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptNumOption(IpoptProblem ipopt_problem, char* keyword, Number val); + + /** Function for adding an Int option. Returns FALSE the option + * could not be set (e.g., if keyword is unknown) */ + IPOPT_EXPORT(Bool) AddIpoptIntOption(IpoptProblem ipopt_problem, char* keyword, Int val); + + /** Function for opening an output file for a given name with given + * printlevel. Returns false, if there was a problem opening the + * file. */ + IPOPT_EXPORT(Bool) OpenIpoptOutputFile(IpoptProblem ipopt_problem, char* file_name, + Int print_level); + + /** Optional function for setting scaling parameter for the NLP. + * This corresponds to the get_scaling_parameters method in TNLP. + * If the pointers x_scaling or g_scaling are NULL, then no scaling + * for x resp. g is done. */ + IPOPT_EXPORT(Bool) SetIpoptProblemScaling(IpoptProblem ipopt_problem, + Number obj_scaling, + Number* x_scaling, + Number* g_scaling); + + /** Setting a callback function for the "intermediate callback" + * method in the TNLP. This gives control back to the user once + * per iteration. If set, it provides the user with some + * information on the state of the optimization. This can be used + * to print some user-defined output. It also gives the user a way + * to terminate the optimization prematurely. If the callback + * method returns false, Ipopt will terminate the optimization. + * Calling this set method to set the CB pointer to NULL disables + * the intermediate callback functionality. */ + IPOPT_EXPORT(Bool) SetIntermediateCallback(IpoptProblem ipopt_problem, + Intermediate_CB intermediate_cb); + + /** Function calling the Ipopt optimization algorithm for a problem + previously defined with CreateIpoptProblem. The return + specified outcome of the optimization procedure (e.g., success, + failure etc). + */ + IPOPT_EXPORT(enum ApplicationReturnStatus) IpoptSolve( + IpoptProblem ipopt_problem + /** Problem that is to be optimized. Ipopt + will use the options previously specified with + AddIpoptOption (etc) for this problem. */ + , Number* x /** Input: Starting point + Output: Optimal solution */ + , Number* g /** Values of constraint at final point + (output only - ignored if set to NULL) */ + , Number* obj_val /** Final value of objective function + (output only - ignored if set to NULL) */ + , Number* mult_g /** Input: Initial values for the constraint + multipliers (only if warm start option + is chosen) + Output: Final multipliers for constraints + (ignored if set to NULL) */ + , Number* mult_x_L /** Input: Initial values for the multipliers for + lower variable bounds (only if warm start + option is chosen) + Output: Final multipliers for lower variable + bounds (ignored if set to NULL) */ + , Number* mult_x_U /** Input: Initial values for the multipliers for + upper variable bounds (only if warm start + option is chosen) + Output: Final multipliers for upper variable + bounds (ignored if set to NULL) */ + , UserDataPtr user_data + /** Pointer to user data. This will be + passed unmodified to the callback + functions. */ + ); + + /** + void IpoptStatisticsCounts; + + void IpoptStatisticsInfeasibilities; */ +#ifdef __cplusplus +} /* extern "C" { */ +#endif + +#endif diff --git a/thirdparty/linux/include/coin1/IpSumSymMatrix.hpp b/thirdparty/linux/include/coin1/IpSumSymMatrix.hpp new file mode 100644 index 0000000..42b1168 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSumSymMatrix.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSumSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSUMSYMMATRIX_HPP__ +#define __IPSUMSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SumSymMatrixSpace; + + /** Class for Matrices which are sum of symmetric matrices. + * For each term in the we store the matrix and a factor. + */ + class SumSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, initializing with dimensions of the matrix and + * the number of terms in the sum. + */ + SumSymMatrix(const SumSymMatrixSpace* owner_space); + + /** Destructor */ + ~SumSymMatrix(); + //@} + + /** Method for setting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void SetTerm(Index iterm, Number factor, const SymMatrix& matrix); + + /** Method for getting term iterm for the sum. Note that counting + * of terms starts at 0. */ + void GetTerm(Index iterm, Number& factor, SmartPtr<const SymMatrix>& matrix) const; + + /** Return the number of terms */ + Index NTerms() const; + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SumSymMatrix(); + + /** Copy Constructor */ + SumSymMatrix(const SumSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SumSymMatrix&); + //@} + + /** std::vector storing the factors for each term. */ + std::vector<Number> factors_; + + /** std::vector storing the matrices for each term. */ + std::vector<SmartPtr<const SymMatrix> > matrices_; + + /** Copy of the owner_space as a SumSymMatrixSpace */ + const SumSymMatrixSpace* owner_space_; + }; + + /** Class for matrix space for SumSymMatrix */ + class SumSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the dimension of the matrix and the number + * of terms in the sum. */ + SumSymMatrixSpace(Index ndim, Index nterms) + : + SymMatrixSpace(ndim), + nterms_(nterms) + {} + + /** Destructor */ + ~SumSymMatrixSpace() + {} + //@} + + /** @name Accessor functions */ + //@{ + /** Number of terms in the sum. */ + Index NTerms() const + { + return nterms_; + } + //@} + + /** Use this method to set the matrix spaces for the various terms. + * You will not be able to create a matrix until all these spaces + * are set. */ + void SetTermSpace(Index term_idx, const SymMatrixSpace& space); + + /** Get the matix space for a particular term */ + SmartPtr<const SymMatrixSpace> GetTermSpace(Index term_idx) const; + + /** Method for creating a new matrix of this specific type. */ + SumSymMatrix* MakeNewSumSymMatrix() const; + + /** Overloaded MakeNew method for the SymMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const; + + private: + Index nterms_; + + std::vector< SmartPtr<const SymMatrixSpace> > term_spaces_; + }; + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpSymLinearSolver.hpp b/thirdparty/linux/include/coin1/IpSymLinearSolver.hpp new file mode 100644 index 0000000..82e7dd4 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSymLinearSolver.hpp @@ -0,0 +1,130 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymLinearSolver.hpp 2322 2013-06-12 17:45:57Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMLINEARSOLVER_HPP__ +#define __IPSYMLINEARSOLVER_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" +#include "IpAlgStrategy.hpp" +#include <vector> + +namespace Ipopt +{ + + /** Enum to report outcome of a linear solve */ + enum ESymSolverStatus { + /** Successful solve */ + SYMSOLVER_SUCCESS, + /** Matrix seems to be singular; solve was aborted */ + SYMSOLVER_SINGULAR, + /** The number of negative eigenvalues is not correct */ + SYMSOLVER_WRONG_INERTIA, + /** Call the solver interface again after the matrix values have + * been restored */ + SYMSOLVER_CALL_AGAIN, + /** Unrecoverable error in linear solver occurred. The + * optimization will be aborted. */ + SYMSOLVER_FATAL_ERROR + }; + + /** Base class for all derived symmetric linear + * solvers. In the full space version of Ipopt a large linear + * system has to be solved for the augmented system. This case is + * meant to be the base class for all derived linear solvers for + * symmetric matrices (of type SymMatrix). + * + * A linear solver can be used repeatedly for matrices with + * identical structure of nonzero elements. The nonzero structure + * of those matrices must not be changed between calls. + * + * The called might ask the solver to only solve the linear system + * if the system is nonsingular, and if the number of negative + * eigenvalues matches a given number. + */ + class SymLinearSolver: public AlgorithmStrategyObject + { + public: + /** @name Constructor/Destructor */ + //@{ + SymLinearSolver() + {} + + virtual ~SymLinearSolver() + {} + //@} + + /** overloaded from AlgorithmStrategyObject */ + virtual bool InitializeImpl(const OptionsList& options, + const std::string& prefix) = 0; + + /** @name Methods for requesting solution of the linear system. */ + //@{ + /** Solve operation for multiple right hand sides. Solves the + * linear system A * Sol = Rhs with multiple right hand sides. If + * necessary, A is factorized. Correct solutions are only + * guaranteed if the return values is SYMSOLVER_SUCCESS. The + * solver will return SYMSOLVER_SINGULAR if the linear system is + * singular, and it will return SYMSOLVER_WRONG_INERTIA if + * check_NegEVals is true and the number of negative eigenvalues + * in the matrix does not match numberOfNegEVals. + * + * check_NegEVals cannot be chosen true, if ProvidesInertia() + * returns false. + */ + virtual ESymSolverStatus MultiSolve(const SymMatrix &A, + std::vector<SmartPtr<const Vector> >& rhsV, + std::vector<SmartPtr<Vector> >& solV, + bool check_NegEVals, + Index numberOfNegEVals)=0; + + /** Solve operation for a single right hand side. Solves the + * linear system A * Sol = Rhs. See MultiSolve for more + * details. */ + ESymSolverStatus Solve(const SymMatrix &A, + const Vector& rhs, Vector& sol, + bool check_NegEVals, + Index numberOfNegEVals) + { + std::vector<SmartPtr<const Vector> > rhsV(1); + rhsV[0] = &rhs; + std::vector<SmartPtr<Vector> > solV(1); + solV[0] = / + return MultiSolve(A, rhsV, solV, check_NegEVals, + numberOfNegEVals); + } + + /** Number of negative eigenvalues detected during last + * factorization. Returns the number of negative eigenvalues of + * the most recent factorized matrix. This must not be called if + * the linear solver does not compute this quantities (see + * ProvidesInertia). + */ + virtual Index NumberOfNegEVals() const =0; + //@} + + //* @name Options of Linear solver */ + //@{ + /** Request to increase quality of solution for next solve. + * Ask linear solver to increase quality of solution for the next + * solve (e.g. increase pivot tolerance). Returns false, if this + * is not possible (e.g. maximal pivot tolerance already used.) + */ + virtual bool IncreaseQuality() =0; + + /** Query whether inertia is computed by linear solver. + * Returns true, if linear solver provides inertia. + */ + virtual bool ProvidesInertia() const =0; + //@} + }; + + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpSymMatrix.hpp b/thirdparty/linux/include/coin1/IpSymMatrix.hpp new file mode 100644 index 0000000..4a0137b --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSymMatrix.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMMATRIX_HPP__ +#define __IPSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymMatrixSpace; + + /** This is the base class for all derived symmetric matrix types. + */ + class SymMatrix : public Matrix + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor, taking the owner_space. + */ + inline + SymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + virtual ~SymMatrix() + {} + //@} + + /** @name Information about the size of the matrix */ + //@{ + /** Dimension of the matrix (number of rows and columns) */ + inline + Index Dim() const; + //@} + + inline + SmartPtr<const SymMatrixSpace> OwnerSymMatrixSpace() const; + + protected: + /** @name Overloaded methods from Matrix. */ + //@{ + /** Since the matrix is + * symmetric, it is only necessary to implement the + * MultVectorImpl method in a class that inherits from this base + * class. If the TransMultVectorImpl is called, this base class + * automatically calls MultVectorImpl instead. */ + virtual void TransMultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const + { + // Since this matrix is symetric, this is the same operation as + // MultVector + MultVector(alpha, x, beta, y); + } + /** Since the matrix is symmetric, the row and column max norms + * are identical */ + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + { + ComputeRowAMaxImpl(cols_norms, init); + } + //@} + + private: + /** Copy of the owner space ptr as a SymMatrixSpace instead + * of a MatrixSpace + */ + const SymMatrixSpace* owner_space_; + }; + + + /** SymMatrixSpace base class, corresponding to the SymMatrix base + * class. */ + class SymMatrixSpace : public MatrixSpace + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension (identical to the number of + * rows and columns). + */ + SymMatrixSpace(Index dim) + : + MatrixSpace(dim,dim) + {} + + /** Destructor */ + virtual ~SymMatrixSpace() + {} + //@} + + /** Pure virtual method for creating a new matrix of this specific + * type. */ + virtual SymMatrix* MakeNewSymMatrix() const=0; + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymMatrix(); + } + + /** Accessor method for the dimension of the matrices in this + * matrix space. + */ + Index Dim() const + { + DBG_ASSERT(NRows() == NCols()); + return NRows(); + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + SymMatrixSpace(); + + /* Copy constructor */ + SymMatrixSpace(const SymMatrixSpace&); + + /** Overloaded Equals Operator */ + SymMatrixSpace& operator=(const SymMatrixSpace&); + //@} + + }; + + /* inline methods */ + inline + SymMatrix::SymMatrix(const SymMatrixSpace* owner_space) + : + Matrix(owner_space), + owner_space_(owner_space) + {} + + inline + Index SymMatrix::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr<const SymMatrixSpace> SymMatrix::OwnerSymMatrixSpace() const + { + return owner_space_; + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpSymScaledMatrix.hpp b/thirdparty/linux/include/coin1/IpSymScaledMatrix.hpp new file mode 100644 index 0000000..d58742f --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSymScaledMatrix.hpp @@ -0,0 +1,230 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymScaledMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMSCALEDMATRIX_HPP__ +#define __IPSYMSCALEDMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymScaledMatrixSpace; + + /** Class for a Matrix in conjunction with its scaling factors for + * row and column scaling. Operations on the matrix are performed using + * the scaled matrix. You can pull out the pointer to the + * unscaled matrix for unscaled calculations. + */ + class SymScaledMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the owner_space. + */ + SymScaledMatrix(const SymScaledMatrixSpace* owner_space); + + /** Destructor */ + ~SymScaledMatrix(); + //@} + + /** Set the unscaled matrix */ + void SetUnscaledMatrix(const SmartPtr<const SymMatrix> unscaled_matrix); + + /** Set the unscaled matrix in a non-const version */ + void SetUnscaledMatrixNonConst(const SmartPtr<SymMatrix>& unscaled_matrix); + + /** Return the unscaled matrix in const form */ + SmartPtr<const SymMatrix> GetUnscaledMatrix() const; + + /** Return the unscaled matrix in non-const form */ + SmartPtr<SymMatrix> GetUnscaledMatrixNonConst(); + + /** return the vector for the row and column scaling */ + SmartPtr<const Vector> RowColScaling() const; + + protected: + /**@name Methods overloaded from Matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). It is assumed here that the scaling factors + * are always valid numbers. */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymScaledMatrix(); + + /** Copy Constructor */ + SymScaledMatrix(const SymScaledMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymScaledMatrix&); + //@} + + /** const version of the unscaled matrix */ + SmartPtr<const SymMatrix> matrix_; + /** non-const version of the unscaled matrix */ + SmartPtr<SymMatrix> nonconst_matrix_; + + /** Matrix space stored as a SymScaledMatrixSpace */ + SmartPtr<const SymScaledMatrixSpace> owner_space_; + }; + + /** This is the matrix space for SymScaledMatrix. + */ + class SymScaledMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns blocks, as + * well as the totel number of rows and columns. + */ + SymScaledMatrixSpace(const SmartPtr<const Vector>& row_col_scaling, + bool row_col_scaling_reciprocal, + const SmartPtr<const SymMatrixSpace>& unscaled_matrix_space) + : + SymMatrixSpace(unscaled_matrix_space->Dim()), + unscaled_matrix_space_(unscaled_matrix_space) + { + scaling_ = row_col_scaling->MakeNewCopy(); + if (row_col_scaling_reciprocal) { + scaling_->ElementWiseReciprocal(); + } + } + + /** Destructor */ + ~SymScaledMatrixSpace() + {} + //@} + + /** Method for creating a new matrix of this specific type. */ + SymScaledMatrix* MakeNewSymScaledMatrix(bool allocate_unscaled_matrix = false) const + { + SymScaledMatrix* ret = new SymScaledMatrix(this); + if (allocate_unscaled_matrix) { + SmartPtr<SymMatrix> unscaled_matrix = unscaled_matrix_space_->MakeNewSymMatrix(); + ret->SetUnscaledMatrixNonConst(unscaled_matrix); + } + return ret; + } + + /** Overloaded method from SymMatrixSpace */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymScaledMatrix(); + } + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewSymScaledMatrix(); + } + + /** return the vector for the row and column scaling */ + SmartPtr<const Vector> RowColScaling() const + { + return ConstPtr(scaling_); + } + + /** return the matrix space for the unscaled matrix */ + SmartPtr<const SymMatrixSpace> UnscaledMatrixSpace() const + { + return unscaled_matrix_space_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + SymScaledMatrixSpace(); + + /** Copy Constructor */ + SymScaledMatrixSpace(const SymScaledMatrixSpace&); + + /** Overloaded Equals Operator */ + SymScaledMatrixSpace& operator=(const SymScaledMatrixSpace&); + //@} + + /** Row scaling vector */ + SmartPtr<Vector> scaling_; + /** unscaled matrix space */ + SmartPtr<const SymMatrixSpace> unscaled_matrix_space_; + }; + + inline + void SymScaledMatrix::SetUnscaledMatrix(const SmartPtr<const SymMatrix> unscaled_matrix) + { + matrix_ = unscaled_matrix; + nonconst_matrix_ = NULL; + ObjectChanged(); + } + + inline + void SymScaledMatrix::SetUnscaledMatrixNonConst(const SmartPtr<SymMatrix>& unscaled_matrix) + { + nonconst_matrix_ = unscaled_matrix; + matrix_ = GetRawPtr(unscaled_matrix); + ObjectChanged(); + } + + inline + SmartPtr<const SymMatrix> SymScaledMatrix::GetUnscaledMatrix() const + { + return matrix_; + } + + inline + SmartPtr<SymMatrix> SymScaledMatrix::GetUnscaledMatrixNonConst() + { + DBG_ASSERT(IsValid(nonconst_matrix_)); + ObjectChanged(); + return nonconst_matrix_; + } + + inline SmartPtr<const Vector> SymScaledMatrix::RowColScaling() const + { + return ConstPtr(owner_space_->RowColScaling()); + } + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpSymTMatrix.hpp b/thirdparty/linux/include/coin1/IpSymTMatrix.hpp new file mode 100644 index 0000000..ead2d85 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpSymTMatrix.hpp @@ -0,0 +1,253 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpSymTMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPSYMTMATRIX_HPP__ +#define __IPSYMTMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /* forward declarations */ + class SymTMatrixSpace; + + /** Class for symmetric matrices stored in triplet format. In the + * triplet format, the nonzeros elements of a symmetric matrix is + * stored in three arrays, Irn, Jcn, and Values, all of length + * Nonzeros. The first two arrays indicate the location of a + * non-zero element (as the row and column indices), and the last + * array stores the value at that location. Off-diagonal elements + * need to be stored only once since the matrix is symmetric. For + * example, the element \f$a_{1,2}=a_{2,1}\f$ would be stored only + * once, either with Irn[i]=1 and Jcn[i]=2, or with Irn[i]=2 and + * Jcn[i]=1. Both representations are identical. If nonzero + * elements (or their symmetric counter part) are listed more than + * once, their values are added. + * + * The structure of the nonzeros (i.e. the arrays Irn and Jcn) + * cannot be changed after the matrix can been initialized. Only + * the values of the nonzero elements can be modified. + * + * Note that the first row and column of a matrix has index 1, not + * 0. + * + */ + class SymTMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + SymTMatrix(const SymTMatrixSpace* owner_space); + + /** Destructor */ + ~SymTMatrix(); + //@} + + /**@name Changing the Values.*/ + //@{ + /** Set values of nonzero elements. The values of the nonzero + * elements is copied from the incoming Number array. Important: + * It is assume that the order of the values in Values + * corresponds to the one of Irn and Jcn given to the matrix + * space. */ + void SetValues(const Number* Values); + //@} + + /** @name Accessor Methods */ + //@{ + /** Number of nonzero entries */ + Index Nonzeros() const; + + /** Obtain pointer to the internal Index array irn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Irows() const; + + /** Obtain pointer to the internal Index array jcn_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Index* Jcols() const; + + /** Obtain pointer to the internal Number array values_ with the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + Number* Values(); + /** Obtain pointer to the internal Number array values_ without the + * intention to change the matrix data (USE WITH CARE!). This + * does not produce a copy, and lifetime is not guaranteed! + */ + const Number* Values() const; + //@} + + /**@name Methods for providing copy of the matrix data */ + //@{ + /** Copy the nonzero structure into provided space */ + void FillStruct(ipfint* Irn, ipfint* Jcn) const; + + /** Copy the value data into provided space */ + void FillValues(Number* Values) const; + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, Number beta, + Vector& y) const; + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + virtual bool HasValidNumbersImpl() const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const; + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + SymTMatrix(); + + /** Copy Constructor */ + SymTMatrix(const SymTMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const SymTMatrix&); + //@} + + /** Copy of the owner_space ptr as a SymTMatrixSpace insteaqd + * of a MatrixSpace + */ + const SymTMatrixSpace* owner_space_; + + /** Values of nonzeros */ + Number* values_; + + /** Flag for Initialization */ + bool initialized_; + + }; + + /** This is the matrix space for a SymTMatrix with fixed sparsity + * structure. The sparsity structure is stored here in the matrix + * space. + */ + class SymTMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of rows and columns (both as + * dim), as well as the number of nonzeros and the position of + * the nonzero elements. Note that the counting of the nonzeros + * starts a 1, i.e., iRows[i]==1 and jCols[i]==1 refers to the + * first element in the first row. This is in accordance with + * the HSL data structure. Off-diagonal elements are stored only + * once. + */ + SymTMatrixSpace(Index dim, Index nonZeros, const Index* iRows, + const Index* jCols); + + /** Destructor */ + ~SymTMatrixSpace(); + //@} + + /** Overloaded MakeNew method for the sYMMatrixSpace base class. + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewSymTMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + SymTMatrix* MakeNewSymTMatrix() const + { + return new SymTMatrix(this); + } + + /**@name Methods describing Matrix structure */ + //@{ + /** Number of non-zeros in the sparse matrix */ + Index Nonzeros() const + { + return nonZeros_; + } + + /** Row index of each non-zero element */ + const Index* Irows() const + { + return iRows_; + } + + /** Column index of each non-zero element */ + const Index* Jcols() const + { + return jCols_; + } + //@} + + private: + /**@name Methods called by SymTMatrix for memory management */ + //@{ + /** Allocate internal storage for the SymTMatrix values */ + Number* AllocateInternalStorage() const; + + /** Deallocate internal storage for the SymTMatrix values */ + void FreeInternalStorage(Number* values) const; + //@} + + const Index nonZeros_; + Index* iRows_; + Index* jCols_; + + friend class SymTMatrix; + }; + + /* Inline Methods */ + inline + Index SymTMatrix::Nonzeros() const + { + return owner_space_->Nonzeros(); + } + + inline + const Index* SymTMatrix::Irows() const + { + return owner_space_->Irows(); + } + + inline + const Index* SymTMatrix::Jcols() const + { + return owner_space_->Jcols(); + } + + +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpTNLP.hpp b/thirdparty/linux/include/coin1/IpTNLP.hpp new file mode 100644 index 0000000..998d38e --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTNLP.hpp @@ -0,0 +1,301 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLP.hpp 2212 2013-04-14 14:51:52Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLP_HPP__ +#define __IPTNLP_HPP__ + +#include "IpUtils.hpp" +#include "IpReferenced.hpp" +#include "IpException.hpp" +#include "IpAlgTypes.hpp" +#include "IpReturnCodes.hpp" + +#include <map> + +namespace Ipopt +{ + // forward declarations + class IpoptData; + class IpoptCalculatedQuantities; + class IteratesVector; + + /** Base class for all NLP's that use standard triplet matrix form + * and dense vectors. This is the standard base class for all + * NLP's that use the standard triplet matrix form (as for Harwell + * routines) and dense vectors. The class TNLPAdapter then converts + * this interface to an interface that can be used directly by + * ipopt. + * + * This interface presents the problem form: + * + * min f(x) + * + * s.t. gL <= g(x) <= gU + * + * xL <= x <= xU + * + * In order to specify an equality constraint, set gL_i = gU_i = + * rhs. The value that indicates "infinity" for the bounds + * (i.e. the variable or constraint has no lower bound (-infinity) + * or upper bound (+infinity)) is set through the option + * nlp_lower_bound_inf and nlp_upper_bound_inf. To indicate that a + * variable has no upper or lower bound, set the bound to + * -ipopt_inf or +ipopt_inf respectively + */ + class TNLP : public ReferencedObject + { + public: + /** Type of the constraints*/ + enum LinearityType + { + LINEAR/** Constraint/Variable is linear.*/, + NON_LINEAR/**Constraint/Varaible is non-linear.*/ + }; + + /**@name Constructors/Destructors */ + //@{ + TNLP() + {} + + /** Default destructor */ + virtual ~TNLP() + {} + //@} + + DECLARE_STD_EXCEPTION(INVALID_TNLP); + + /**@name methods to gather information about the NLP */ + //@{ + /** overload this method to return the number of variables + * and constraints, and the number of non-zeros in the jacobian and + * the hessian. The index_style parameter lets you specify C or Fortran + * style indexing for the sparse matrix iRow and jCol parameters. + * C_STYLE is 0-based, and FORTRAN_STYLE is 1-based. + */ + enum IndexStyleEnum { C_STYLE=0, FORTRAN_STYLE=1 }; + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style)=0; + + typedef std::map<std::string, std::vector<std::string> > StringMetaDataMapType; + typedef std::map<std::string, std::vector<Index> > IntegerMetaDataMapType; + typedef std::map<std::string, std::vector<Number> > NumericMetaDataMapType; + + /** overload this method to return any meta data for + * the variables and the constraints */ + virtual bool get_var_con_metadata(Index n, + StringMetaDataMapType& var_string_md, + IntegerMetaDataMapType& var_integer_md, + NumericMetaDataMapType& var_numeric_md, + Index m, + StringMetaDataMapType& con_string_md, + IntegerMetaDataMapType& con_integer_md, + NumericMetaDataMapType& con_numeric_md) + + { + return false; + } + + /** overload this method to return the information about the bound + * on the variables and constraints. The value that indicates + * that a bound does not exist is specified in the parameters + * nlp_lower_bound_inf and nlp_upper_bound_inf. By default, + * nlp_lower_bound_inf is -1e19 and nlp_upper_bound_inf is + * 1e19. (see TNLPAdapter) */ + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u)=0; + + /** overload this method to return scaling parameters. This is + * only called if the options are set to retrieve user scaling. + * There, use_x_scaling (or use_g_scaling) should get set to true + * only if the variables (or constraints) are to be scaled. This + * method should return true only if the scaling parameters could + * be provided. + */ + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling) + { + return false; + } + + /** overload this method to return the variables linearity + * (TNLP::LINEAR or TNLP::NON_LINEAR). The var_types + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_variables_linearity(Index n, LinearityType* var_types) + { + return false; + } + + /** overload this method to return the constraint linearity. + * array has been allocated with length at least n. (default implementation + * just return false and does not fill the array).*/ + virtual bool get_constraints_linearity(Index m, LinearityType* const_types) + { + return false; + } + + /** overload this method to return the starting point. The bool + * variables indicate whether the algorithm wants you to + * initialize x, z_L/z_u, and lambda, respectively. If, for some + * reason, the algorithm wants you to initialize these and you + * cannot, return false, which will cause Ipopt to stop. You + * will have to run Ipopt with different options then. + */ + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda)=0; + + /** overload this method to provide an Ipopt iterate (already in + * the form Ipopt requires it internally) for a warm start. + * Since this is only for expert users, a default dummy + * implementation is provided and returns false. */ + virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate) + { + return false; + } + + /** overload this method to return the value of the objective function */ + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value)=0; + + /** overload this method to return the vector of the gradient of + * the objective w.r.t. x */ + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f)=0; + + /** overload this method to return the vector of constraint values */ + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g)=0; + /** overload this method to return the jacobian of the + * constraints. The vectors iRow and jCol only need to be set + * once. The first call is used to set the structure only (iRow + * and jCol will be non-NULL, and values will be NULL) For + * subsequent calls, iRow and jCol will be NULL. */ + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values)=0; + + /** overload this method to return the hessian of the + * lagrangian. The vectors iRow and jCol only need to be set once + * (during the first call). The first call is used to set the + * structure only (iRow and jCol will be non-NULL, and values + * will be NULL) For subsequent calls, iRow and jCol will be + * NULL. This matrix is symmetric - specify the lower diagonal + * only. A default implementation is provided, in case the user + * wants to se quasi-Newton approximations to estimate the second + * derivatives and doesn't not neet to implement this method. */ + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, + Index* iRow, Index* jCol, Number* values) + { + return false; + } + //@} + + /** @name Solution Methods */ + //@{ + /** This method is called when the algorithm is complete so the TNLP can store/write the solution */ + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq)=0; + /** This method is called just before finalize_solution. With + * this method, the algorithm returns any metadata collected + * during its run, including the metadata provided by the user + * with the above get_var_con_metadata. Each metadata can be of + * type string, integer, and numeric. It can be associated to + * either the variables or the constraints. The metadata that + * was associated with the primal variable vector is stored in + * var_..._md. The metadata associated with the constraint + * multipliers is stored in con_..._md. The metadata associated + * with the bound multipliers is stored in var_..._md, with the + * suffixes "_z_L", and "_z_U", denoting lower and upper + * bounds. */ + virtual void finalize_metadata(Index n, + const StringMetaDataMapType& var_string_md, + const IntegerMetaDataMapType& var_integer_md, + const NumericMetaDataMapType& var_numeric_md, + Index m, + const StringMetaDataMapType& con_string_md, + const IntegerMetaDataMapType& con_integer_md, + const NumericMetaDataMapType& con_numeric_md) + {} + + + /** Intermediate Callback method for the user. Providing dummy + * default implementation. For details see IntermediateCallBack + * in IpNLP.hpp. */ + virtual bool intermediate_callback(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq) + { + return true; + } + //@} + + /** @name Methods for quasi-Newton approximation. If the second + * derivatives are approximated by Ipopt, it is better to do this + * only in the space of nonlinear variables. The following + * methods are call by Ipopt if the quasi-Newton approximation is + * selected. If -1 is returned as number of nonlinear variables, + * Ipopt assumes that all variables are nonlinear. Otherwise, it + * calls get_list_of_nonlinear_variables with an array into which + * the indices of the nonlinear variables should be written - the + * array has the lengths num_nonlin_vars, which is identical with + * the return value of get_number_of_nonlinear_variables(). It + * is assumed that the indices are counted starting with 1 in the + * FORTRAN_STYLE, and 0 for the C_STYLE. */ + //@{ + virtual Index get_number_of_nonlinear_variables() + { + return -1; + } + + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars) + { + return false; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + //TNLP(); + + /** Copy Constructor */ + TNLP(const TNLP&); + + /** Overloaded Equals Operator */ + void operator=(const TNLP&); + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTNLPAdapter.hpp b/thirdparty/linux/include/coin1/IpTNLPAdapter.hpp new file mode 100644 index 0000000..6eea8e3 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTNLPAdapter.hpp @@ -0,0 +1,427 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPAdapter.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTNLPADAPTER_HPP__ +#define __IPTNLPADAPTER_HPP__ + +#include "IpNLP.hpp" +#include "IpTNLP.hpp" +#include "IpOrigIpoptNLP.hpp" +#include <list> + +namespace Ipopt +{ + + // forward declarations + class ExpansionMatrix; + class ExpansionMatrixSpace; + class IteratesVector; + class TDependencyDetector; + + /** This class Adapts the TNLP interface so it looks like an NLP interface. + * This is an Adapter class (Design Patterns) that converts a TNLP to an + * NLP. This allows users to write to the "more convenient" TNLP interface. + */ + class TNLPAdapter : public NLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor */ + TNLPAdapter(const SmartPtr<TNLP> tnlp, + const SmartPtr<const Journalist> jnlst = NULL); + + /** Default destructor */ + virtual ~TNLPAdapter(); + //@} + + /**@name Exceptions */ + //@{ + DECLARE_STD_EXCEPTION(INVALID_TNLP); + DECLARE_STD_EXCEPTION(ERROR_IN_TNLP_DERIVATIVE_TEST); + //@} + + /** @name TNLPAdapter Initialization. */ + //@{ + virtual bool ProcessOptions(const OptionsList& options, + const std::string& prefix); + + /** Method for creating the derived vector / matrix types + * (Do not delete these, the ). */ + virtual bool GetSpaces(SmartPtr<const VectorSpace>& x_space, + SmartPtr<const VectorSpace>& c_space, + SmartPtr<const VectorSpace>& d_space, + SmartPtr<const VectorSpace>& x_l_space, + SmartPtr<const MatrixSpace>& px_l_space, + SmartPtr<const VectorSpace>& x_u_space, + SmartPtr<const MatrixSpace>& px_u_space, + SmartPtr<const VectorSpace>& d_l_space, + SmartPtr<const MatrixSpace>& pd_l_space, + SmartPtr<const VectorSpace>& d_u_space, + SmartPtr<const MatrixSpace>& pd_u_space, + SmartPtr<const MatrixSpace>& Jac_c_space, + SmartPtr<const MatrixSpace>& Jac_d_space, + SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space); + + /** Method for obtaining the bounds information */ + virtual bool GetBoundsInformation(const Matrix& Px_L, + Vector& x_L, + const Matrix& Px_U, + Vector& x_U, + const Matrix& Pd_L, + Vector& d_L, + const Matrix& Pd_U, + Vector& d_U); + + /** Method for obtaining the starting point + * for all the iterates. */ + virtual bool GetStartingPoint( + SmartPtr<Vector> x, + bool need_x, + SmartPtr<Vector> y_c, + bool need_y_c, + SmartPtr<Vector> y_d, + bool need_y_d, + SmartPtr<Vector> z_L, + bool need_z_L, + SmartPtr<Vector> z_U, + bool need_z_U + ); + + /** Method for obtaining an entire iterate as a warmstart point. + * The incoming IteratesVector has to be filled. */ + virtual bool GetWarmStartIterate(IteratesVector& warm_start_iterate); + //@} + + /** @name TNLPAdapter evaluation routines. */ + //@{ + virtual bool Eval_f(const Vector& x, Number& f); + + virtual bool Eval_grad_f(const Vector& x, Vector& g_f); + + virtual bool Eval_c(const Vector& x, Vector& c); + + virtual bool Eval_jac_c(const Vector& x, Matrix& jac_c); + + virtual bool Eval_d(const Vector& x, Vector& d); + + virtual bool Eval_jac_d(const Vector& x, Matrix& jac_d); + + virtual bool Eval_h(const Vector& x, + Number obj_factor, + const Vector& yc, + const Vector& yd, + SymMatrix& h); + + virtual void GetScalingParameters( + const SmartPtr<const VectorSpace> x_space, + const SmartPtr<const VectorSpace> c_space, + const SmartPtr<const VectorSpace> d_space, + Number& obj_scaling, + SmartPtr<Vector>& x_scaling, + SmartPtr<Vector>& c_scaling, + SmartPtr<Vector>& d_scaling) const; + //@} + + /** @name Solution Reporting Methods */ + //@{ + virtual void FinalizeSolution(SolverReturn status, + const Vector& x, + const Vector& z_L, const Vector& z_U, + const Vector& c, const Vector& d, + const Vector& y_c, const Vector& y_d, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool IntermediateCallBack(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + //@} + + /** Method returning information on quasi-Newton approximation. */ + virtual void + GetQuasiNewtonApproximationSpaces(SmartPtr<VectorSpace>& approx_space, + SmartPtr<Matrix>& P_approx); + + /** Enum for treatment of fixed variables option */ + enum FixedVariableTreatmentEnum + { + MAKE_PARAMETER=0, + MAKE_CONSTRAINT, + RELAX_BOUNDS + }; + + /** Enum for specifying which derivative test is to be performed. */ + enum DerivativeTestEnum + { + NO_TEST=0, + FIRST_ORDER_TEST, + SECOND_ORDER_TEST, + ONLY_SECOND_ORDER_TEST + }; + + /** Enum for specifying technique for computing Jacobian */ + enum JacobianApproxEnum + { + JAC_EXACT=0, + JAC_FINDIFF_VALUES + }; + + /** Method for performing the derivative test */ + bool CheckDerivatives(DerivativeTestEnum deriv_test, + Index deriv_test_start_index); + + /** @name Methods for IpoptType */ + //@{ + static void RegisterOptions(SmartPtr<RegisteredOptions> roptions); + //@} + + /** Accessor method for the underlying TNLP. */ + SmartPtr<TNLP> tnlp() const + { + return tnlp_; + } + + /** @name Methods for translating data for IpoptNLP into the TNLP + * data. These methods are used to obtain the current (or + * final) data for the TNLP formulation from the IpoptNLP + * structure. */ + //@{ + /** Sort the primal variables, and add the fixed values in x */ + void ResortX(const Vector& x, Number* x_orig); + void ResortG(const Vector& c, const Vector& d, Number *g_orig); + void ResortBnds(const Vector& x_L, Number* x_L_orig, + const Vector& x_U, Number* x_U_orig); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TNLPAdapter(const TNLPAdapter&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPAdapter&); + //@} + + /** @name Method implementing the detection of linearly dependent + equality constraints */ + bool DetermineDependentConstraints(Index n_x_var, + const Index* x_not_fixed_map, + const Number* x_l, const Number* x_u, + const Number* g_l, const Number* g_u, + Index n_c, const Index* c_map, + std::list<Index>& c_deps); + + /** Pointer to the TNLP class (class specific to Number* vectors and + * harwell triplet matrices) */ + SmartPtr<TNLP> tnlp_; + + /** Journalist */ + SmartPtr<const Journalist> jnlst_; + + /** Object that can be used to detect linearly dependent rows in + * the equality constraint Jacobian */ + SmartPtr<TDependencyDetector> dependency_detector_; + + /**@name Algorithmic parameters */ + //@{ + /** Value for a lower bound that denotes -infinity */ + Number nlp_lower_bound_inf_; + /** Value for a upper bound that denotes infinity */ + Number nlp_upper_bound_inf_; + /** Flag indicating how fixed variables should be handled */ + FixedVariableTreatmentEnum fixed_variable_treatment_; + /* Determines relaxation of fixing bound for RELAX_BOUNDS. */ + Number bound_relax_factor_; + /* Maximal slack for one-sidedly bounded variables. If a + * variable has only one bound, say a lower bound xL, then an + * upper bound xL + max_onesided_bound_slack_. If this value is + * zero, no upper bound is added. */ + /* Took this out: Number max_onesided_bound_slack_; */ + /** Enum indicating whether and which derivative test should be + * performed at starting point. */ + DerivativeTestEnum derivative_test_; + /** Size of the perturbation for the derivative test */ + Number derivative_test_perturbation_; + /** Relative threshold for marking deviation from finite + * difference test */ + Number derivative_test_tol_; + /** Flag indicating if all test values should be printed, or only + * those violating the threshold. */ + bool derivative_test_print_all_; + /** Index of first quantity to be checked. */ + Index derivative_test_first_index_; + /** Flag indicating whether the TNLP with identical structure has + * already been solved before. */ + bool warm_start_same_structure_; + /** Flag indicating what Hessian information is to be used. */ + HessianApproximationType hessian_approximation_; + /** Number of linear variables. */ + Index num_linear_variables_; + /** Flag indicating how Jacobian is computed. */ + JacobianApproxEnum jacobian_approximation_; + /** Size of the perturbation for the derivative approximation */ + Number findiff_perturbation_; + /** Maximal perturbation of the initial point */ + Number point_perturbation_radius_; + /** Flag indicating if rhs should be considered during dependency + * detection */ + bool dependency_detection_with_rhs_; + + /** Overall convergence tolerance */ + Number tol_; + //@} + + /**@name Problem Size Data */ + //@{ + /** full dimension of x (fixed + non-fixed) */ + Index n_full_x_; + /** full dimension of g (c + d) */ + Index n_full_g_; + /** non-zeros of the jacobian of c */ + Index nz_jac_c_; + /** non-zeros of the jacobian of c without added constraints for + * fixed variables. */ + Index nz_jac_c_no_extra_; + /** non-zeros of the jacobian of d */ + Index nz_jac_d_; + /** number of non-zeros in full-size Jacobian of g */ + Index nz_full_jac_g_; + /** number of non-zeros in full-size Hessian */ + Index nz_full_h_; + /** number of non-zeros in the non-fixed-size Hessian */ + Index nz_h_; + /** Number of fixed variables */ + Index n_x_fixed_; + //@} + + /** Numbering style of variables and constraints */ + TNLP::IndexStyleEnum index_style_; + + /** @name Local copy of spaces (for warm start) */ + //@{ + SmartPtr<const VectorSpace> x_space_; + SmartPtr<const VectorSpace> c_space_; + SmartPtr<const VectorSpace> d_space_; + SmartPtr<const VectorSpace> x_l_space_; + SmartPtr<const MatrixSpace> px_l_space_; + SmartPtr<const VectorSpace> x_u_space_; + SmartPtr<const MatrixSpace> px_u_space_; + SmartPtr<const VectorSpace> d_l_space_; + SmartPtr<const MatrixSpace> pd_l_space_; + SmartPtr<const VectorSpace> d_u_space_; + SmartPtr<const MatrixSpace> pd_u_space_; + SmartPtr<const MatrixSpace> Jac_c_space_; + SmartPtr<const MatrixSpace> Jac_d_space_; + SmartPtr<const SymMatrixSpace> Hess_lagrangian_space_; + //@} + + /**@name Local Copy of the Data */ + //@{ + Number* full_x_; /** copy of the full x vector (fixed & non-fixed) */ + Number* full_lambda_; /** copy of lambda (yc & yd) */ + Number* full_g_; /** copy of g (c & d) */ + Number* jac_g_; /** the values for the full jacobian of g */ + Number* c_rhs_; /** the rhs values of c */ + //@} + + /**@name Tags for deciding when to update internal copies of vectors */ + //@{ + TaggedObject::Tag x_tag_for_iterates_; + TaggedObject::Tag y_c_tag_for_iterates_; + TaggedObject::Tag y_d_tag_for_iterates_; + TaggedObject::Tag x_tag_for_g_; + TaggedObject::Tag x_tag_for_jac_g_; + //@} + + /**@name Methods to update the values in the local copies of vectors */ + //@{ + bool update_local_x(const Vector& x); + bool update_local_lambda(const Vector& y_c, const Vector& y_d); + //@} + + /**@name Internal routines for evaluating g and jac_g (values stored since + * they are used in both c and d routines */ + //@{ + bool internal_eval_g(bool new_x); + bool internal_eval_jac_g(bool new_x); + //@} + + /** @name Internal methods for dealing with finite difference + approxation */ + //@{ + /** Initialize sparsity structure for finite difference Jacobian */ + void initialize_findiff_jac(const Index* iRow, const Index* jCol); + //@} + + /**@name Internal Permutation Spaces and matrices + */ + //@{ + /** Expansion from fixed x (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_full_x_; + SmartPtr<ExpansionMatrixSpace> P_x_full_x_space_; + + /** Expansion from fixed x_L (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_x_L_; + SmartPtr<ExpansionMatrixSpace> P_x_x_L_space_; + + /** Expansion from fixed x_U (ipopt) to full x */ + SmartPtr<ExpansionMatrix> P_x_x_U_; + SmartPtr<ExpansionMatrixSpace> P_x_x_U_space_; + + /** Expansion from c only (ipopt) to full ampl c */ + SmartPtr<ExpansionMatrixSpace> P_c_g_space_; + SmartPtr<ExpansionMatrix> P_c_g_; + + /** Expansion from d only (ipopt) to full ampl d */ + SmartPtr<ExpansionMatrixSpace> P_d_g_space_; + SmartPtr<ExpansionMatrix> P_d_g_; + + Index* jac_idx_map_; + Index* h_idx_map_; + + /** Position of fixed variables. This is required for a warm start */ + Index* x_fixed_map_; + //@} + + /** @name Data for finite difference approximations of derivatives */ + //@{ + /** Number of unique nonzeros in constraint Jacobian */ + Index findiff_jac_nnz_; + /** Start position for nonzero indices in ja for each column of + Jacobian */ + Index* findiff_jac_ia_; + /** Ordered by columns, for each column the row indices in + Jacobian */ + Index* findiff_jac_ja_; + /** Position of entry in original triplet matrix */ + Index* findiff_jac_postriplet_; + /** Copy of the lower bounds */ + Number* findiff_x_l_; + /** Copy of the upper bounds */ + Number* findiff_x_u_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTNLPReducer.hpp b/thirdparty/linux/include/coin1/IpTNLPReducer.hpp new file mode 100644 index 0000000..bce1478 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTNLPReducer.hpp @@ -0,0 +1,180 @@ +// Copyright (C) 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTNLPReducer.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2008-08-10 + +#ifndef __IPTNLPREDUCER_HPP__ +#define __IPTNLPREDUCER_HPP__ + +#include "IpTNLP.hpp" + +namespace Ipopt +{ + /** This is a wrapper around a given TNLP class that takes out a + * list of constraints that are given to the constructor. It is + * provided for convenience, if one wants to experiment with + * problems that consist of only a subset of the constraints. But + * keep in mind that this is not efficient, since behind the scenes + * we are still evaluation all functions and derivatives, and are + * making copies of the original data. */ + class TNLPReducer : public TNLP + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Constructor is given the indices of the constraints that + * should be taken out of the problem statement, as well as the + * original TNLP. */ + TNLPReducer(TNLP& tnlp, Index n_g_skip, const Index* index_g_skip, + Index n_xL_skip, const Index* index_xL_skip, + Index n_xU_skip, const Index* index_xU_skip, + Index n_x_fix, const Index* index_f_fix); + + /** Default destructor */ + virtual ~TNLPReducer(); + //@} + + /** @name Overloaded methods from TNLP */ + virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, + Index& nnz_h_lag, IndexStyleEnum& index_style); + + virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, + Index m, Number* g_l, Number* g_u); + + virtual bool get_scaling_parameters(Number& obj_scaling, + bool& use_x_scaling, Index n, + Number* x_scaling, + bool& use_g_scaling, Index m, + Number* g_scaling); + + virtual bool get_variables_linearity(Index n, LinearityType* var_types); + + virtual bool get_constraints_linearity(Index m, LinearityType* const_types); + + virtual bool get_starting_point(Index n, bool init_x, Number* x, + bool init_z, Number* z_L, Number* z_U, + Index m, bool init_lambda, + Number* lambda); + + virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate); + + virtual bool eval_f(Index n, const Number* x, bool new_x, + Number& obj_value); + + virtual bool eval_grad_f(Index n, const Number* x, bool new_x, + Number* grad_f); + + virtual bool eval_g(Index n, const Number* x, bool new_x, + Index m, Number* g); + + virtual bool eval_jac_g(Index n, const Number* x, bool new_x, + Index m, Index nele_jac, Index* iRow, + Index *jCol, Number* values); + + virtual bool eval_h(Index n, const Number* x, bool new_x, + Number obj_factor, Index m, const Number* lambda, + bool new_lambda, Index nele_hess, + Index* iRow, Index* jCol, Number* values); + + virtual void finalize_solution(SolverReturn status, + Index n, const Number* x, const Number* z_L, const Number* z_U, + Index m, const Number* g, const Number* lambda, + Number obj_value, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual bool intermediate_callback(AlgorithmMode mode, + Index iter, Number obj_value, + Number inf_pr, Number inf_du, + Number mu, Number d_norm, + Number regularization_size, + Number alpha_du, Number alpha_pr, + Index ls_trials, + const IpoptData* ip_data, + IpoptCalculatedQuantities* ip_cq); + + virtual Index get_number_of_nonlinear_variables(); + + virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, + Index* pos_nonlin_vars); + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + TNLPReducer(); + + /** Copy Constructor */ + TNLPReducer(const TNLPReducer&); + + /** Overloaded Equals Operator */ + void operator=(const TNLPReducer&); + //@} + + /** @name original TNLP */ + //@{ + SmartPtr<TNLP> tnlp_; + Index m_orig_; + Index nnz_jac_g_orig_; + //@} + + /** Number of constraints to be skipped */ + Index n_g_skip_; + + /** Array of indices of the constraints that are to be skipped. + * This is provided at the beginning in the constructor. */ + Index* index_g_skip_; + + /** Index style for original problem. Internally, we use C-Style + * now. */ + IndexStyleEnum index_style_orig_; + + /** Map from original constraints to new constraints. A -1 means + * that a constraint is skipped. */ + Index* g_keep_map_; + + /** Number of constraints in reduced NLP */ + Index m_reduced_; + + /** Number of Jacobian nonzeros in the reduced NLP */ + Index nnz_jac_g_reduced_; + + /** Number of Jacobian nonzeros that are skipped */ + Index nnz_jac_g_skipped_; + + /** Array of Jacobian elements that are to be skipped. This is in + * increasing order. */ + Index* jac_g_skipped_; + + /** Number of lower variable bounds to be skipped. */ + Index n_xL_skip_; + + /** Array of indices of the lower variable bounds to be skipped. */ + Index* index_xL_skip_; + + /** Number of upper variable bounds to be skipped. */ + Index n_xU_skip_; + + /** Array of indices of the upper variable bounds to be skipped. */ + Index* index_xU_skip_; + + /** Number of variables that are to be fixed to initial value. */ + Index n_x_fix_; + + /** Array of indices of the variables that are to be fixed. */ + Index* index_x_fix_; + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTaggedObject.hpp b/thirdparty/linux/include/coin1/IpTaggedObject.hpp new file mode 100644 index 0000000..7262c43 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTaggedObject.hpp @@ -0,0 +1,162 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTaggedObject.hpp 2613 2015-11-04 14:42:02Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTAGGEDOBJECT_HPP__ +#define __IPTAGGEDOBJECT_HPP__ + +#include "IpUtils.hpp" +#include "IpDebug.hpp" +#include "IpReferenced.hpp" +#include "IpObserver.hpp" +#include <limits> + +/* keyword to declare a thread-local variable according to http://en.wikipedia.org/wiki/Thread-local_storage + * GCC < 4.5 on MacOS X does not support TLS + * With Intel compiler on MacOS X, problems with TLS were reported. + */ +#ifndef IPOPT_THREAD_LOCAL + +#if defined(_MSC_VER) +#define IPOPT_THREAD_LOCAL __declspec(thread) +#elif defined(__APPLE__) && ((defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ < 405)) || defined(__INTEL_COMPILER)) +#define IPOPT_THREAD_LOCAL +#else +#define IPOPT_THREAD_LOCAL __thread +#endif + +#endif + +namespace Ipopt +{ + + /** TaggedObject class. + * Often, certain calculations or operations are expensive, + * and it can be very inefficient to perform these calculations + * again if the input to the calculation has not changed + * since the result was last stored. + * This base class provides an efficient mechanism to update + * a tag, indicating that the object has changed. + * Users of a TaggedObject class, need their own Tag data + * member to keep track of the state of the TaggedObject, the + * last time they performed a calculation. A basic use case for + * users of a class inheriting from TaggedObject follows like + * this: + * + * 1. Initialize your own Tag to zero in constructor. + * + * 2. Before an expensive calculation, + * check if the TaggedObject has changed, passing in + * your own Tag, indicating the last time you used + * the object for the calculation. If it has changed, + * perform the calculation again, and store the result. + * If it has not changed, simply return the stored result. + * + * Here is a simple example: + \verbatim + if (vector.HasChanged(my_vector_tag_)) { + my_vector_tag_ = vector.GetTag(); + result = PerformExpensiveCalculation(vector); + return result; + } + else { + return result; + } + \endverbatim + * + * Objects derived from TaggedObject must indicate that they have changed to + * the base class using the protected member function ObjectChanged(). For + * example, a Vector class, inside its own set method, MUST call + * ObjectChanged() to update the internally stored tag for comparison. + */ + class TaggedObject : public ReferencedObject, public Subject + { + public: + /** Type for the Tag values */ + typedef unsigned int Tag; + + /** Constructor. */ + TaggedObject() + : + Subject() + { + ObjectChanged(); + } + + /** Destructor. */ + virtual ~TaggedObject() + {} + + /** Users of TaggedObjects call this to + * update their own internal tags every time + * they perform the expensive operation. + */ + Tag GetTag() const + { + return tag_; + } + + /** Users of TaggedObjects call this to + * check if the object HasChanged since + * they last updated their own internal + * tag. + */ + bool HasChanged(const Tag comparison_tag) const + { + return (comparison_tag == tag_) ? false : true; + } + protected: + /** Objects derived from TaggedObject MUST call this + * method every time their internal state changes to + * update the internal tag for comparison + */ + void ObjectChanged() + { + DBG_START_METH("TaggedObject::ObjectChanged()", 0); + tag_ = unique_tag_; + unique_tag_++; + DBG_ASSERT(unique_tag_ < std::numeric_limits<Tag>::max()); + // The Notify method from the Subject base class notifies all + // registered Observers that this subject has changed. + Notify(Observer::NT_Changed); + } + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not implemented + * and we do not want the compiler to implement them for us, so we + * declare them private and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TaggedObject(const TaggedObject&); + + /** Overloaded Equals Operator */ + void operator=(const TaggedObject&); + //@} + + /** static data member that is incremented every + * time ANY TaggedObject changes. This allows us + * to obtain a unique Tag when the object changes + */ + static IPOPT_THREAD_LOCAL Tag unique_tag_; + + /** The tag indicating the current state of the object. + * We use this to compare against the comparison_tag + * in the HasChanged method. This member is updated + * from the unique_tag_ every time the object changes. + */ + Tag tag_; + + /** The index indicating the cache priority for this + * TaggedObject. If a result that depended on this + * TaggedObject is cached, it will be cached with this + * priority + */ + Index cache_priority_; + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpTimedTask.hpp b/thirdparty/linux/include/coin1/IpTimedTask.hpp new file mode 100644 index 0000000..a1c5bac --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTimedTask.hpp @@ -0,0 +1,146 @@ +// Copyright (C) 2006, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimedTask.hpp 1861 2010-12-21 21:34:47Z andreasw $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMEDTASK_HPP__ +#define __IPTIMEDTASK_HPP__ + +#include "IpUtils.hpp" + +namespace Ipopt +{ + /** This class is used to collect timing information for a + * particular task. */ + class TimedTask + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimedTask() + : + total_cputime_(0.), + total_systime_(0.), + total_walltime_(0.), + start_called_(false), + end_called_(true) + {} + + /** Default destructor */ + ~TimedTask() + {} + //@} + + /** Method for resetting time to zero. */ + void Reset() + { + total_cputime_ = 0.; + total_systime_ = 0.; + total_walltime_ = 0.; + start_called_ = false; + end_called_ = true; + } + + /** Method that is called before execution of the task. */ + void Start() + { + DBG_ASSERT(end_called_); + DBG_ASSERT(!start_called_); + end_called_ = false; + start_called_ = true; + start_cputime_ = CpuTime(); + start_systime_ = SysTime(); + start_walltime_ = WallclockTime(); + } + + /** Method that is called after execution of the task. */ + void End() + { + DBG_ASSERT(!end_called_); + DBG_ASSERT(start_called_); + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + + /** Method that is called after execution of the task for which + * timing might have been started. This only updates the timing + * if the timing has indeed been conducted. This is useful to + * stop timing after catching exceptions. */ + void EndIfStarted() + { + if (start_called_) { + end_called_ = true; + start_called_ = false; + total_cputime_ += CpuTime() - start_cputime_; + total_systime_ += SysTime() - start_systime_; + total_walltime_ += WallclockTime() - start_walltime_; + } + DBG_ASSERT(end_called_); + } + + /** Method returning total CPU time spend for task so far. */ + Number TotalCpuTime() const + { + DBG_ASSERT(end_called_); + return total_cputime_; + } + + /** Method returning total system time spend for task so far. */ + Number TotalSysTime() const + { + DBG_ASSERT(end_called_); + return total_systime_; + } + + /** Method returning total wall clock time spend for task so far. */ + Number TotalWallclockTime() const + { + DBG_ASSERT(end_called_); + return total_walltime_; + } + + private: + /**@name Default Compiler Generated Methods (Hidden to avoid + * implicit creation/calling). These methods are not + * implemented and we do not want the compiler to implement them + * for us, so we declare them private and do not define + * them. This ensures that they will not be implicitly + * created/called. */ + //@{ + /** Copy Constructor */ + TimedTask(const TimedTask&); + + /** Overloaded Equals Operator */ + void operator=(const TimedTask&); + //@} + + /** CPU time at beginning of task. */ + Number start_cputime_; + /** Total CPU time for task measured so far. */ + Number total_cputime_; + /** System time at beginning of task. */ + Number start_systime_; + /** Total system time for task measured so far. */ + Number total_systime_; + /** Wall clock time at beginning of task. */ + Number start_walltime_; + /** Total wall clock time for task measured so far. */ + Number total_walltime_; + + /** @name fields for debugging */ + //@{ + bool start_called_; + bool end_called_; + //@} + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTimingStatistics.hpp b/thirdparty/linux/include/coin1/IpTimingStatistics.hpp new file mode 100644 index 0000000..850ed1b --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTimingStatistics.hpp @@ -0,0 +1,213 @@ +// Copyright (C) 2005, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTimingStatistics.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Andreas Waechter IBM 2005-09-19 + +#ifndef __IPTIMINGSTATISTICS_HPP__ +#define __IPTIMINGSTATISTICS_HPP__ + +#include "IpReferenced.hpp" +#include "IpJournalist.hpp" +#include "IpTimedTask.hpp" + +namespace Ipopt +{ + /** This class collects all timing statistics for Ipopt. + */ + class TimingStatistics : public ReferencedObject + { + public: + /**@name Constructors/Destructors */ + //@{ + /** Default constructor. */ + TimingStatistics() + {} + + /** Default destructor */ + virtual ~TimingStatistics() + {} + //@} + + /** Method for resetting all times. */ + void ResetTimes(); + + /** Method for printing all timing information */ + void PrintAllTimingStatistics(Journalist& jnlst, + EJournalLevel level, + EJournalCategory category) const; + + /**@name Accessor methods to all timed tasks. */ + //@{ + TimedTask& OverallAlgorithm() + { + return OverallAlgorithm_; + } + TimedTask& PrintProblemStatistics() + { + return PrintProblemStatistics_; + } + TimedTask& InitializeIterates() + { + return InitializeIterates_; + } + TimedTask& UpdateHessian() + { + return UpdateHessian_; + } + TimedTask& OutputIteration() + { + return OutputIteration_; + } + TimedTask& UpdateBarrierParameter() + { + return UpdateBarrierParameter_; + } + TimedTask& ComputeSearchDirection() + { + return ComputeSearchDirection_; + } + TimedTask& ComputeAcceptableTrialPoint() + { + return ComputeAcceptableTrialPoint_; + } + TimedTask& AcceptTrialPoint() + { + return AcceptTrialPoint_; + } + TimedTask& CheckConvergence() + { + return CheckConvergence_; + } + + TimedTask& PDSystemSolverTotal() + { + return PDSystemSolverTotal_; + } + TimedTask& PDSystemSolverSolveOnce() + { + return PDSystemSolverSolveOnce_; + } + TimedTask& ComputeResiduals() + { + return ComputeResiduals_; + } + TimedTask& StdAugSystemSolverMultiSolve() + { + return StdAugSystemSolverMultiSolve_; + } + TimedTask& LinearSystemScaling() + { + return LinearSystemScaling_; + } + TimedTask& LinearSystemSymbolicFactorization() + { + return LinearSystemSymbolicFactorization_; + } + TimedTask& LinearSystemFactorization() + { + return LinearSystemFactorization_; + } + TimedTask& LinearSystemBackSolve() + { + return LinearSystemBackSolve_; + } + TimedTask& LinearSystemStructureConverter() + { + return LinearSystemStructureConverter_; + } + TimedTask& LinearSystemStructureConverterInit() + { + return LinearSystemStructureConverterInit_; + } + TimedTask& QualityFunctionSearch() + { + return QualityFunctionSearch_; + } + TimedTask& TryCorrector() + { + return TryCorrector_; + } + + TimedTask& Task1() + { + return Task1_; + } + TimedTask& Task2() + { + return Task2_; + } + TimedTask& Task3() + { + return Task3_; + } + TimedTask& Task4() + { + return Task4_; + } + TimedTask& Task5() + { + return Task5_; + } + TimedTask& Task6() + { + return Task6_; + } + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Copy Constructor */ + TimingStatistics(const TimingStatistics&); + + /** Overloaded Equals Operator */ + void operator=(const TimingStatistics&); + //@} + + /**@name All timed tasks. */ + //@{ + TimedTask OverallAlgorithm_; + TimedTask PrintProblemStatistics_; + TimedTask InitializeIterates_; + TimedTask UpdateHessian_; + TimedTask OutputIteration_; + TimedTask UpdateBarrierParameter_; + TimedTask ComputeSearchDirection_; + TimedTask ComputeAcceptableTrialPoint_; + TimedTask AcceptTrialPoint_; + TimedTask CheckConvergence_; + + TimedTask PDSystemSolverTotal_; + TimedTask PDSystemSolverSolveOnce_; + TimedTask ComputeResiduals_; + TimedTask StdAugSystemSolverMultiSolve_; + TimedTask LinearSystemScaling_; + TimedTask LinearSystemSymbolicFactorization_; + TimedTask LinearSystemFactorization_; + TimedTask LinearSystemBackSolve_; + TimedTask LinearSystemStructureConverter_; + TimedTask LinearSystemStructureConverterInit_; + TimedTask QualityFunctionSearch_; + TimedTask TryCorrector_; + + TimedTask Task1_; + TimedTask Task2_; + TimedTask Task3_; + TimedTask Task4_; + TimedTask Task5_; + TimedTask Task6_; + //@} + }; + +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTripletHelper.hpp b/thirdparty/linux/include/coin1/IpTripletHelper.hpp new file mode 100644 index 0000000..35424c0 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTripletHelper.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTripletHelper.hpp 2380 2013-09-06 22:57:49Z ghackebeil $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTRIPLETHELPER_HPP__ +#define __IPTRIPLETHELPER_HPP__ + +#include "IpTypes.hpp" +#include "IpException.hpp" + +namespace Ipopt +{ + + DECLARE_STD_EXCEPTION(UNKNOWN_MATRIX_TYPE); + DECLARE_STD_EXCEPTION(UNKNOWN_VECTOR_TYPE); + + /** forward declarations */ + class Matrix; + class GenTMatrix; + class SymTMatrix; + class DiagMatrix; + class IdentityMatrix; + class ExpansionMatrix; + class ScaledMatrix; + class SymScaledMatrix; + class SumMatrix; + class SumSymMatrix; + class ZeroMatrix; + class ZeroSymMatrix; + class CompoundMatrix; + class CompoundSymMatrix; + class TransposeMatrix; + class ExpandedMultiVectorMatrix; + class Vector; + + class TripletHelper + { + public: + /**@name A set of recursive routines that help with the Triplet format. */ + //@{ + /** find the total number of triplet entries of a Matrix */ + static Index GetNumberEntries(const Matrix& matrix); + + /** fill the irows, jcols structure for the triplet format from the matrix */ + static void FillRowCol(Index n_entries, const Matrix& matrix, Index* iRow, Index* jCol, Index row_offset=0, Index col_offset=0); + + /** fill the values for the triplet format from the matrix */ + static void FillValues(Index n_entries, const Matrix& matrix, Number* values); + + /** fill the values from the vector into a dense double* structure */ + static void FillValuesFromVector(Index dim, const Vector& vector, Number* values); + + /** put the values from the double* back into the vector */ + static void PutValuesInVector(Index dim, const double* values, Vector& vector); + //@} + + private: + /** find the total number of triplet entries for the SumMatrix */ + static Index GetNumberEntries_(const SumMatrix& matrix); + + /** find the total number of triplet entries for the SumSymMatrix */ + static Index GetNumberEntries_(const SumSymMatrix& matrix); + + /** find the total number of triplet entries for the CompoundMatrix */ + static Index GetNumberEntries_(const CompoundMatrix& matrix); + + /** find the total number of triplet entries for the CompoundSymMatrix */ + static Index GetNumberEntries_(const CompoundSymMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const TransposeMatrix& matrix); + + /** find the total number of triplet entries for the TransposeMatrix */ + static Index GetNumberEntries_(const ExpandedMultiVectorMatrix& matrix); + + static void FillRowCol_(Index n_entries, const GenTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const GenTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymTMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymTMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const DiagMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const DiagMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const IdentityMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const IdentityMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpansionMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpansionMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SumSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SumSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const CompoundSymMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const CompoundSymMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const SymScaledMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const SymScaledMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const TransposeMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const TransposeMatrix& matrix, Number* values); + + static void FillRowCol_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Index row_offset, Index col_offset, Index* iRow, Index* jCol); + + static void FillValues_(Index n_entries, const ExpandedMultiVectorMatrix& matrix, Number* values); + + }; +} // namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpTypes.hpp b/thirdparty/linux/include/coin1/IpTypes.hpp new file mode 100644 index 0000000..9c41b8f --- /dev/null +++ b/thirdparty/linux/include/coin1/IpTypes.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2004, 2006 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpTypes.hpp 2005 2011-06-06 12:55:16Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPTYPES_HPP__ +#define __IPTYPES_HPP__ + +#include "IpoptConfig.h" + +namespace Ipopt +{ + /** Type of all numbers */ + typedef double Number; + /** Type of all indices of vectors, matrices etc */ + typedef int Index; + /** Type of default integer */ + typedef int Int; + +} // namespace Ipopt + +/* Type of Fortran integer translated into C */ +typedef FORTRAN_INTEGER_TYPE ipfint; + +#endif diff --git a/thirdparty/linux/include/coin1/IpUtils.hpp b/thirdparty/linux/include/coin1/IpUtils.hpp new file mode 100644 index 0000000..4e5f045 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpUtils.hpp @@ -0,0 +1,128 @@ +// Copyright (C) 2004, 2009 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpUtils.hpp 2167 2013-03-08 11:15:38Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPUTILS_HPP__ +#define __IPUTILS_HPP__ + +// Standard Ip Include Files +#include "IpTypes.hpp" +#include "IpDebug.hpp" + +namespace Ipopt +{ + + inline Index Max(Index a, Index b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Index Max(Index a, Index b, Index c) + { + Index max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Index Max(Index a, Index b, Index c, Index d) + { + Index max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Index Min(Index a, Index b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Index Min(Index a, Index b, Index c) + { + Index min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Index Min(Index a, Index b, Index c, Index d) + { + Index min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /////////////////////////////////////////// + + inline Number Max(Number a, Number b) + { + return ((a) > (b) ? (a) : (b)); + } + + inline Number Max(Number a, Number b, Number c) + { + Number max = Max(a,b); + max = Max(max, c); + return max; + } + + inline Number Max(Number a, Number b, Number c, Number d) + { + Number max = Max(a, b, c); + max = Max(max, d); + return max; + } + + inline Number Min(Number a, Number b) + { + return ((a) < (b) ? (a) : (b)); + } + + inline Number Min(Number a, Number b, Number c) + { + Number min = Min(a,b); + min = Min(min, c); + return min; + } + + inline Number Min(Number a, Number b, Number c, Number d) + { + Number min = Min(a, b, c); + min = Min(min, d); + return min; + } + + /** Function returning true iff the argument is a valid double number + * (not NaN or Inf). */ + bool IsFiniteNumber(Number val); + + /** Function returning a random number between 0 and 1 */ + Number IpRandom01(); + + /** Function resetting the random number generator */ + void IpResetRandom01(); + + /** method determining CPU time */ + Number CpuTime(); + + /** method determining system time */ + Number SysTime(); + + /** method determining wallclock time since first call */ + Number WallclockTime(); + + /** Method for comparing two numbers within machine precision. The + * return value is true if lhs is less or equal the rhs, relaxing + * this inequality by something a little larger than machine + * precision relative to the absolute value of BasVal. */ + bool Compare_le(Number lhs, Number rhs, Number BasVal); + + /** Method for printing a formatted output to a string with given size. + */ + int Snprintf(char* str, long size, const char* format, ...); + +} //namespace Ipopt + +#endif diff --git a/thirdparty/linux/include/coin1/IpVector.hpp b/thirdparty/linux/include/coin1/IpVector.hpp new file mode 100644 index 0000000..a903558 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpVector.hpp @@ -0,0 +1,774 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpVector.hpp 2472 2014-04-05 17:47:20Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPVECTOR_HPP__ +#define __IPVECTOR_HPP__ + +#include "IpTypes.hpp" +#include "IpTaggedObject.hpp" +#include "IpCachedResults.hpp" +#include "IpSmartPtr.hpp" +#include "IpJournalist.hpp" +#include "IpException.hpp" + +#include <vector> + +namespace Ipopt +{ + /** Exception that can be used to flag unimplemented linear algebra + * methods */ + DECLARE_STD_EXCEPTION(UNIMPLEMENTED_LINALG_METHOD_CALLED); + + /* forward declarations */ + class VectorSpace; + + /** Vector Base Class. + * This is the base class for all derived vector types. Those vectors + * are meant to store entities like iterates, Lagrangian multipliers, + * constraint values etc. The implementation of a vector type depends + * on the computational environment (e.g. just a double array on a shared + * memory machine, or distributed double arrays for a distributed + * memory machine.) + * + * Deriving from Vector: This class inherits from tagged object to + * implement an advanced caching scheme. Because of this, the + * TaggedObject method ObjectChanged() must be called each time the + * Vector changes. If you overload the XXXX_Impl protected methods, + * this taken care of (along with caching if possible) for you. If + * you have additional methods in your derived class that change the + * underlying data (vector values), you MUST remember to call + * ObjectChanged() AFTER making the change! + */ + class Vector : public TaggedObject + { + public: + /** @name Constructor/Destructor */ + //@{ + /** Constructor. It has to be given a pointer to the + * corresponding VectorSpace. + */ + inline + Vector(const VectorSpace* owner_space); + + /** Destructor */ + inline + virtual ~Vector(); + //@} + + /** Create new Vector of the same type with uninitialized data */ + inline + Vector* MakeNew() const; + + /** Create new Vector of the same type and copy the data over */ + inline + Vector* MakeNewCopy() const; + + /**@name Standard BLAS-1 Operations + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + inline + void Copy(const Vector& x); + + /** Scales the vector by scalar alpha (DSCAL) */ + void Scal(Number alpha); + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + inline + void Axpy(Number alpha, const Vector &x); + + /** Computes inner product of vector x with this (DDOT) */ + inline + Number Dot(const Vector &x) const; + + /** Computes the 2-norm of this vector (DNRM2) */ + inline + Number Nrm2() const; + + /** Computes the 1-norm of this vector (DASUM) */ + inline + Number Asum() const; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + inline + Number Amax() const; + //@} + + /** @name Additional (Non-BLAS) Vector Methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Set each element in the vector to the scalar alpha. */ + inline + void Set(Number alpha); + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + inline + void ElementWiseDivide(const Vector& x); + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + inline + void ElementWiseMultiply(const Vector& x); + + /** Element-wise max against entries in x */ + inline + void ElementWiseMax(const Vector& x); + + /** Element-wise min against entries in x */ + inline + void ElementWiseMin(const Vector& x); + + /** Reciprocates the entries in the vector */ + inline + void ElementWiseReciprocal(); + + /** Absolute values of the entries in the vector */ + inline + void ElementWiseAbs(); + + /** Element-wise square root of the entries in the vector */ + inline + void ElementWiseSqrt(); + + /** Replaces the vector values with their sgn values + ( -1 if x_i < 0, 0 if x_i == 0, and 1 if x_i > 0) + */ + inline + void ElementWiseSgn(); + + /** Add scalar to every vector component */ + inline + void AddScalar(Number scalar); + + /** Returns the maximum value in the vector */ + inline + Number Max() const; + + /** Returns the minimum value in the vector */ + inline + Number Min() const; + + /** Returns the sum of the vector entries */ + inline + Number Sum() const; + + /** Returns the sum of the logs of each vector entry */ + inline + Number SumLogs() const; + //@} + + /** @name Methods for specialized operations. A prototype + * implementation is provided, but for efficient implementation + * those should be specially implemented. + */ + //@{ + /** Add one vector, y = a * v1 + c * y. This is automatically + * reduced to call AddTwoVectors. */ + inline + void AddOneVector(Number a, const Vector& v1, Number c); + + /** Add two vectors, y = a * v1 + b * v2 + c * y. Here, this + * vector is y */ + inline void AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + /** Fraction to the boundary parameter. Computes \f$\alpha = + * \max\{\bar\alpha\in(0,1] : x + \bar\alpha \Delta \geq (1-\tau)x\}\f$ + */ + inline + Number FracToBound(const Vector& delta, Number tau) const; + /** Add the quotient of two vectors, y = a * z/s + c * y. */ + inline + void AddVectorQuotient(Number a, const Vector& z, const Vector& s, + Number c); + //@} + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). */ + inline + bool HasValidNumbers() const; + + /** @name Accessor methods */ + //@{ + /** Dimension of the Vector */ + inline + Index Dim() const; + + /** Return the owner VectorSpace*/ + inline + SmartPtr<const VectorSpace> OwnerSpace() const; + //@} + + /** @name Output methods + * (derived classes do NOT overload these + * methods, instead, overload the + * protected versions of these methods). */ + //@{ + /** Print the entire vector */ + void Print(SmartPtr<const Journalist> jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + void Print(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent=0, + const std::string& prefix="") const; + //@} + + protected: + /** @name implementation methods (derived classes MUST + * overload these pure virtual protected methods.) + */ + //@{ + /** Copy the data of the vector x into this vector (DCOPY). */ + virtual void CopyImpl(const Vector& x)=0; + + /** Scales the vector by scalar alpha (DSCAL) */ + virtual void ScalImpl(Number alpha)=0; + + /** Add the multiple alpha of vector x to this vector (DAXPY) */ + virtual void AxpyImpl(Number alpha, const Vector &x)=0; + + /** Computes inner product of vector x with this (DDOT) */ + virtual Number DotImpl(const Vector &x) const =0; + + /** Computes the 2-norm of this vector (DNRM2) */ + virtual Number Nrm2Impl() const =0; + + /** Computes the 1-norm of this vector (DASUM) */ + virtual Number AsumImpl() const =0; + + /** Computes the max-norm of this vector (based on IDAMAX) */ + virtual Number AmaxImpl() const =0; + + /** Set each element in the vector to the scalar alpha. */ + virtual void SetImpl(Number alpha)=0; + + /** Element-wise division \f$y_i \gets y_i/x_i\f$*/ + virtual void ElementWiseDivideImpl(const Vector& x)=0; + + /** Element-wise multiplication \f$y_i \gets y_i*x_i\f$ */ + virtual void ElementWiseMultiplyImpl(const Vector& x)=0; + + /** Element-wise max against entries in x */ + virtual void ElementWiseMaxImpl(const Vector& x)=0; + + /** Element-wise min against entries in x */ + virtual void ElementWiseMinImpl(const Vector& x)=0; + + /** Reciprocates the elements of the vector */ + virtual void ElementWiseReciprocalImpl()=0; + + /** Take elementwise absolute values of the elements of the vector */ + virtual void ElementWiseAbsImpl()=0; + + /** Take elementwise square-root of the elements of the vector */ + virtual void ElementWiseSqrtImpl()=0; + + /** Replaces entries with sgn of the entry */ + virtual void ElementWiseSgnImpl()=0; + + /** Add scalar to every component of vector */ + virtual void AddScalarImpl(Number scalar)=0; + + /** Max value in the vector */ + virtual Number MaxImpl() const=0; + + /** Min number in the vector */ + virtual Number MinImpl() const=0; + + /** Sum of entries in the vector */ + virtual Number SumImpl() const=0; + + /** Sum of logs of entries in the vector */ + virtual Number SumLogsImpl() const=0; + + /** Add two vectors (a * v1 + b * v2). Result is stored in this + vector. */ + virtual void AddTwoVectorsImpl(Number a, const Vector& v1, + Number b, const Vector& v2, Number c); + + /** Fraction to boundary parameter. */ + virtual Number FracToBoundImpl(const Vector& delta, Number tau) const; + + /** Add the quotient of two vectors */ + virtual void AddVectorQuotientImpl(Number a, const Vector& z, + const Vector& s, Number c); + + /** Method for determining if all stored numbers are valid (i.e., + * no Inf or Nan). A default implementation using Asum is + * provided. */ + virtual bool HasValidNumbersImpl() const; + + /** Print the entire vector */ + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const =0; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default constructor */ + Vector(); + + /** Copy constructor */ + Vector(const Vector&); + + /** Overloaded Equals Operator */ + Vector& operator=(const Vector&); + //@} + + /** Vector Space */ + const SmartPtr<const VectorSpace> owner_space_; + + /**@name CachedResults data members */ + //@{ + /** Cache for dot products */ + mutable CachedResults<Number> dot_cache_; + + mutable TaggedObject::Tag nrm2_cache_tag_; + mutable Number cached_nrm2_; + + mutable TaggedObject::Tag asum_cache_tag_; + mutable Number cached_asum_; + + mutable TaggedObject::Tag amax_cache_tag_; + mutable Number cached_amax_; + + mutable TaggedObject::Tag max_cache_tag_; + mutable Number cached_max_; + + mutable TaggedObject::Tag min_cache_tag_; + mutable Number cached_min_; + + mutable TaggedObject::Tag sum_cache_tag_; + mutable Number cached_sum_; + + mutable TaggedObject::Tag sumlogs_cache_tag_; + mutable Number cached_sumlogs_; + + mutable TaggedObject::Tag valid_cache_tag_; + mutable bool cached_valid_; + + // AW: I removed this cache since it gets in the way for the + // quality function search + // /** Cache for FracToBound */ + // mutable CachedResults<Number> frac_to_bound_cache_; + //@} + + }; + + /** VectorSpace base class, corresponding to the Vector base class. + * For each Vector implementation, a corresponding VectorSpace has + * to be implemented. A VectorSpace is able to create new Vectors + * of a specific type. The VectorSpace should also store + * information that is common to all Vectors of that type. For + * example, the dimension of a Vector is stored in the VectorSpace + * base class. + */ + class VectorSpace : public ReferencedObject + { + public: + /** @name Constructors/Destructors */ + //@{ + /** Constructor, given the dimension of all vectors generated by + * this VectorSpace. + */ + VectorSpace(Index dim); + + /** Destructor */ + virtual ~VectorSpace() + {} + //@} + + /** Pure virtual method for creating a new Vector of the + * corresponding type. + */ + virtual Vector* MakeNew() const=0; + + /** Accessor function for the dimension of the vectors of this type.*/ + Index Dim() const + { + return dim_; + } + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** default constructor */ + VectorSpace(); + + /** Copy constructor */ + VectorSpace(const VectorSpace&); + + /** Overloaded Equals Operator */ + VectorSpace& operator=(const VectorSpace&); + //@} + + /** Dimension of the vectors in this vector space. */ + const Index dim_; + }; + + /* inline methods */ + inline + Vector::~Vector() + {} + + inline + Vector::Vector(const VectorSpace* owner_space) + : + TaggedObject(), + owner_space_(owner_space), + dot_cache_(10), + nrm2_cache_tag_(0), + asum_cache_tag_(0), + amax_cache_tag_(0), + max_cache_tag_(0), + min_cache_tag_(0), + sum_cache_tag_(0), + sumlogs_cache_tag_(0), + cached_valid_(0) + { + DBG_ASSERT(IsValid(owner_space_)); + } + + inline + Vector* Vector::MakeNew() const + { + return owner_space_->MakeNew(); + } + + inline + Vector* Vector::MakeNewCopy() const + { + // ToDo: We can probably copy also the cached values for Norms etc here + Vector* copy = MakeNew(); + copy->Copy(*this); + return copy; + } + + inline + void Vector::Copy(const Vector& x) + { + CopyImpl(x); + ObjectChanged(); + // Also copy any cached scalar values from the original vector + // ToDo: Check if that is too much overhead + TaggedObject::Tag x_tag = x.GetTag(); + if (x_tag == x.nrm2_cache_tag_) { + nrm2_cache_tag_ = GetTag(); + cached_nrm2_ = x.cached_nrm2_; + } + if (x_tag == x.asum_cache_tag_) { + asum_cache_tag_ = GetTag(); + cached_asum_ = x.cached_asum_; + } + if (x_tag == x.amax_cache_tag_) { + amax_cache_tag_ = GetTag(); + cached_amax_ = x.cached_amax_; + } + if (x_tag == x.max_cache_tag_) { + max_cache_tag_ = GetTag(); + cached_max_ = x.cached_max_; + } + if (x_tag == x.min_cache_tag_) { + min_cache_tag_ = GetTag(); + cached_min_ = x.cached_min_; + } + if (x_tag == x.sum_cache_tag_) { + sum_cache_tag_ = GetTag(); + cached_sum_ = x.cached_sum_; + } + if (x_tag == x.sumlogs_cache_tag_) { + sumlogs_cache_tag_ = GetTag(); + cached_sumlogs_ = x.cached_sumlogs_; + } + } + + inline + void Vector::Axpy(Number alpha, const Vector &x) + { + AxpyImpl(alpha, x); + ObjectChanged(); + } + + inline + Number Vector::Dot(const Vector &x) const + { + // The current implementation of the caching doesn't allow to have + // a dependency of something with itself. Therefore, we use the + // Nrm2 method if the dot product is to be taken with the vector + // itself. Might be more efficient anyway. + if (this==&x) { + Number nrm2 = Nrm2(); + return nrm2*nrm2; + } + Number retValue; + if (!dot_cache_.GetCachedResult2Dep(retValue, this, &x)) { + retValue = DotImpl(x); + dot_cache_.AddCachedResult2Dep(retValue, this, &x); + } + return retValue; + } + + inline + Number Vector::Nrm2() const + { + if (nrm2_cache_tag_ != GetTag()) { + cached_nrm2_ = Nrm2Impl(); + nrm2_cache_tag_ = GetTag(); + } + return cached_nrm2_; + } + + inline + Number Vector::Asum() const + { + if (asum_cache_tag_ != GetTag()) { + cached_asum_ = AsumImpl(); + asum_cache_tag_ = GetTag(); + } + return cached_asum_; + } + + inline + Number Vector::Amax() const + { + if (amax_cache_tag_ != GetTag()) { + cached_amax_ = AmaxImpl(); + amax_cache_tag_ = GetTag(); + } + return cached_amax_; + } + + inline + Number Vector::Sum() const + { + if (sum_cache_tag_ != GetTag()) { + cached_sum_ = SumImpl(); + sum_cache_tag_ = GetTag(); + } + return cached_sum_; + } + + inline + Number Vector::SumLogs() const + { + if (sumlogs_cache_tag_ != GetTag()) { + cached_sumlogs_ = SumLogsImpl(); + sumlogs_cache_tag_ = GetTag(); + } + return cached_sumlogs_; + } + + inline + void Vector::ElementWiseSgn() + { + ElementWiseSgnImpl(); + ObjectChanged(); + } + + inline + void Vector::Set(Number alpha) + { + // Could initialize caches here + SetImpl(alpha); + ObjectChanged(); + } + + inline + void Vector::ElementWiseDivide(const Vector& x) + { + ElementWiseDivideImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMultiply(const Vector& x) + { + ElementWiseMultiplyImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseReciprocal() + { + ElementWiseReciprocalImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMax(const Vector& x) + { + // Could initialize some caches here + ElementWiseMaxImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseMin(const Vector& x) + { + // Could initialize some caches here + ElementWiseMinImpl(x); + ObjectChanged(); + } + + inline + void Vector::ElementWiseAbs() + { + // Could initialize some caches here + ElementWiseAbsImpl(); + ObjectChanged(); + } + + inline + void Vector::ElementWiseSqrt() + { + ElementWiseSqrtImpl(); + ObjectChanged(); + } + + inline + void Vector::AddScalar(Number scalar) + { + // Could initialize some caches here + AddScalarImpl(scalar); + ObjectChanged(); + } + + inline + Number Vector::Max() const + { + if (max_cache_tag_ != GetTag()) { + cached_max_ = MaxImpl(); + max_cache_tag_ = GetTag(); + } + return cached_max_; + } + + inline + Number Vector::Min() const + { + if (min_cache_tag_ != GetTag()) { + cached_min_ = MinImpl(); + min_cache_tag_ = GetTag(); + } + return cached_min_; + } + + inline + void Vector::AddOneVector(Number a, const Vector& v1, Number c) + { + AddTwoVectors(a, v1, 0., v1, c); + } + + inline + void Vector::AddTwoVectors(Number a, const Vector& v1, + Number b, const Vector& v2, Number c) + { + AddTwoVectorsImpl(a, v1, b, v2, c); + ObjectChanged(); + } + + inline + Number Vector::FracToBound(const Vector& delta, Number tau) const + { + /* AW: I avoid the caching here, since it leads to overhead in the + quality function search. Caches for this are in + CalculatedQuantities. + Number retValue; + std::vector<const TaggedObject*> tdeps(1); + tdeps[0] = δ + std::vector<Number> sdeps(1); + sdeps[0] = tau; + if (!frac_to_bound_cache_.GetCachedResult(retValue, tdeps, sdeps)) { + retValue = FracToBoundImpl(delta, tau); + frac_to_bound_cache_.AddCachedResult(retValue, tdeps, sdeps); + } + return retValue; + */ + return FracToBoundImpl(delta, tau); + } + + inline + void Vector::AddVectorQuotient(Number a, const Vector& z, + const Vector& s, Number c) + { + AddVectorQuotientImpl(a, z, s, c); + ObjectChanged(); + } + + inline + bool Vector::HasValidNumbers() const + { + if (valid_cache_tag_ != GetTag()) { + cached_valid_ = HasValidNumbersImpl(); + valid_cache_tag_ = GetTag(); + } + return cached_valid_; + } + + inline + Index Vector::Dim() const + { + return owner_space_->Dim(); + } + + inline + SmartPtr<const VectorSpace> Vector::OwnerSpace() const + { + return owner_space_; + } + + inline + VectorSpace::VectorSpace(Index dim) + : + dim_(dim) + {} + +} // namespace Ipopt + +// Macro definitions for debugging vectors +#if COIN_IPOPT_VERBOSITY == 0 +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) +#else +# define DBG_PRINT_VECTOR(__verbose_level, __vec_name, __vec) \ + if (dbg_jrnl.Verbosity() >= (__verbose_level)) { \ + if (dbg_jrnl.Jnlst()!=NULL) { \ + (__vec).Print(dbg_jrnl.Jnlst(), \ + J_ERROR, J_DBG, \ + __vec_name, \ + dbg_jrnl.IndentationLevel()*2, \ + "# "); \ + } \ + } +#endif //if COIN_IPOPT_VERBOSITY == 0 + +#endif diff --git a/thirdparty/linux/include/coin1/IpZeroSymMatrix.hpp b/thirdparty/linux/include/coin1/IpZeroSymMatrix.hpp new file mode 100644 index 0000000..35ad95e --- /dev/null +++ b/thirdparty/linux/include/coin1/IpZeroSymMatrix.hpp @@ -0,0 +1,135 @@ +// Copyright (C) 2004, 2008 International Business Machines and others. +// All Rights Reserved. +// This code is published under the Eclipse Public License. +// +// $Id: IpZeroSymMatrix.hpp 2269 2013-05-05 11:32:40Z stefan $ +// +// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 + +#ifndef __IPZEROSYMMATRIX_HPP__ +#define __IPZEROSYMMATRIX_HPP__ + +#include "IpUtils.hpp" +#include "IpSymMatrix.hpp" + +namespace Ipopt +{ + + /** Class for Symmetric Matrices with only zero entries. + */ + class ZeroSymMatrix : public SymMatrix + { + public: + + /**@name Constructors / Destructors */ + //@{ + + /** Constructor, taking the corresponding matrix space. + */ + ZeroSymMatrix(const SymMatrixSpace* owner_space); + + /** Destructor */ + ~ZeroSymMatrix(); + //@} + + protected: + /**@name Methods overloaded from matrix */ + //@{ + virtual void MultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void TransMultVectorImpl(Number alpha, const Vector& x, + Number beta, Vector& y) const; + + virtual void ComputeRowAMaxImpl(Vector& rows_norms, bool init) const + {} + + virtual void ComputeColAMaxImpl(Vector& cols_norms, bool init) const + {} + + virtual void PrintImpl(const Journalist& jnlst, + EJournalLevel level, + EJournalCategory category, + const std::string& name, + Index indent, + const std::string& prefix) const; + //@} + + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrix(); + + /** Copy Constructor */ + ZeroSymMatrix(const ZeroSymMatrix&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrix&); + //@} + }; + + /** Class for matrix space for ZeroSymMatrix. */ + class ZeroSymMatrixSpace : public SymMatrixSpace + { + public: + /** @name Constructors / Destructors */ + //@{ + /** Constructor, given the number of row and columns. + */ + ZeroSymMatrixSpace(Index dim) + : + SymMatrixSpace(dim) + {} + + /** Destructor */ + virtual ~ZeroSymMatrixSpace() + {} + //@} + + /** Overloaded MakeNew method for the MatrixSpace base class. + */ + virtual Matrix* MakeNew() const + { + return MakeNewZeroSymMatrix(); + } + + /** Overloaded method from SymMatrixSpace base class + */ + virtual SymMatrix* MakeNewSymMatrix() const + { + return MakeNewZeroSymMatrix(); + } + + /** Method for creating a new matrix of this specific type. */ + ZeroSymMatrix* MakeNewZeroSymMatrix() const + { + return new ZeroSymMatrix(this); + } + private: + /**@name Default Compiler Generated Methods + * (Hidden to avoid implicit creation/calling). + * These methods are not implemented and + * we do not want the compiler to implement + * them for us, so we declare them private + * and do not define them. This ensures that + * they will not be implicitly created/called. */ + //@{ + /** Default Constructor */ + ZeroSymMatrixSpace(); + + /** Copy Constructor */ + ZeroSymMatrixSpace(const ZeroSymMatrixSpace&); + + /** Overloaded Equals Operator */ + void operator=(const ZeroSymMatrixSpace&); + //@} + }; +} // namespace Ipopt +#endif diff --git a/thirdparty/linux/include/coin1/IpoptConfig.h b/thirdparty/linux/include/coin1/IpoptConfig.h new file mode 100644 index 0000000..78dadd3 --- /dev/null +++ b/thirdparty/linux/include/coin1/IpoptConfig.h @@ -0,0 +1,22 @@ +/* src/Common/config_ipopt.h. Generated by configure. */ +/* src/Common/config_ipopt.h.in. */ + +#ifndef __CONFIG_IPOPT_H__ +#define __CONFIG_IPOPT_H__ + +/* Version number of project */ +#define IPOPT_VERSION "3.12.7" + +/* Major Version number of project */ +#define IPOPT_VERSION_MAJOR 3 + +/* Minor Version number of project */ +#define IPOPT_VERSION_MINOR 12 + +/* Release Version number of project */ +#define IPOPT_VERSION_RELEASE 7 + +/* Define to the C type corresponding to Fortran INTEGER */ +#define FORTRAN_INTEGER_TYPE int + +#endif diff --git a/thirdparty/linux/include/coin1/OsiAuxInfo.hpp b/thirdparty/linux/include/coin1/OsiAuxInfo.hpp new file mode 100644 index 0000000..182d981 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiAuxInfo.hpp @@ -0,0 +1,206 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiAuxInfo_H +#define OsiAuxInfo_H + +class OsiSolverInterface; + +//############################################################################# +/** This class allows for a more structured use of algorithmic tweaking to + an OsiSolverInterface. It is designed to replace the simple use of + appData_ pointer. + + This has been done to make it easier to use NonLinear solvers and other + exotic beasts in a branch and bound mode. After this class definition + there is one for a derived class for just such a purpose. + +*/ + +class OsiAuxInfo { +public: + // Default Constructor + OsiAuxInfo (void * appData = NULL); + + // Copy Constructor + OsiAuxInfo (const OsiAuxInfo & rhs); + // Destructor + virtual ~OsiAuxInfo(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiAuxInfo & operator=(const OsiAuxInfo& rhs); + + /// Get application data + inline void * getApplicationData() const + { return appData_;} +protected: + /// Pointer to user-defined data structure + void * appData_; +}; +//############################################################################# +/** This class allows for the use of more exotic solvers e.g. Non-Linear or Volume. + + You can derive from this although at present I can't see the need. +*/ + +class OsiBabSolver : public OsiAuxInfo { +public: + // Default Constructor + OsiBabSolver (int solverType=0); + + // Copy Constructor + OsiBabSolver (const OsiBabSolver & rhs); + // Destructor + virtual ~OsiBabSolver(); + + /// Clone + virtual OsiAuxInfo * clone() const; + /// Assignment operator + OsiBabSolver & operator=(const OsiBabSolver& rhs); + + /// Update solver + inline void setSolver(const OsiSolverInterface * solver) + { solver_ = solver;} + /// Update solver + inline void setSolver(const OsiSolverInterface & solver) + { solver_ = &solver;} + + /** returns 0 if no heuristic solution, 1 if valid solution + with better objective value than one passed in + Sets solution values if good, sets objective value + numberColumns is size of newSolution + */ + int solution(double & objectiveValue, + double * newSolution, int numberColumns); + /** Set solution and objective value. + Number of columns and optimization direction taken from current solver. + Size of solution is numberColumns (may be padded or truncated in function) */ + void setSolution(const double * solution, int numberColumns, double objectiveValue); + + /** returns true if the object stores a solution, false otherwise. If there + is a solution then solutionValue and solution will be filled out as well. + In that case the user needs to allocate solution to be a big enough + array. + */ + bool hasSolution(double & solutionValue, double * solution); + + /** Sets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check solver to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline void setSolverType(int value) + { solverType_=value;} + /** gets solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + 4 - normal solver but cuts are needed for integral solution + */ + inline int solverType() const + { return solverType_;} + /** Return true if getting solution may add cuts so hot start etc will + be obsolete */ + inline bool solutionAddsCuts() const + { return solverType_==3;} + /// Return true if we should try cuts at root even if looks satisfied + inline bool alwaysTryCutsAtRootNode() const + { return solverType_==4;} + /** Returns true if can use solver objective or feasible values, + otherwise use mipBound etc */ + inline bool solverAccurate() const + { return solverType_==0||solverType_==2||solverType_==4;} + /// Returns true if can use reduced costs for fixing + inline bool reducedCostsAccurate() const + { return solverType_==0||solverType_==4;} + /// Get objective (well mip bound) + double mipBound() const; + /// Returns true if node feasible + bool mipFeasible() const; + /// Set mip bound (only used for some solvers) + inline void setMipBound(double value) + { mipBound_ = value;} + /// Get objective value of saved solution + inline double bestObjectiveValue() const + { return bestObjectiveValue_;} + /// Says whether we want to try cuts at all + inline bool tryCuts() const + { return solverType_!=2;} + /// Says whether we have a warm start (so can do strong branching) + inline bool warmStart() const + { return solverType_!=2;} + /** Get bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline int extraCharacteristics() const + { return extraCharacteristics_;} + /** Set bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + inline void setExtraCharacteristics(int value) + { extraCharacteristics_=value;} + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + inline const double * beforeLower() const + { return beforeLower_;} + /// Set pointer to lower bounds before branch (only if extraCharacteristics set) + inline void setBeforeLower(const double * array) + { beforeLower_ = array;} + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + inline const double * beforeUpper() const + { return beforeUpper_;} + /// Set pointer to upper bounds before branch (only if extraCharacteristics set) + inline void setBeforeUpper(const double * array) + { beforeUpper_ = array;} +protected: + /// Objective value of best solution (if there is one) (minimization) + double bestObjectiveValue_; + /// Current lower bound on solution ( if > 1.0e50 infeasible) + double mipBound_; + /// Solver to use for getting/setting solutions etc + const OsiSolverInterface * solver_; + /// Best integer feasible solution + double * bestSolution_; + /// Pointer to lower bounds before branch (only if extraCharacteristics set) + const double * beforeLower_; + /// Pointer to upper bounds before branch (only if extraCharacteristics set) + const double * beforeUpper_; + /** Solver type + 0 - normal LP solver + 1 - DW - may also return heuristic solutions + 2 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is + - may also return heuristic solution + 3 - NLP solver or similar - can't compute objective value just from solution + check this (rather than solver) to see if feasible and what objective value is. + Using Outer Approximation so called lp based + - may also return heuristic solution + */ + int solverType_; + /// Size of solution + int sizeSolution_; + /** Bit mask for odd actions of solvers + 1 - solution or bound arrays may move in mysterious ways e.g. cplex + 2 - solver may want bounds before branch + */ + int extraCharacteristics_; +}; + +#endif diff --git a/thirdparty/linux/include/coin1/OsiBranchingObject.hpp b/thirdparty/linux/include/coin1/OsiBranchingObject.hpp new file mode 100644 index 0000000..78b6984 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiBranchingObject.hpp @@ -0,0 +1,1005 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiBranchingObject_H +#define OsiBranchingObject_H + +#include <cassert> +#include <string> +#include <vector> + +#include "CoinError.hpp" +#include "CoinTypes.hpp" + +class OsiSolverInterface; +class OsiSolverBranch; + +class OsiBranchingObject; +class OsiBranchingInformation; + +//############################################################################# +//This contains the abstract base class for an object and for branching. +//It also contains a simple integer class +//############################################################################# + +/** Abstract base class for `objects'. + + The branching model used in Osi is based on the idea of an <i>object</i>. + In the abstract, an object is something that has a feasible region, can be + evaluated for infeasibility, can be branched on (<i>i.e.</i>, there's some + constructive action to be taken to move toward feasibility), and allows + comparison of the effect of branching. + + This class (OsiObject) is the base class for an object. To round out the + branching model, the class OsiBranchingObject describes how to perform a + branch, and the class OsiBranchDecision describes how to compare two + OsiBranchingObjects. + + To create a new type of object you need to provide three methods: + #infeasibility(), #feasibleRegion(), and #createBranch(), described below. + + This base class is primarily virtual to allow for any form of structure. + Any form of discontinuity is allowed. + + As there is an overhead in getting information from solvers and because + other useful information is available there is also an OsiBranchingInformation + class which can contain pointers to information. + If used it must at minimum contain pointers to current value of objective, + maximum allowed objective and pointers to arrays for bounds and solution + and direction of optimization. Also integer and primal tolerance. + + Classes which inherit might have other information such as depth, number of + solutions, pseudo-shadow prices etc etc. + May be easier just to throw in here - as I keep doing +*/ +class OsiObject { + +public: + + /// Default Constructor + OsiObject (); + + /// Copy constructor + OsiObject ( const OsiObject &); + + /// Assignment operator + OsiObject & operator=( const OsiObject& rhs); + + /// Clone + virtual OsiObject * clone() const=0; + + /// Destructor + virtual ~OsiObject (); + + /** Infeasibility of the object + + This is some measure of the infeasibility of the object. 0.0 + indicates that the object is satisfied. + + The preferred branching direction is returned in whichWay, where for + normal two-way branching 0 is down, 1 is up + + This is used to prepare for strong branching but should also think of + case when no strong branching + + The object may also compute an estimate of cost of going "up" or "down". + This will probably be based on pseudo-cost ideas + + This should also set mutable infeasibility_ and whichWay_ + This is for instant re-use for speed + + Default for this just calls infeasibility with OsiBranchingInformation + NOTE - Convention says that an infeasibility of COIN_DBL_MAX means + object has worked out it can't be satisfied! + */ + double infeasibility(const OsiSolverInterface * solver,int &whichWay) const ; + // Faster version when more information available + virtual double infeasibility(const OsiBranchingInformation * info, int &whichWay) const =0; + // This does NOT set mutable stuff + virtual double checkInfeasibility(const OsiBranchingInformation * info) const; + + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + */ + virtual double feasibleRegion(OsiSolverInterface * solver) const ; + /** For the variable(s) referenced by the object, + look at the current solution and set bounds to match the solution. + Returns measure of how much it had to move solution to make feasible + Faster version + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const =0; + + /** Create a branching object and indicate which way to branch first. + + The branching object has to know how to create branches (fix + variables, etc.) + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * /*solver*/, + const OsiBranchingInformation * /*info*/, + int /*way*/) const {throw CoinError("Need code","createBranch","OsiBranchingObject"); return NULL; } + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return true;} + /** \brief Return true if object can take part in move to nearest heuristic + */ + virtual bool canMoveToNearest() const + {return false;} + /** Column number if single column object -1 otherwise, + Used by heuristics + */ + virtual int columnNumber() const; + /// Return Priority - note 1 is highest priority + inline int priority() const + { return priority_;} + /// Set priority + inline void setPriority(int priority) + { priority_ = priority;} + /** \brief Return true if branch should only bound variables + */ + virtual bool boundBranch() const + {return true;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} + /// Return maximum number of ways branch may have + inline int numberWays() const + { return numberWays_;} + /// Set maximum number of ways branch may have + inline void setNumberWays(int numberWays) + { numberWays_ = static_cast<short int>(numberWays) ; } + /** Return preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline void setWhichWay(int way) + { whichWay_ = static_cast<short int>(way) ; } + /** Return current preferred way to branch. If two + then way=0 means down and 1 means up, otherwise + way points to preferred branch + */ + inline int whichWay() const + { return whichWay_;} + /// Get pre-emptive preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return -1;} + /// Return infeasibility + inline double infeasibility() const + { return infeasibility_;} + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * ) {} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int , const int * ) {} + /// Updates stuff like pseudocosts before threads + virtual void updateBefore(const OsiObject * ) {} + /// Updates stuff like pseudocosts after threads finished + virtual void updateAfter(const OsiObject * , const OsiObject * ) {} + +protected: + /// data + + /// Computed infeasibility + mutable double infeasibility_; + /// Computed preferred way to branch + mutable short whichWay_; + /// Maximum number of ways on branch + short numberWays_; + /// Priority + int priority_; + +}; +/// Define a class to add a bit of complexity to OsiObject +/// This assumes 2 way branching + + +class OsiObject2 : public OsiObject { + +public: + + /// Default Constructor + OsiObject2 (); + + /// Copy constructor + OsiObject2 ( const OsiObject2 &); + + /// Assignment operator + OsiObject2 & operator=( const OsiObject2& rhs); + + /// Destructor + virtual ~OsiObject2 (); + + /// Set preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + inline void setPreferredWay(int value) + {preferredWay_=value;} + + /// Get preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + virtual int preferredWay() const + { return preferredWay_;} +protected: + /// Preferred way of branching - -1 off, 0 down, 1 up (for 2-way) + int preferredWay_; + /// "Infeasibility" on other way + mutable double otherInfeasibility_; + +}; + +/** \brief Abstract branching object base class + + In the abstract, an OsiBranchingObject contains instructions for how to + branch. We want an abstract class so that we can describe how to branch on + simple objects (<i>e.g.</i>, integers) and more exotic objects + (<i>e.g.</i>, cliques or hyperplanes). + + The #branch() method is the crucial routine: it is expected to be able to + step through a set of branch arms, executing the actions required to create + each subproblem in turn. The base class is primarily virtual to allow for + a wide range of problem modifications. + + See OsiObject for an overview of the two classes (OsiObject and + OsiBranchingObject) which make up Osi's branching + model. +*/ + +class OsiBranchingObject { + +public: + + /// Default Constructor + OsiBranchingObject (); + + /// Constructor + OsiBranchingObject (OsiSolverInterface * solver, double value); + + /// Copy constructor + OsiBranchingObject ( const OsiBranchingObject &); + + /// Assignment operator + OsiBranchingObject & operator=( const OsiBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const=0; + + /// Destructor + virtual ~OsiBranchingObject (); + + /// The number of branch arms created for this branching object + inline int numberBranches() const + {return numberBranches_;} + + /// The number of branch arms left for this branching object + inline int numberBranchesLeft() const + {return numberBranches_-branchIndex_;} + + /// Increment the number of branch arms left for this branching object + inline void incrementNumberBranchesLeft() + { numberBranches_ ++;} + + /** Set the number of branch arms left for this branching object + Just for forcing + */ + inline void setNumberBranchesLeft(int /*value*/) + {/*assert (value==1&&!branchIndex_);*/ numberBranches_=1;} + + /// Decrement the number of branch arms left for this branching object + inline void decrementNumberBranchesLeft() + {branchIndex_++;} + + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + /** \brief Execute the actions required to branch, as specified by the + current state of the branching object, and advance the object's + state. + Returns change in guessed objective on next branch + */ + virtual double branch() {return branch(NULL);} + /** \brief Return true if branch should fix variables + */ + virtual bool boundBranch() const + {return true;} + /** Get the state of the branching object + This is just the branch index + */ + inline int branchIndex() const + {return branchIndex_;} + + /** Set the state of the branching object. + */ + inline void setBranchingIndex(int branchIndex) + { branchIndex_ = static_cast<short int>(branchIndex) ; } + + /// Current value + inline double value() const + {return value_;} + + /// Return pointer back to object which created + inline const OsiObject * originalObject() const + {return originalObject_;} + /// Set pointer back to object which created + inline void setOriginalObject(const OsiObject * object) + {originalObject_=object;} + /** Double checks in case node can change its mind! + Returns objective value + Can change objective etc */ + virtual void checkIsCutoff(double ) {} + /// For debug + int columnNumber() const; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * =NULL) const {} + +protected: + + /// Current value - has some meaning about branch + double value_; + + /// Pointer back to object which created + const OsiObject * originalObject_; + + /** Number of branches + */ + int numberBranches_; + + /** The state of the branching object. i.e. branch index + This starts at 0 when created + */ + short branchIndex_; + +}; +/* This contains information + This could also contain pseudo shadow prices + or information for dealing with computing and trusting pseudo-costs +*/ +class OsiBranchingInformation { + +public: + + /// Default Constructor + OsiBranchingInformation (); + + /** Useful Constructor + (normalSolver true if has matrix etc etc) + copySolution true if constructot should make a copy + */ + OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false); + + /// Copy constructor + OsiBranchingInformation ( const OsiBranchingInformation &); + + /// Assignment operator + OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs); + + /// Clone + virtual OsiBranchingInformation * clone() const; + + /// Destructor + virtual ~OsiBranchingInformation (); + + // Note public +public: + /// data + + /** State of search + 0 - no solution + 1 - only heuristic solutions + 2 - branched to a solution + 3 - no solution but many nodes + */ + int stateOfSearch_; + /// Value of objective function (in minimization sense) + double objectiveValue_; + /// Value of objective cutoff (in minimization sense) + double cutoff_; + /// Direction 1.0 for minimization, -1.0 for maximization + double direction_; + /// Integer tolerance + double integerTolerance_; + /// Primal tolerance + double primalTolerance_; + /// Maximum time remaining before stopping on time + double timeRemaining_; + /// Dual to use if row bound violated (if negative then pseudoShadowPrices off) + double defaultDual_; + /// Pointer to solver + mutable const OsiSolverInterface * solver_; + /// The number of columns + int numberColumns_; + /// Pointer to current lower bounds on columns + mutable const double * lower_; + /// Pointer to current solution + mutable const double * solution_; + /// Pointer to current upper bounds on columns + mutable const double * upper_; + /// Highly optional target (hot start) solution + const double * hotstartSolution_; + /// Pointer to duals + const double * pi_; + /// Pointer to row activity + const double * rowActivity_; + /// Objective + const double * objective_; + /// Pointer to current lower bounds on rows + const double * rowLower_; + /// Pointer to current upper bounds on rows + const double * rowUpper_; + /// Elements in column copy of matrix + const double * elementByColumn_; + /// Column starts + const CoinBigIndex * columnStart_; + /// Column lengths + const int * columnLength_; + /// Row indices + const int * row_; + /** Useful region of length CoinMax(numberColumns,2*numberRows) + This is allocated and deleted before OsiObject::infeasibility + It is zeroed on entry and should be so on exit + It only exists if defaultDual_>=0.0 + */ + double * usefulRegion_; + /// Useful index region to go with usefulRegion_ + int * indexRegion_; + /// Number of solutions found + int numberSolutions_; + /// Number of branching solutions found (i.e. exclude heuristics) + int numberBranchingSolutions_; + /// Depth in tree + int depth_; + /// TEMP + bool owningSolution_; +}; + +/// This just adds two-wayness to a branching object + +class OsiTwoWayBranchingObject : public OsiBranchingObject { + +public: + + /// Default constructor + OsiTwoWayBranchingObject (); + + /** Create a standard tw0-way branch object + + Specifies a simple two-way branch. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject, + int way , double value) ; + + /// Copy constructor + OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &); + + /// Assignment operator + OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs); + + /// Destructor + virtual ~OsiTwoWayBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver)=0; + + inline int firstBranch() const { return firstBranch_; } + /// Way returns -1 on down +1 on up + inline int way() const + { return !branchIndex_ ? firstBranch_ : -firstBranch_;} +protected: + /// Which way was first branch -1 = down, +1 = up + int firstBranch_; +}; +/// Define a single integer class + + +class OsiSimpleInteger : public OsiObject2 { + +public: + + /// Default Constructor + OsiSimpleInteger (); + + /// Useful constructor - passed solver index + OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn); + + /// Useful constructor - passed solver index and original bounds + OsiSimpleInteger (int iColumn, double lower, double upper); + + /// Copy constructor + OsiSimpleInteger ( const OsiSimpleInteger &); + + /// Clone + virtual OsiObject * clone() const; + + /// Assignment operator + OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs); + + /// Destructor + virtual ~OsiSimpleInteger (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + + /// Original bounds + inline double originalLowerBound() const + { return originalLower_;} + inline void setOriginalLowerBound(double value) + { originalLower_=value;} + inline double originalUpperBound() const + { return originalUpper_;} + inline void setOriginalUpperBound(double value) + { originalUpper_=value;} + /** Reset variable bounds to their original values. + Bounds may be tightened, so it may be good to be able to reset them to + their original values. + */ + virtual void resetBounds(const OsiSolverInterface * solver) ; + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return false;} +protected: + /// data + /// Original lower bound + double originalLower_; + /// Original upper bound + double originalUpper_; + /// Column number in solver + int columnNumber_; + +}; +/** Simple branching object for an integer variable + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. 0 -> down, 1-> up. +*/ + +class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiIntegerBranchingObject (); + + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be lb <= x <= floor(x*), the other ceil(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value) ; + /** Create a standard floor/ceiling branch object + + Specifies a simple two-way branch in a more flexible way. One arm of the + branch will be lb <= x <= downUpperBound, the other upLowerBound <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject, + int way , double value, double downUpperBound, double upLowerBound) ; + + /// Copy constructor + OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &); + + /// Assignment operator + OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiIntegerBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + // Probably could get away with just value which is already stored + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; + + +/** Define Special Ordered Sets of type 1 and 2. These do not have to be + integer - so do not appear in lists of integers. + + which_ points columns of matrix +*/ + + +class OsiSOS : public OsiObject2 { + +public: + + // Default Constructor + OsiSOS (); + + /** Useful constructor - which are indices + and weights are also given. If null then 0,1,2.. + type is SOS type + */ + OsiSOS (const OsiSolverInterface * solver, int numberMembers, + const int * which, const double * weights, int type=1); + + // Copy constructor + OsiSOS ( const OsiSOS &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiSOS & operator=( const OsiSOS& rhs); + + // Destructor + virtual ~OsiSOS (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to fix the variable at the current (integer) value. + + Given an integer value, set the lower and upper bounds to fix the + variable. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + + /// Redoes data when sequence numbers change + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Number of members + inline int numberMembers() const + {return numberMembers_;} + + /// Members (indices in range 0 ... numberColumns-1) + inline const int * members() const + {return members_;} + + /// SOS type + inline int sosType() const + {return sosType_;} + + /// SOS type + inline int setType() const + {return sosType_;} + + /** Array of weights */ + inline const double * weights() const + { return weights_;} + + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return (sosType_==1&&integerValued_);} + /// Set whether set is integer valued or not + inline void setIntegerValued(bool yesNo) + { integerValued_=yesNo;} + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /// Set number of members + inline void setNumberMembers(int value) + {numberMembers_=value;} + + /// Members (indices in range 0 ... numberColumns-1) + inline int * mutableMembers() const + {return members_;} + + /// Set SOS type + inline void setSosType(int value) + {sosType_=value;} + + /** Array of weights */ + inline double * mutableWeights() const + { return weights_;} +protected: + /// data + + /// Members (indices in range 0 ... numberColumns-1) + int * members_; + /// Weights + double * weights_; + + /// Number of members + int numberMembers_; + /// SOS type + int sosType_; + /// Whether integer valued + bool integerValued_; +}; + +/** Branching object for Special ordered sets + + */ +class OsiSOSBranchingObject : public OsiTwoWayBranchingObject { + +public: + + // Default Constructor + OsiSOSBranchingObject (); + + // Useful constructor + OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject, + int way, + double separator); + + // Copy constructor + OsiSOSBranchingObject ( const OsiSOSBranchingObject &); + + // Assignment operator + OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + // Destructor + virtual ~OsiSOSBranchingObject (); + + using OsiBranchingObject::branch ; + /// Does next branch and updates state + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); +private: + /// data +}; +/** Lotsize class */ + + +class OsiLotsize : public OsiObject2 { + +public: + + // Default Constructor + OsiLotsize (); + + /* Useful constructor - passed model index. + Also passed valid values - if range then pairs + */ + OsiLotsize (const OsiSolverInterface * solver, int iColumn, + int numberPoints, const double * points, bool range=false); + + // Copy constructor + OsiLotsize ( const OsiLotsize &); + + /// Clone + virtual OsiObject * clone() const; + + // Assignment operator + OsiLotsize & operator=( const OsiLotsize& rhs); + + // Destructor + virtual ~OsiLotsize (); + + using OsiObject::infeasibility ; + /// Infeasibility - large is 0.5 + virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const; + + using OsiObject::feasibleRegion ; + /** Set bounds to contain the current solution. + + More precisely, for the variable associated with this object, take the + value given in the current solution, force it within the current bounds + if required, then set the bounds to fix the variable at the integer + nearest the solution value. Returns amount it had to move variable. + */ + virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const; + + /** Creates a branching object + + The preferred direction is set by \p way, 0 for down, 1 for up. + */ + virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const; + + + /// Set solver column number + inline void setColumnNumber(int value) + {columnNumber_=value;} + + /** Column number if single column object -1 otherwise, + so returns >= 0 + Used by heuristics + */ + virtual int columnNumber() const; + /** Reset original upper and lower bound values from the solver. + + Handy for updating bounds held in this object after bounds held in the + solver have been tightened. + */ + virtual void resetBounds(const OsiSolverInterface * solver); + + /** Finds range of interest so value is feasible in range range_ or infeasible + between hi[range_] and lo[range_+1]. Returns true if feasible. + */ + bool findRange(double value, double integerTolerance) const; + + /** Returns floor and ceiling + */ + virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value, + double tolerance) const; + + /// Original bounds + inline double originalLowerBound() const + { return bound_[0];} + inline double originalUpperBound() const + { return bound_[rangeType_*numberRanges_-1];} + /// Type - 1 points, 2 ranges + inline int rangeType() const + { return rangeType_;} + /// Number of points + inline int numberRanges() const + { return numberRanges_;} + /// Ranges + inline double * bound() const + { return bound_;} + /** Change column numbers after preprocessing + */ + virtual void resetSequenceEtc(int numberColumns, const int * originalColumns); + + /// Return "up" estimate (default 1.0e-5) + virtual double upEstimate() const; + /// Return "down" estimate (default 1.0e-5) + virtual double downEstimate() const; + /// Return true if knows how to deal with Pseudo Shadow Prices + virtual bool canHandleShadowPrices() const + { return true;} + /** \brief Return true if object can take part in normal heuristics + */ + virtual bool canDoHeuristics() const + {return false;} + +private: + /// data + + /// Column number in model + int columnNumber_; + /// Type - 1 points, 2 ranges + int rangeType_; + /// Number of points + int numberRanges_; + // largest gap + double largestGap_; + /// Ranges + double * bound_; + /// Current range + mutable int range_; +}; + + +/** Lotsize branching object + + This object can specify a two-way branch on an integer variable. For each + arm of the branch, the upper and lower bounds on the variable can be + independently specified. + + Variable_ holds the index of the integer variable in the integerVariable_ + array of the model. +*/ + +class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject { + +public: + + /// Default constructor + OsiLotsizeBranchingObject (); + + /** Create a lotsize floor/ceiling branch object + + Specifies a simple two-way branch. Let \p value = x*. One arm of the + branch will be is lb <= x <= valid range below(x*), the other valid range above(x*) <= x <= ub. + Specify way = -1 to set the object state to perform the down arm first, + way = 1 for the up arm. + */ + OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject, + int way , double value) ; + + /// Copy constructor + OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &); + + /// Assignment operator + OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs); + + /// Clone + virtual OsiBranchingObject * clone() const; + + /// Destructor + virtual ~OsiLotsizeBranchingObject (); + + using OsiBranchingObject::branch ; + /** \brief Sets the bounds for the variable according to the current arm + of the branch and advances the object state to the next arm. + state. + Returns change in guessed objective on next branch + */ + virtual double branch(OsiSolverInterface * solver); + + using OsiBranchingObject::print ; + /** \brief Print something about branch - only if log level high + */ + virtual void print(const OsiSolverInterface * solver=NULL); + +protected: + /// Lower [0] and upper [1] bounds for the down arm (way_ = -1) + double down_[2]; + /// Lower [0] and upper [1] bounds for the up arm (way_ = 1) + double up_[2]; +}; +#endif diff --git a/thirdparty/linux/include/coin1/OsiChooseVariable.hpp b/thirdparty/linux/include/coin1/OsiChooseVariable.hpp new file mode 100644 index 0000000..1613bca --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiChooseVariable.hpp @@ -0,0 +1,534 @@ +// Copyright (C) 2006, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiChooseVariable_H +#define OsiChooseVariable_H + +#include <string> +#include <vector> + +#include "CoinWarmStartBasis.hpp" +#include "OsiBranchingObject.hpp" + +class OsiSolverInterface; +class OsiHotInfo; + +/** This class chooses a variable to branch on + + The base class just chooses the variable and direction without strong branching but it + has information which would normally be used by strong branching e.g. to re-enter + having fixed a variable but using same candidates for strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseVariable (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseVariable (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseVariable (const OsiChooseVariable &); + + /// Assignment operator + OsiChooseVariable & operator= (const OsiChooseVariable& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseVariable (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + /// Returns true if solution looks feasible against given objects + virtual bool feasibleSolution(const OsiBranchingInformation * info, + const double * solution, + int numberObjects, + const OsiObject ** objects); + /// Saves a good solution + void saveSolution(const OsiSolverInterface * solver); + /// Clears out good solution after use + void clearGoodSolution(); + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation( const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif + /// Objective value for feasible solution + inline double goodObjectiveValue() const + { return goodObjectiveValue_;} + /// Estimate of up change or change on chosen if n-way + inline double upChange() const + { return upChange_;} + /// Estimate of down change or max change on other possibilities if n-way + inline double downChange() const + { return downChange_;} + /// Good solution - deleted by finalize + inline const double * goodSolution() const + { return goodSolution_;} + /// Index of chosen object + inline int bestObjectIndex() const + { return bestObjectIndex_;} + /// Set index of chosen object + inline void setBestObjectIndex(int value) + { bestObjectIndex_ = value;} + /// Preferred way of chosen object + inline int bestWhichWay() const + { return bestWhichWay_;} + /// Set preferred way of chosen object + inline void setBestWhichWay(int value) + { bestWhichWay_ = value;} + /// Index of forced object + inline int firstForcedObjectIndex() const + { return firstForcedObjectIndex_;} + /// Set index of forced object + inline void setFirstForcedObjectIndex(int value) + { firstForcedObjectIndex_ = value;} + /// Preferred way of forced object + inline int firstForcedWhichWay() const + { return firstForcedWhichWay_;} + /// Set preferred way of forced object + inline void setFirstForcedWhichWay(int value) + { firstForcedWhichWay_ = value;} + /// Get the number of objects unsatisfied at this node - accurate on first pass + inline int numberUnsatisfied() const + {return numberUnsatisfied_;} + /// Number of objects to choose for strong branching + inline int numberStrong() const + { return numberStrong_;} + /// Set number of objects to choose for strong branching + inline void setNumberStrong(int value) + { numberStrong_ = value;} + /// Number left on strong list + inline int numberOnList() const + { return numberOnList_;} + /// Number of strong branches actually done + inline int numberStrongDone() const + { return numberStrongDone_;} + /// Number of strong iterations actually done + inline int numberStrongIterations() const + { return numberStrongIterations_;} + /// Number of strong branches which changed bounds + inline int numberStrongFixed() const + { return numberStrongFixed_;} + /// List of candidates + inline const int * candidates() const + { return list_;} + /// Trust results from strong branching for changing bounds + inline bool trustStrongForBound() const + { return trustStrongForBound_;} + /// Set trust results from strong branching for changing bounds + inline void setTrustStrongForBound(bool yesNo) + { trustStrongForBound_ = yesNo;} + /// Trust results from strong branching for valid solution + inline bool trustStrongForSolution() const + { return trustStrongForSolution_;} + /// Set trust results from strong branching for valid solution + inline void setTrustStrongForSolution(bool yesNo) + { trustStrongForSolution_ = yesNo;} + /// Set solver and redo arrays + void setSolver (const OsiSolverInterface * solver); + /** Return status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + */ + inline int status() const + { return status_;} + inline void setStatus(int value) + { status_ = value;} + + +protected: + // Data + /// Objective value for feasible solution + double goodObjectiveValue_; + /// Estimate of up change or change on chosen if n-way + double upChange_; + /// Estimate of down change or max change on other possibilities if n-way + double downChange_; + /// Good solution - deleted by finalize + double * goodSolution_; + /// List of candidates + int * list_; + /// Useful array (for sorting etc) + double * useful_; + /// Pointer to solver + const OsiSolverInterface * solver_; + /* Status - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + */ + int status_; + /// Index of chosen object + int bestObjectIndex_; + /// Preferred way of chosen object + int bestWhichWay_; + /// Index of forced object + int firstForcedObjectIndex_; + /// Preferred way of forced object + int firstForcedWhichWay_; + /// The number of objects unsatisfied at this node. + int numberUnsatisfied_; + /// Number of objects to choose for strong branching + int numberStrong_; + /// Number left on strong list + int numberOnList_; + /// Number of strong branches actually done + int numberStrongDone_; + /// Number of strong iterations actually done + int numberStrongIterations_; + /// Number of bound changes due to strong branching + int numberStrongFixed_; + /// List of unsatisfied objects - first numberOnList_ for strong branching + /// Trust results from strong branching for changing bounds + bool trustStrongForBound_; + /// Trust results from strong branching for valid solution + bool trustStrongForSolution_; +}; + +/** This class is the placeholder for the pseudocosts used by OsiChooseStrong. + It can also be used by any other pseudocost based strong branching + algorithm. +*/ + +class OsiPseudoCosts { +protected: + // Data + /// Total of all changes up + double * upTotalChange_; + /// Total of all changes down + double * downTotalChange_; + /// Number of times up + int * upNumber_; + /// Number of times down + int * downNumber_; + /// Number of objects (could be found from solver) + int numberObjects_; + /// Number before we trust + int numberBeforeTrusted_; + +private: + void gutsOfDelete(); + void gutsOfCopy(const OsiPseudoCosts& rhs); + +public: + OsiPseudoCosts(); + virtual ~OsiPseudoCosts(); + OsiPseudoCosts(const OsiPseudoCosts& rhs); + OsiPseudoCosts& operator=(const OsiPseudoCosts& rhs); + + /// Number of times before trusted + inline int numberBeforeTrusted() const + { return numberBeforeTrusted_; } + /// Set number of times before trusted + inline void setNumberBeforeTrusted(int value) + { numberBeforeTrusted_ = value; } + /// Initialize the pseudocosts with n entries + void initialize(int n); + /// Give the number of objects for which pseudo costs are stored + inline int numberObjects() const + { return numberObjects_; } + + /** @name Accessor methods to pseudo costs data */ + //@{ + inline double* upTotalChange() { return upTotalChange_; } + inline const double* upTotalChange() const { return upTotalChange_; } + + inline double* downTotalChange() { return downTotalChange_; } + inline const double* downTotalChange() const { return downTotalChange_; } + + inline int* upNumber() { return upNumber_; } + inline const int* upNumber() const { return upNumber_; } + + inline int* downNumber() { return downNumber_; } + inline const int* downNumber() const { return downNumber_; } + //@} + + /// Given a candidate fill in useful information e.g. estimates + virtual void updateInformation(const OsiBranchingInformation *info, + int branch, OsiHotInfo * hotInfo); +#if 1 + /// Given a branch fill in useful information e.g. estimates + virtual void updateInformation( int whichObject, int branch, + double changeInObjective, double changeInValue, + int status); +#endif +}; + +/** This class chooses a variable to branch on + + This chooses the variable and direction with reliability strong branching. + + The flow is : + a) initialize the process. This decides on strong branching list + and stores indices of all infeasible objects + b) do strong branching on list. If list is empty then just + choose one candidate and return without strong branching. If not empty then + go through list and return best. However we may find that the node is infeasible + or that we can fix a variable. If so we return and it is up to user to call + again (after fixing a variable). +*/ + +class OsiChooseStrong : public OsiChooseVariable { + +public: + + /// Default Constructor + OsiChooseStrong (); + + /// Constructor from solver (so we can set up arrays etc) + OsiChooseStrong (const OsiSolverInterface * solver); + + /// Copy constructor + OsiChooseStrong (const OsiChooseStrong &); + + /// Assignment operator + OsiChooseStrong & operator= (const OsiChooseStrong& rhs); + + /// Clone + virtual OsiChooseVariable * clone() const; + + /// Destructor + virtual ~OsiChooseStrong (); + + /** Sets up strong list and clears all if initialize is true. + Returns number of infeasibilities. + If returns -1 then has worked out node is infeasible! + */ + virtual int setupList ( OsiBranchingInformation *info, bool initialize); + /** Choose a variable + Returns - + -1 Node is infeasible + 0 Normal termination - we have a candidate + 1 All looks satisfied - no candidate + 2 We can change the bound on a variable - but we also have a strong branching candidate + 3 We can change the bound on a variable - but we have a non-strong branching candidate + 4 We can change the bound on a variable - no other candidates + We can pick up branch from bestObjectIndex() and bestWhichWay() + We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay() + If we have a solution then we can pick up from goodObjectiveValue() and goodSolution() + If fixVariables is true then 2,3,4 are all really same as problem changed + */ + virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables); + + /** Pseudo Shadow Price mode + 0 - off + 1 - use if no strong info + 2 - use if strong not trusted + 3 - use even if trusted + */ + inline int shadowPriceMode() const + { return shadowPriceMode_;} + /// Set Shadow price mode + inline void setShadowPriceMode(int value) + { shadowPriceMode_ = value;} + + /** Accessor method to pseudo cost object*/ + const OsiPseudoCosts& pseudoCosts() const + { return pseudoCosts_; } + + /** Accessor method to pseudo cost object*/ + OsiPseudoCosts& pseudoCosts() + { return pseudoCosts_; } + + /** A feww pass-through methods to access members of pseudoCosts_ as if they + were members of OsiChooseStrong object */ + inline int numberBeforeTrusted() const { + return pseudoCosts_.numberBeforeTrusted(); } + inline void setNumberBeforeTrusted(int value) { + pseudoCosts_.setNumberBeforeTrusted(value); } + inline int numberObjects() const { + return pseudoCosts_.numberObjects(); } + +protected: + + /** This is a utility function which does strong branching on + a list of objects and stores the results in OsiHotInfo.objects. + On entry the object sequence is stored in the OsiHotInfo object + and maybe more. + It returns - + -1 - one branch was infeasible both ways + 0 - all inspected - nothing can be fixed + 1 - all inspected - some can be fixed (returnCriterion==0) + 2 - may be returning early - one can be fixed (last one done) (returnCriterion==1) + 3 - returning because max time + + */ + int doStrongBranching( OsiSolverInterface * solver, + OsiBranchingInformation *info, + int numberToDo, int returnCriterion); + + /** Clear out the results array */ + void resetResults(int num); + +protected: + /** Pseudo Shadow Price mode + 0 - off + 1 - use and multiply by strong info + 2 - use + */ + int shadowPriceMode_; + + /** The pseudo costs for the chooser */ + OsiPseudoCosts pseudoCosts_; + + /** The results of the strong branching done on the candidates where the + pseudocosts were not sufficient */ + OsiHotInfo* results_; + /** The number of OsiHotInfo objetcs that contain information */ + int numResults_; +}; + +/** This class contains the result of strong branching on a variable + When created it stores enough information for strong branching +*/ + +class OsiHotInfo { + +public: + + /// Default Constructor + OsiHotInfo (); + + /// Constructor from useful information + OsiHotInfo ( OsiSolverInterface * solver, + const OsiBranchingInformation *info, + const OsiObject * const * objects, + int whichObject); + + /// Copy constructor + OsiHotInfo (const OsiHotInfo &); + + /// Assignment operator + OsiHotInfo & operator= (const OsiHotInfo& rhs); + + /// Clone + virtual OsiHotInfo * clone() const; + + /// Destructor + virtual ~OsiHotInfo (); + + /** Fill in useful information after strong branch. + Return status + */ + int updateInformation( const OsiSolverInterface * solver, const OsiBranchingInformation * info, + OsiChooseVariable * choose); + /// Original objective value + inline double originalObjectiveValue() const + { return originalObjectiveValue_;} + /// Up change - invalid if n-way + inline double upChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[1];} + /// Down change - invalid if n-way + inline double downChange() const + { assert (branchingObject_->numberBranches()==2); return changes_[0];} + /// Set up change - invalid if n-way + inline void setUpChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[1] = value;} + /// Set down change - invalid if n-way + inline void setDownChange(double value) + { assert (branchingObject_->numberBranches()==2); changes_[0] = value;} + /// Change on way k + inline double change(int k) const + { return changes_[k];} + + /// Up iteration count - invalid if n-way + inline int upIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[1];} + /// Down iteration count - invalid if n-way + inline int downIterationCount() const + { assert (branchingObject_->numberBranches()==2); return iterationCounts_[0];} + /// Iteration count on way k + inline int iterationCount(int k) const + { return iterationCounts_[k];} + + /// Up status - invalid if n-way + inline int upStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[1];} + /// Down status - invalid if n-way + inline int downStatus() const + { assert (branchingObject_->numberBranches()==2); return statuses_[0];} + /// Set up status - invalid if n-way + inline void setUpStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[1] = value;} + /// Set down status - invalid if n-way + inline void setDownStatus(int value) + { assert (branchingObject_->numberBranches()==2); statuses_[0] = value;} + /// Status on way k + inline int status(int k) const + { return statuses_[k];} + /// Branching object + inline OsiBranchingObject * branchingObject() const + { return branchingObject_;} + inline int whichObject() const + { return whichObject_;} + +protected: + // Data + /// Original objective value + double originalObjectiveValue_; + /// Objective changes + double * changes_; + /// Iteration counts + int * iterationCounts_; + /** Status + -1 - not done + 0 - feasible and finished + 1 - infeasible + 2 - not finished + */ + int * statuses_; + /// Branching object + OsiBranchingObject * branchingObject_; + /// Which object on list + int whichObject_; +}; + + +#endif diff --git a/thirdparty/linux/include/coin1/OsiClpSolverInterface.hpp b/thirdparty/linux/include/coin1/OsiClpSolverInterface.hpp new file mode 100644 index 0000000..ebc7e64 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiClpSolverInterface.hpp @@ -0,0 +1,1509 @@ +// $Id$ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + + +#ifndef OsiClpSolverInterface_H +#define OsiClpSolverInterface_H + +#include <string> +#include <cfloat> +#include <map> + +#include "ClpSimplex.hpp" +#include "ClpLinearObjective.hpp" +#include "CoinPackedMatrix.hpp" +#include "OsiSolverInterface.hpp" +#include "CoinWarmStartBasis.hpp" +#include "ClpEventHandler.hpp" +#include "ClpNode.hpp" +#include "CoinIndexedVector.hpp" +#include "CoinFinite.hpp" + +class OsiRowCut; +class OsiClpUserSolver; +class OsiClpDisasterHandler; +class CoinSet; +static const double OsiClpInfinity = COIN_DBL_MAX; + +//############################################################################# + +/** Clp Solver Interface + +Instantiation of OsiClpSolverInterface for the Model Algorithm. + +*/ + +class OsiClpSolverInterface : + virtual public OsiSolverInterface { + friend void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + //--------------------------------------------------------------------------- + /**@name Solve methods */ + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an LP relaxation after problem modification + virtual void resolve(); + + /// Resolve an LP relaxation after problem modification (try GUB) + virtual void resolveGub(int needed); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + + /** Solve when primal column and dual row solutions are near-optimal + options - 0 no presolve (use primal and dual) + 1 presolve (just use primal) + 2 no presolve (just use primal) + basis - 0 use all slack basis + 1 try and put some in basis + */ + void crossover(int options,int basis); + //@} + + /*! @name OsiSimplexInterface methods + \brief Methods for the Osi Simplex API. + + The current implementation should work for both minimisation and + maximisation in mode 1 (tableau access). In mode 2 (single pivot), only + minimisation is supported as of 100907. + */ + //@{ + /** \brief Simplex API capability. + + Returns + - 0 if no simplex API + - 1 if can just do getBInv etc + - 2 if has all OsiSimplex methods + */ + virtual int canDoSimplexInterface() const; + + /*! \brief Enables simplex mode 1 (tableau access) + + Tells solver that calls to getBInv etc are about to take place. + Underlying code may need mutable as this may be called from + CglCut::generateCuts which is const. If that is too horrific then + each solver e.g. BCP or CBC will have to do something outside + main loop. + */ + virtual void enableFactorization() const; + + /*! \brief Undo any setting changes made by #enableFactorization */ + virtual void disableFactorization() const; + + /** Returns true if a basis is available + AND problem is optimal. This should be used to see if + the BInvARow type operations are possible and meaningful. + */ + virtual bool basisIsAvailable() const; + + /** The following two methods may be replaced by the + methods of OsiSolverInterface using OsiWarmStartBasis if: + 1. OsiWarmStartBasis resize operation is implemented + more efficiently and + 2. It is ensured that effects on the solver are the same + + Returns a basis status of the structural/artificial variables + At present as warm start i.e 0 free, 1 basic, 2 upper, 3 lower + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + virtual void getBasisStatus(int* cstat, int* rstat) const; + + /** Set the status of structural/artificial variables and + factorize, update solution etc + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + Returns 0 if OK, 1 if problem is bad e.g. duplicate elements, too large ... + */ + virtual int setBasisStatus(const int* cstat, const int* rstat); + + ///Get the reduced gradient for the cost vector c + virtual void getReducedGradient(double* columnReducedCosts, + double * duals, + const double * c) const ; + + ///Get a row of the tableau (slack part in slack if not NULL) + virtual void getBInvARow(int row, double* z, double * slack=NULL) const; + + /** Get a row of the tableau (slack part in slack if not NULL) + If keepScaled is true then scale factors not applied after so + user has to use coding similar to what is in this method + */ + virtual void getBInvARow(int row, CoinIndexedVector * z, CoinIndexedVector * slack=NULL, + bool keepScaled=false) const; + + ///Get a row of the basis inverse + virtual void getBInvRow(int row, double* z) const; + + ///Get a column of the tableau + virtual void getBInvACol(int col, double* vec) const ; + + ///Get a column of the tableau + virtual void getBInvACol(int col, CoinIndexedVector * vec) const ; + + /** Update (i.e. ftran) the vector passed in. + Unscaling is applied after - can't be applied before + */ + + virtual void getBInvACol(CoinIndexedVector * vec) const ; + + ///Get a column of the basis inverse + virtual void getBInvCol(int col, double* vec) const ; + + /** Get basic indices (order of indices corresponds to the + order of elements in a vector retured by getBInvACol() and + getBInvCol()). + */ + virtual void getBasics(int* index) const; + + /*! \brief Enables simplex mode 2 (individual pivot control) + + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. + */ + virtual void enableSimplexInterface(bool doingPrimal); + /// Copy across enabled stuff from one solver to another + void copyEnabledSuff(OsiClpSolverInterface & rhs); + + /*! \brief Undo setting changes made by #enableSimplexInterface */ + virtual void disableSimplexInterface(); + /// Copy across enabled stuff from one solver to another + void copyEnabledStuff(ClpSimplex & rhs); + + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in statOut. Where + 1 is to upper bound, -1 to lower bound + Return code is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus); + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx); + + + //@} + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the clp algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + */ + //@{ + // Set an integer parameter + bool setIntParam(OsiIntParam key, int value); + // Set an double parameter + bool setDblParam(OsiDblParam key, double value); + // Set a string parameter + bool setStrParam(OsiStrParam key, const std::string & value); + // Get an integer parameter + bool getIntParam(OsiIntParam key, int& value) const; + // Get an double parameter + bool getDblParam(OsiDblParam key, double& value) const; + // Get a string parameter + bool getStrParam(OsiStrParam key, std::string& value) const; + // Set a hint parameter - overrides OsiSolverInterface + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * otherInformation=NULL); + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there a numerical difficulties? + virtual bool isAbandoned() const; + /// Is optimality proven? + virtual bool isProvenOptimal() const; + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + //@} + + //--------------------------------------------------------------------------- + /**@name WarmStart related methods */ + //@{ + + /*! \brief Get an empty warm start object + + This routine returns an empty CoinWarmStartBasis object. Its purpose is + to provide a way to give a client a warm start basis object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const; + + /// Get warmstarting information + virtual CoinWarmStart* getWarmStart() const; + /// Get warmstarting information + inline CoinWarmStartBasis* getPointerToWarmStart() + { return &basis_;} + /// Get warmstarting information + inline const CoinWarmStartBasis* getConstPointerToWarmStart() const + { return &basis_;} + /** Set warmstarting information. Return true/false depending on whether + the warmstart information was accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + OsiClp version always returns pointer and false. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /// Set column status in ClpSimplex and warmStart + void setColumnStatus(int iColumn, ClpSimplex::Status status); + + //@} + + //--------------------------------------------------------------------------- + /**@name Hotstart related methods (primarily used in strong branching). + The user can create a hotstart (a snapshot) of the optimization process + then reoptimize over and over again always starting from there.<br> + <strong>NOTE</strong>: between hotstarted optimizations only + bound changes are allowed. */ + //@{ + /// Create a hotstart point of the optimization process + virtual void markHotStart(); + /// Optimize starting from the hotstart + virtual void solveFromHotStart(); + /// Delete the snapshot + virtual void unmarkHotStart(); + /** Start faster dual - returns negative if problems 1 if infeasible, + Options to pass to solver + 1 - create external reduced costs for columns + 2 - create external reduced costs for rows + 4 - create external row activity (columns always done) + Above only done if feasible + When set resolve does less work + */ + int startFastDual(int options); + /// Stop fast dual + void stopFastDual(); + /// Sets integer tolerance and increment + void setStuff(double tolerance,double increment); + /// Return a conflict analysis cut from small model + OsiRowCut * smallModelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + /** Return a conflict analysis cut from model + If type is 0 then genuine cut, if 1 then only partially processed + */ + OsiRowCut * modelCut(const double * originalLower, const double * originalUpper, + int numberRowsAtContinuous,const int * whichGenerator, + int typeCut=0); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem information methods + + These methods call the solver's query routines to return + information about the problem referred to by the current object. + Querying a problem that has no data associated with it result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /**@name Methods related to querying the input data */ + //@{ + /// Get number of columns + virtual int getNumCols() const { + return modelPtr_->numberColumns(); } + + /// Get number of rows + virtual int getNumRows() const { + return modelPtr_->numberRows(); } + + /// Get number of nonzero elements + virtual int getNumElements() const { + int retVal = 0; + const CoinPackedMatrix * matrix =modelPtr_->matrix(); + if ( matrix != NULL ) retVal=matrix->getNumElements(); + return retVal; } + + /// Return name of row if one exists or Rnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const; + + /// Return name of column if one exists or Cnnnnnnn + /// maxLen is currently ignored and only there to match the signature from the base class! + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const; + + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const { return modelPtr_->columnLower(); } + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const { return modelPtr_->columnUpper(); } + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L' <= constraint + <li>'E' = constraint + <li>'G' >= constraint + <li>'R' ranged constraint + <li>'N' free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of rows right-hand sides + <ul> + <li> if rowsense()[i] == 'L' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'G' then rhs()[i] == rowlower()[i] + <li> if rowsense()[i] == 'R' then rhs()[i] == rowupper()[i] + <li> if rowsense()[i] == 'N' then rhs()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const ; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if rowsense()[i] == 'R' then + rowrange()[i] == rowupper()[i] - rowlower()[i] + <li> if rowsense()[i] != 'R' then + rowrange()[i] is undefined + </ul> + */ + virtual const double * getRowRange() const ; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const { return modelPtr_->rowLower(); } + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const { return modelPtr_->rowUpper(); } + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const + { if (fakeMinInSimplex_) + return linearObjective_ ; + else + return modelPtr_->objective(); } + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const + { return ((fakeMinInSimplex_)?-modelPtr_->optimizationDirection(): + modelPtr_->optimizationDirection()); } + + /// Return true if column is continuous + virtual bool isContinuous(int colNumber) const; + /// Return true if variable is binary + virtual bool isBinary(int colIndex) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if variable is binary and not fixed at either bound + virtual bool isFreeBinary(int colIndex) const; + /** Return array of column length + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + virtual const char * getColType(bool refresh=false) const; + + /** Return true if column is integer but does not have to + be declared as such. + Note: This function returns true if the the column + is binary or a general integer. + */ + bool isOptionalInteger(int colIndex) const; + /** Set the index-th variable to be an optional integer variable */ + void setOptionalInteger(int index); + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get pointer to mutable column-wise copy of matrix + virtual CoinPackedMatrix * getMutableMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const { return OsiClpInfinity; } + //@} + + /**@name Methods related to querying the solution */ + //@{ + /// Get pointer to array[getNumCols()] of primal solution vector + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual prices + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /** Get how many iterations it took to solve the problem (whatever + "iteration" mean to the solver. */ + virtual int getIterationCount() const + { return modelPtr_->numberIterations(); } + + /** Get as many dual rays as the solver can provide. (In case of proven + primal infeasibility there should be at least one.) + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const; + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const; + + //@} + //@} + + //--------------------------------------------------------------------------- + + /**@name Problem modifying methods */ + //@{ + //------------------------------------------------------------------------- + /**@name Changing bounds on variables and constraints */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + /** Set a single column lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + /** Set a single column upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single column lower and upper bound */ + virtual void setColBounds( int elementIndex, + double lower, double upper ); + + /** Set the bounds on a number of columns simultaneously<br> + The default implementation just invokes setColLower() and + setColUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the variables whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the variables + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound<br> + Use -DBL_MAX for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound<br> + Use DBL_MAX for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) ; + + /** Set a single row lower and upper bound */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) ; + + /** Set the type of a single row<br> */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /** Set the bounds on a number of rows simultaneously<br> + The default implementation just invokes setRowLower() and + setRowUpper() over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>either</em> bound changes + @param boundList the new lower/upper bound pairs for the constraints + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set the type of a number of rows simultaneously<br> + The default implementation just invokes setRowType() + over and over again. + @param indexFirst,indexLast pointers to the beginning and after the + end of the array of the indices of the constraints whose + <em>any</em> characteristics changes + @param senseList the new senses + @param rhsList the new right hand sides + @param rangeList the new ranges + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + /** Set the objective coefficients for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the lower bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set the upper bounds for all columns + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + +// using OsiSolverInterface::setRowName ; + /// Set name of row +// virtual void setRowName(int rowIndex, std::string & name) ; + virtual void setRowName(int rowIndex, std::string name) ; + +// using OsiSolverInterface::setColName ; + /// Set name of column +// virtual void setColName(int colIndex, std::string & name) ; + virtual void setColName(int colIndex, std::string name) ; + + //@} + + //------------------------------------------------------------------------- + /**@name Integrality related changing methods */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + /// Number of SOS sets + inline int numberSOS() const + { return numberSOS_;} + /// SOS set info + inline const CoinSet * setInfo() const + { return setInfo_;} + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + //@} + + //------------------------------------------------------------------------- + /// Set objective function sense (1 for min (default), -1 for max,) + virtual void setObjSense(double s ) + { modelPtr_->setOptimizationDirection( s < 0 ? -1 : 1); } + + /** Set the primal solution column values + + colsol[numcols()] is an array of values of the problem column + variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of colsol() until changed by another call to + setColsol() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setColSolution(const double * colsol); + + /** Set dual solution vector + + rowprice[numrows()] is an array of values of the problem row + dual variables. These values are copied to memory owned by the + solver object or the solver. They will be returned as the + result of rowprice() until changed by another call to + setRowprice() or by a call to any solver routine. Whether the + solver makes use of the solution in any way is + solver-dependent. + */ + virtual void setRowPrice(const double * rowprice); + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem.<br> + Note that if a column is added then by default it will correspond to a + continuous variable. */ + //@{ + + //using OsiSolverInterface::addCol ; + /** */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, const int * rows, const double * elements, + const double collb, const double colub, + const double obj) ; + /*! \brief Add a named column (primal variable) to the problem. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + /** */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void addCols(const int numcols, + const int * columnStarts, const int * rows, const double * elements, + const double* collb, const double* colub, + const double* obj); + /** */ + virtual void deleteCols(const int num, const int * colIndices); + + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + /** Add a row (constraint) to the problem. */ + virtual void addRow(int numberElements, const int * columns, const double * element, + const double rowlb, const double rowub) ; + /*! \brief Add a named row (constraint) to the problem. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** */ + virtual void addRows(const int numrows, + const int * rowStarts, const int * columns, const double * element, + const double* rowlb, const double* rowub); + /// + void modifyCoefficient(int row, int column, double newElement, + bool keepZero=false) + {modelPtr_->modifyCoefficient(row,column,newElement, keepZero);} + + /** */ + virtual void deleteRows(const int num, const int * rowIndices); + /** If solver wants it can save a copy of "base" (continuous) model here + */ + virtual void saveBaseModel() ; + /** Strip off rows to get to this number of rows. + If solver wants it can restore a copy of "base" (continuous) model here + */ + virtual void restoreBaseModel(int numberRows); + + //----------------------------------------------------------------------- + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + This uses array of pointers + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + /** Apply a collection of cuts. + + Only cuts which have an <code>effectiveness >= effectivenessLb</code> + are applied. + <ul> + <li> ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + <code>effectiveness < effectivenessLb</code> + <li> ReturnCode.getNuminconsistent() -- number of invalid cuts + <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model + <li> ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible + <li> ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model + <li> cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() + </ul> + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + //@} + //@} + + //--------------------------------------------------------------------------- + +public: + + /**@name Methods to input a problem */ + //@{ + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is NULL then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. <br> + <strong>WARNING</strong>: The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given as a ClpMatrixBase. */ + virtual void loadProblem(const ClpMatrixBase& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) ; + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + /// This loads a model from a coinModel object - returns number of errors + virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false); + + using OsiSolverInterface::readMps ; + /** Read an mps file from the given filename (defaults to Osi reader) - returns + number of errors (see OsiMpsReader class) */ + virtual int readMps(const char *filename, + const char *extension = "mps") ; + /** Read an mps file from the given filename returns + number of errors (see OsiMpsReader class) */ + int readMps(const char *filename,bool keepNames,bool allowErrors); + /// Read an mps file + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /** Write the problem into an mps file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + /** Write the problem into an mps file of the given filename, + names may be null. formatType is + 0 - normal + 1 - extra accuracy + 2 - IEEE hex (later) + + Returns non-zero on I/O error + */ + virtual int writeMpsNative(const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0) const ; + /// Read file in LP format (with names) + virtual int readLp(const char *filename, const double epsilon = 1e-5); + /** Write the problem into an Lp file of the given filename. + If objSense is non zero then -1.0 forces the code to write a + maximization objective and +1.0 to write a minimization one. + If 0.0 then solver can do what it wants. + This version calls writeLpNative with names */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + /** + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would not matter + e.g. strengthening a matrix for MIP + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix); + /// And if it does matter (not used at present) + virtual void replaceMatrix(const CoinPackedMatrix & matrix) ; + //@} + + /**@name Message handling (extra for Clp messages). + Normally I presume you would want the same language. + If not then you could use underlying model pointer */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Set log level (will also set underlying solver's log level) + void setLogLevel(int value); + /// Create C++ lines to get to current state + void generateCpp( FILE * fp); + //@} + //--------------------------------------------------------------------------- + + /**@name Clp specific public interfaces */ + //@{ + /// Get pointer to Clp model + ClpSimplex * getModelPtr() const ; + /// Set pointer to Clp model and return old + inline ClpSimplex * swapModelPtr(ClpSimplex * newModel) + { ClpSimplex * model = modelPtr_; modelPtr_=newModel;return model;} + /// Get special options + inline unsigned int specialOptions() const + { return specialOptions_;} + void setSpecialOptions(unsigned int value); + /// Last algorithm used , 1 = primal, 2 = dual other unknown + inline int lastAlgorithm() const + { return lastAlgorithm_;} + /// Set last algorithm used , 1 = primal, 2 = dual other unknown + inline void setLastAlgorithm(int value) + { lastAlgorithm_ = value;} + /// Get scaling action option + inline int cleanupScaling() const + { return cleanupScaling_;} + /** Set Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + inline void setCleanupScaling(int value) + { cleanupScaling_=value;} + /** Get smallest allowed element in cut. + If smaller than this then ignored */ + inline double smallestElementInCut() const + { return smallestElementInCut_;} + /** Set smallest allowed element in cut. + If smaller than this then ignored */ + inline void setSmallestElementInCut(double value) + { smallestElementInCut_=value;} + /** Get smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline double smallestChangeInCut() const + { return smallestChangeInCut_;} + /** Set smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. + (upper-lower) is taken to be at least 1.0 and + this is assumed >= smallestElementInCut_ + */ + inline void setSmallestChangeInCut(double value) + { smallestChangeInCut_=value;} + /// Pass in initial solve options + inline void setSolveOptions(const ClpSolve & options) + { solveOptions_ = options;} + /** Tighten bounds - lightweight or very lightweight + 0 - normal, 1 lightweight but just integers, 2 lightweight and all + */ + virtual int tightenBounds(int lightweight=0); + /// See if any integer variables make infeasible other way + int infeasibleOtherWay(char * whichWay); + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; + /// Get disaster handler + const OsiClpDisasterHandler * disasterHandler() const + { return disasterHandler_;} + /// Pass in disaster handler + void passInDisasterHandler(OsiClpDisasterHandler * handler); + /// Get fake objective + ClpLinearObjective * fakeObjective() const + { return fakeObjective_;} + /// Set fake objective (and take ownership) + void setFakeObjective(ClpLinearObjective * fakeObjective); + /// Set fake objective + void setFakeObjective(double * fakeObjective); + /*! \brief Set up solver for repeated use by Osi interface. + + The normal usage does things like keeping factorization around so can be + used. Will also do things like keep scaling and row copy of matrix if + matrix does not change. + + \p senseOfAdventure: + - 0 - safe stuff as above + - 1 - will take more risks - if it does not work then bug which will be + fixed + - 2 - don't bother doing most extreme termination checks e.g. don't bother + re-factorizing if less than 20 iterations. + - 3 - Actually safer than 1 (mainly just keeps factorization) + + \p printOut + - -1 always skip round common messages instead of doing some work + - 0 skip if normal defaults + - 1 leaves + */ + void setupForRepeatedUse(int senseOfAdventure=0, int printOut=0); + /// Synchronize model (really if no cuts in tree) + virtual void synchronizeModel(); + /*! \brief Set special options in underlying clp solver. + + Safe as const because #modelPtr_ is mutable. + */ + void setSpecialOptionsMutable(unsigned int value) const; + + //@} + + //--------------------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiClpSolverInterface (); + + /// Clone + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiClpSolverInterface (const OsiClpSolverInterface &); + + /// Borrow constructor - only delete one copy + OsiClpSolverInterface (ClpSimplex * rhs, bool reallyOwn=false); + + /// Releases so won't error + void releaseClp(); + + /// Assignment operator + OsiClpSolverInterface & operator=(const OsiClpSolverInterface& rhs); + + /// Destructor + virtual ~OsiClpSolverInterface (); + + /// Resets as if default constructor + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to constraint matrix). */ + virtual void applyRowCut(const OsiRowCut& rc); + + /** Apply a column cut (adjust one or more bounds). */ + virtual void applyColCut(const OsiColCut& cc); + //@} + + //--------------------------------------------------------------------------- + +protected: + /**@name Protected methods */ + //@{ + /// The real work of a copy constructor (used by copy and assignment) + void gutsOfDestructor(); + + /// Deletes all mutable stuff + void freeCachedResults() const; + + /// Deletes all mutable stuff for row ranges etc + void freeCachedResults0() const; + + /// Deletes all mutable stuff for matrix etc + void freeCachedResults1() const; + + /// A method that fills up the rowsense_, rhs_ and rowrange_ arrays + void extractSenseRhsRange() const; + + /// + void fillParamMaps(); + /** Warm start + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + CoinWarmStartBasis getBasis(ClpSimplex * model) const; + /** Sets up working basis as a copy of input + + NOTE artificials are treated as +1 elements so for <= rhs + artificial will be at lower bound if constraint is tight + + This means that Clpsimplex flips artificials as it works + in terms of row activities + */ + void setBasis( const CoinWarmStartBasis & basis, ClpSimplex * model); + /// Crunch down problem a bit + void crunch(); + /// Extend scale factors + void redoScaleFactors(int numberRows,const CoinBigIndex * starts, + const int * indices, const double * elements); +public: + /** Sets up working basis as a copy of input and puts in as basis + */ + void setBasis( const CoinWarmStartBasis & basis); + /// Just puts current basis_ into ClpSimplex model + inline void setBasis( ) + { setBasis(basis_,modelPtr_);} + /// Warm start difference from basis_ to statusArray + CoinWarmStartDiff * getBasisDiff(const unsigned char * statusArray) const ; + /// Warm start from statusArray + CoinWarmStartBasis * getBasis(const unsigned char * statusArray) const ; + /// Delete all scale factor stuff and reset option + void deleteScaleFactors(); + /// If doing fast hot start then ranges are computed + inline const double * upRange() const + { return rowActivity_;} + inline const double * downRange() const + { return columnActivity_;} + /// Pass in range array + inline void passInRanges(int * array) + { whichRange_=array;} + /// Pass in sos stuff from AMPl + void setSOSData(int numberSOS,const char * type, + const int * start,const int * indices, const double * weights=NULL); + /// Compute largest amount any at continuous away from bound + void computeLargestAway(); + /// Get largest amount continuous away from bound + inline double largestAway() const + { return largestAway_;} + /// Set largest amount continuous away from bound + inline void setLargestAway(double value) + { largestAway_ = value;} + /// Sort of lexicographic resolve + void lexSolve(); + //@} + +protected: + /**@name Protected member data */ + //@{ + /// Clp model represented by this class instance + mutable ClpSimplex * modelPtr_; + //@} + /**@name Cached information derived from the OSL model */ + //@{ + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack upper bounds for range + constraints (undefined for non-range rows) + */ + mutable double *rowrange_; + + /** A pointer to the warmstart information to be used in the hotstarts. + This is NOT efficient and more thought should be given to it... */ + mutable CoinWarmStartBasis* ws_; + /** also save row and column information for hot starts + only used in hotstarts so can be casual */ + mutable double * rowActivity_; + mutable double * columnActivity_; + /// Stuff for fast dual + ClpNodeStuff stuff_; + /// Number of SOS sets + int numberSOS_; + /// SOS set info + CoinSet * setInfo_; + /// Alternate model (hot starts) - but also could be permanent and used for crunch + ClpSimplex * smallModel_; + /// factorization for hot starts + ClpFactorization * factorization_; + /** Smallest allowed element in cut. + If smaller than this then ignored */ + double smallestElementInCut_; + /** Smallest change in cut. + If (upper-lower)*element < this then element is + taken out and cut relaxed. */ + double smallestChangeInCut_; + /// Largest amount continuous away from bound + double largestAway_; + /// Arrays for hot starts + char * spareArrays_; + /** Warmstart information to be used in resolves. */ + CoinWarmStartBasis basis_; + /** The original iteration limit before hotstarts started. */ + int itlimOrig_; + + /*! \brief Last algorithm used + + Coded as + - 0 invalid + - 1 primal + - 2 dual + - -911 disaster in the algorithm that was attempted + - 999 current solution no longer optimal due to change in problem or + basis + */ + mutable int lastAlgorithm_; + + /// To say if destructor should delete underlying model + bool notOwned_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to row-wise copy of continuous problem matrix coefficients. + CoinPackedMatrix *matrixByRowAtContinuous_; + + /// Pointer to integer information + char * integerInformation_; + + /** Pointer to variables for which we want range information + The number is in [0] + memory is not owned by OsiClp + */ + int * whichRange_; + + //std::map<OsiIntParam, ClpIntParam> intParamMap_; + //std::map<OsiDblParam, ClpDblParam> dblParamMap_; + //std::map<OsiStrParam, ClpStrParam> strParamMap_; + + /*! \brief Faking min to get proper dual solution signs in simplex API */ + mutable bool fakeMinInSimplex_ ; + /*! \brief Linear objective + + Normally a pointer to the linear coefficient array in the clp objective. + An independent copy when #fakeMinInSimplex_ is true, because we need + something permanent to point to when #getObjCoefficients is called. + */ + mutable double *linearObjective_; + + /// To save data in OsiSimplex stuff + mutable ClpDataSave saveData_; + /// Options for initialSolve + ClpSolve solveOptions_; + /** Scaling option + When scaling is on it is possible that the scaled problem + is feasible but the unscaled is not. Clp returns a secondary + status code to that effect. This option allows for a cleanup. + If you use it I would suggest 1. + This only affects actions when scaled optimal + 0 - no action + 1 - clean up using dual if primal infeasibility + 2 - clean up using dual if dual infeasibility + 3 - clean up using dual if primal or dual infeasibility + 11,12,13 - as 1,2,3 but use primal + */ + int cleanupScaling_; + /** Special options + 0x80000000 off + 0 simple stuff for branch and bound + 1 try and keep work regions as much as possible + 2 do not use any perturbation + 4 allow exit before re-factorization + 8 try and re-use factorization if no cuts + 16 use standard strong branching rather than clp's + 32 Just go to first factorization in fast dual + 64 try and tighten bounds in crunch + 128 Model will only change in column bounds + 256 Clean up model before hot start + 512 Give user direct access to Clp regions in getBInvARow etc (i.e., + do not unscale, and do not return result in getBInv parameters; + you have to know where to look for the answer) + 1024 Don't "borrow" model in initialSolve + 2048 Don't crunch + 4096 quick check for optimality + Bits above 8192 give where called from in Cbc + At present 0 is normal, 1 doing fast hotstarts, 2 is can do quick check + 65536 Keep simple i.e. no crunch etc + 131072 Try and keep scaling factors around + 262144 Don't try and tighten bounds (funny global cuts) + 524288 Fake objective and 0-1 + 1048576 Don't recompute ray after crunch + 2097152 + */ + mutable unsigned int specialOptions_; + /// Copy of model when option 131072 set + ClpSimplex * baseModel_; + /// Number of rows when last "scaled" + int lastNumberRows_; + /// Continuous model + ClpSimplex * continuousModel_; + /// Possible disaster handler + OsiClpDisasterHandler * disasterHandler_ ; + /// Fake objective + ClpLinearObjective * fakeObjective_; + /// Row scale factors (has inverse at end) + CoinDoubleArrayWithLength rowScale_; + /// Column scale factors (has inverse at end) + CoinDoubleArrayWithLength columnScale_; + //@} +}; + +class OsiClpDisasterHandler : public ClpDisasterHandler { +public: + /**@name Virtual methods that the derived classe should provide. + */ + //@{ + /// Into simplex + virtual void intoSimplex(); + /// Checks if disaster + virtual bool check() const ; + /// saves information for next attempt + virtual void saveInfo(); + /// Type of disaster 0 can fix, 1 abort + virtual int typeOfDisaster(); + //@} + + + /**@name Constructors, destructor */ + + //@{ + /** Default constructor. */ + OsiClpDisasterHandler(OsiClpSolverInterface * model = NULL); + /** Destructor */ + virtual ~OsiClpDisasterHandler(); + // Copy + OsiClpDisasterHandler(const OsiClpDisasterHandler&); + // Assignment + OsiClpDisasterHandler& operator=(const OsiClpDisasterHandler&); + /// Clone + virtual ClpDisasterHandler * clone() const; + + //@} + + /**@name Sets/gets */ + + //@{ + /** set model. */ + void setOsiModel(OsiClpSolverInterface * model); + /// Get model + inline OsiClpSolverInterface * osiModel() const + { return osiModel_;} + /// Set where from + inline void setWhereFrom(int value) + { whereFrom_=value;} + /// Get where from + inline int whereFrom() const + { return whereFrom_;} + /// Set phase + inline void setPhase(int value) + { phase_=value;} + /// Get phase + inline int phase() const + { return phase_;} + /// are we in trouble + bool inTrouble() const; + + //@} + + +protected: + /**@name Data members + The data members are protected to allow access for derived classes. */ + //@{ + /// Pointer to model + OsiClpSolverInterface * osiModel_; + /** Where from + 0 dual (resolve) + 1 crunch + 2 primal (resolve) + 4 dual (initialSolve) + 6 primal (initialSolve) + */ + int whereFrom_; + /** phase + 0 initial + 1 trying continuing with back in and maybe different perturb + 2 trying continuing with back in and different scaling + 3 trying dual from all slack + 4 trying primal from previous stored basis + */ + int phase_; + /// Are we in trouble + bool inTrouble_; + //@} +}; +// So unit test can find out if NDEBUG set +bool OsiClpHasNDEBUG(); +//############################################################################# +/** A function that tests the methods in the OsiClpSolverInterface class. */ +void OsiClpSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); +#endif diff --git a/thirdparty/linux/include/coin1/OsiColCut.hpp b/thirdparty/linux/include/coin1/OsiColCut.hpp new file mode 100644 index 0000000..c98eb5c --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiColCut.hpp @@ -0,0 +1,324 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiColCut_H +#define OsiColCut_H + +#include <string> + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +/** Column Cut Class + +Column Cut Class has: + <ul> + <li>a sparse vector of column lower bounds + <li>a sparse vector of column upper bounds + </ul> +*/ +class OsiColCut : public OsiCut { + friend void OsiColCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + //---------------------------------------------------------------- + + /**@name Setting column bounds */ + //@{ + /// Set column lower bounds + inline void setLbs( + int nElements, + const int * colIndices, + const double * lbElements ); + + /// Set column lower bounds from a packed vector + inline void setLbs( const CoinPackedVector & lbs ); + + /// Set column upper bounds + inline void setUbs( + int nElements, + const int * colIndices, + const double * ubElements ); + + /// Set column upper bounds from a packed vector + inline void setUbs( const CoinPackedVector & ubs ); + //@} + + //---------------------------------------------------------------- + + /**@name Getting column bounds */ + //@{ + /// Get column lower bounds + inline const CoinPackedVector & lbs() const; + /// Get column upper bounds + inline const CoinPackedVector & ubs() const; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bounds, upper bounds, + and OsiCut are equal. + */ + inline virtual bool operator==(const OsiColCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + inline virtual bool operator!=(const OsiColCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself. + This checks to ensure that: + <ul> + <li>The bound vectors do not have duplicate indices, + <li>The bound vectors indices are >=0 + </ul> + */ + inline virtual bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. This checks to ensure that + the lower & upperbound packed vectors: + <ul> + <li>do not have an index >= the number of column is the model. + </ul> + */ + inline virtual bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the cut is infeasible with respect to its bounds and the + column bounds in the solver interface's models. + This checks whether: + <ul> + <li>the maximum of the new and existing lower bounds is strictly + greater than the minimum of the new and existing upper bounds. +</ul> + */ + inline virtual bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + //---------------------------------------------------------------- + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiColCut & operator=( const OsiColCut& rhs); + + /// Copy constructor + OsiColCut ( const OsiColCut &); + + /// Default Constructor + OsiColCut (); + + /// Clone + virtual OsiColCut * clone() const; + + /// Destructor + virtual ~OsiColCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const; + //@} + +private: + + /**@name Private member data */ + //@{ + /// Lower bounds + CoinPackedVector lbs_; + /// Upper bounds + CoinPackedVector ubs_; + //@} + +}; + + + +//------------------------------------------------------------------- +// Set lower & upper bound vectors +//------------------------------------------------------------------- +void OsiColCut::setLbs( + int size, + const int * colIndices, + const double * lbElements ) +{ + lbs_.setVector(size,colIndices,lbElements); +} +// +void OsiColCut::setUbs( + int size, + const int * colIndices, + const double * ubElements ) +{ + ubs_.setVector(size,colIndices,ubElements); +} +// +void OsiColCut::setLbs( const CoinPackedVector & lbs ) +{ + lbs_ = lbs; +} +// +void OsiColCut::setUbs( const CoinPackedVector & ubs ) +{ + ubs_ = ubs; +} + +//------------------------------------------------------------------- +// Get Column Lower Bounds and Column Upper Bounds +//------------------------------------------------------------------- +const CoinPackedVector & OsiColCut::lbs() const +{ + return lbs_; +} +// +const CoinPackedVector & OsiColCut::ubs() const +{ + return ubs_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiColCut::operator==( + const OsiColCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) + return false; + if ( lbs() != rhs.lbs() ) + return false; + if ( ubs() != rhs.ubs() ) + return false; + return true; +} +// +bool +OsiColCut::operator!=( + const OsiColCut& rhs) const +{ + return !( (*this)==rhs ); +} + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiColCut::consistent() const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + // Test for consistent cut. + // Are packed vectors consistent? + lb.duplicateIndex("consistent", "OsiColCut"); + ub.duplicateIndex("consistent", "OsiColCut"); + if ( lb.getMinIndex() < 0 ) return false; + if ( ub.getMinIndex() < 0 ) return false; + return true; +} +// +bool OsiColCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & lb = lbs(); + const CoinPackedVector & ub = ubs(); + + // Test for consistent cut. + if ( lb.getMaxIndex() >= im.getNumCols() ) return false; + if ( ub.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} + +#if 0 +bool OsiColCut::feasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i<cutLbs.size(); i++ ) { + int colIndx = cutLbs.indices()[i]; + double newLb; + if ( cutLbs.elements()[i] > oldColLb[colIndx] ) + newLb = cutLbs.elements()[i]; + else + newLb = oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.indexExists(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return false; + } + + for ( i=0; i<cutUbs.size(); i++ ) { + int colIndx = cutUbs.indices()[i]; + double newUb = cutUbs.elements()[i] < oldColUb[colIndx] ? cutUbs.elements()[i] : oldColUb[colIndx]; + double newLb = oldColLb[colIndx]; + if ( cutLbs.indexExists(colIndx) ) + if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return false; + } + + return true; +} +#endif + + +bool OsiColCut::infeasible(const OsiSolverInterface &im) const +{ + const double * oldColLb = im.getColLower(); + const double * oldColUb = im.getColUpper(); + const CoinPackedVector & cutLbs = lbs(); + const CoinPackedVector & cutUbs = ubs(); + int i; + + for ( i=0; i<cutLbs.getNumElements(); i++ ) { + int colIndx = cutLbs.getIndices()[i]; + double newLb= cutLbs.getElements()[i] > oldColLb[colIndx] ? + cutLbs.getElements()[i] : oldColLb[colIndx]; + + double newUb = oldColUb[colIndx]; + if ( cutUbs.isExistingIndex(colIndx) ) + if ( cutUbs[colIndx] < newUb ) newUb = cutUbs[colIndx]; + if ( newLb > newUb ) + return true; + } + + for ( i=0; i<cutUbs.getNumElements(); i++ ) { + int colIndx = cutUbs.getIndices()[i]; + double newUb = cutUbs.getElements()[i] < oldColUb[colIndx] ? + cutUbs.getElements()[i] : oldColUb[colIndx]; + double newLb = oldColLb[colIndx]; + if ( cutLbs.isExistingIndex(colIndx) ) + if ( cutLbs[colIndx] > newLb ) newLb = cutLbs[colIndx]; + if ( newUb < newLb ) + return true; + } + + return false; +} + +#endif diff --git a/thirdparty/linux/include/coin1/OsiCollections.hpp b/thirdparty/linux/include/coin1/OsiCollections.hpp new file mode 100644 index 0000000..d68df1a --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiCollections.hpp @@ -0,0 +1,35 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCollections_H +#define OsiCollections_H + +#include <vector> + +//Forward declarations +class OsiColCut; +class OsiRowCut; +class OsiCut; + + + +/* Collection Classes */ + +/**@name Typedefs for Standard Template Library collections of Osi Objects. */ +//@{ +/// Vector of int +typedef std::vector<int> OsiVectorInt; +/// Vector of double +typedef std::vector<double> OsiVectorDouble; +/// Vector of OsiColCut pointers +typedef std::vector<OsiColCut *> OsiVectorColCutPtr; +/// Vector of OsiRowCut pointers +typedef std::vector<OsiRowCut *> OsiVectorRowCutPtr; +/// Vector of OsiCut pointers +typedef std::vector<OsiCut *> OsiVectorCutPtr; +//@} + + + +#endif diff --git a/thirdparty/linux/include/coin1/OsiConfig.h b/thirdparty/linux/include/coin1/OsiConfig.h new file mode 100644 index 0000000..2e42bb9 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiConfig.h @@ -0,0 +1,19 @@ +/* src/Osi/config_osi.h. Generated by configure. */ +/* src/Osi/config_osi.h.in. */ + +#ifndef __CONFIG_OSI_H__ +#define __CONFIG_OSI_H__ + +/* Version number of project */ +#define OSI_VERSION "0.107.4" + +/* Major Version number of project */ +#define OSI_VERSION_MAJOR 0 + +/* Minor Version number of project */ +#define OSI_VERSION_MINOR 107 + +/* Release Version number of project */ +#define OSI_VERSION_RELEASE 4 + +#endif diff --git a/thirdparty/linux/include/coin1/OsiCut.hpp b/thirdparty/linux/include/coin1/OsiCut.hpp new file mode 100644 index 0000000..0b2cc5c --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiCut.hpp @@ -0,0 +1,245 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCut_H +#define OsiCut_H + +#include "OsiCollections.hpp" +#include "OsiSolverInterface.hpp" + +/** Base Class for cut. + +The Base cut class contains: + <ul> + <li>a measure of the cut's effectivness + </ul> +*/ + +/* + COIN_NOTEST_DUPLICATE is rooted in CoinUtils. Check there before you + meddle here. +*/ +#ifdef COIN_FAST_CODE +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_NOTEST_DUPLICATE +#endif +#endif + +#ifndef COIN_NOTEST_DUPLICATE +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE true +#else +#define COIN_DEFAULT_VALUE_FOR_DUPLICATE false +#endif + + +class OsiCut { + +public: + + //------------------------------------------------------------------- + /**@name Effectiveness */ + //@{ + /// Set effectiveness + inline void setEffectiveness( double e ); + /// Get effectiveness + inline double effectiveness() const; + //@} + + /**@name GloballyValid */ + //@{ + /// Set globallyValid (nonzero true) + inline void setGloballyValid( bool trueFalse ) + { globallyValid_=trueFalse ? 1 : 0;} + inline void setGloballyValid( ) + { globallyValid_=1;} + inline void setNotGloballyValid( ) + { globallyValid_=0;} + /// Get globallyValid + inline bool globallyValid() const + { return globallyValid_!=0;} + /// Set globallyValid as integer (nonzero true) + inline void setGloballyValidAsInteger( int trueFalse ) + { globallyValid_=trueFalse;} + /// Get globallyValid + inline int globallyValidAsInteger() const + { return globallyValid_;} + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const {} + //@} + +#if 0 + / **@name Times used */ + / /@{ + / // Set times used + inline void setTimesUsed( int t ); + / // Increment times used + inline void incrementTimesUsed(); + / // Get times used + inline int timesUsed() const; + / /@} + + / **@name Times tested */ + / /@{ + / // Set times tested + inline void setTimesTested( int t ); + / // Increment times tested + inline void incrementTimesTested(); + / // Get times tested + inline int timesTested() const; + / /@} +#endif + + //---------------------------------------------------------------- + + /**@name Comparison operators */ + //@{ + ///equal. 2 cuts are equal if there effectiveness are equal + inline virtual bool operator==(const OsiCut& rhs) const; + /// not equal + inline virtual bool operator!=(const OsiCut& rhs) const; + /// less than. True if this.effectiveness < rhs.effectiveness + inline virtual bool operator< (const OsiCut& rhs) const; + /// less than. True if this.effectiveness > rhs.effectiveness + inline virtual bool operator> (const OsiCut& rhs) const; + //@} + + //---------------------------------------------------------------- + // consistent() - returns true if the cut is consistent with repect to itself. + // This might include checks to ensure that a packed vector + // itself does not have a negative index. + // consistent(const OsiSolverInterface& si) - returns true if cut is consistent with + // respect to the solver interface's model. This might include a check to + // make sure a column index is not greater than the number + // of columns in the problem. + // infeasible(const OsiSolverInterface& si) - returns true if the cut is infeasible + // "with respect to itself". This might include a check to ensure + // the lower bound is greater than the upper bound, or if the + // cut simply replaces bounds that the new bounds are feasible with + // respect to the old bounds. + //----------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent with respect to itself, + without considering any + data in the model. For example, it might check to ensure + that a column index is not negative. + */ + inline virtual bool consistent() const=0; + + /** Returns true if cut is consistent when considering the solver + interface's model. For example, it might check to ensure + that a column index is not greater than the number of columns + in the model. Assumes consistent() is true. + */ + inline virtual bool consistent(const OsiSolverInterface& si) const=0; + + /** Returns true if the cut is infeasible "with respect to itself" and + cannot be satisfied. This method does NOT check whether adding the + cut to the solver interface's model will make the -model- infeasble. + A cut which returns !infeasible(si) may very well make the model + infeasible. (Of course, adding a cut with returns infeasible(si) + will make the model infeasible.) + + The "with respect to itself" is in quotes becaues + in the case where the cut + simply replaces existing bounds, it may make + sense to test infeasibility with respect to the current bounds + held in the solver interface's model. For example, if the cut + has a single variable in it, it might check that the maximum + of new and existing lower bounds is greater than the minium of + the new and existing upper bounds. + + Assumes that consistent(si) is true.<br> + Infeasible cuts can be a useful mechanism for a cut generator to + inform the solver interface that its detected infeasibility of the + problem. + */ + inline virtual bool infeasible(const OsiSolverInterface &si) const=0; + + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const=0; + //@} + +protected: + + /**@name Constructors and destructors */ + //@{ + /// Default Constructor + OsiCut (); + + /// Copy constructor + OsiCut ( const OsiCut &); + + /// Assignment operator + OsiCut & operator=( const OsiCut& rhs); + + /// Destructor + virtual ~OsiCut (); + //@} + +private: + + /**@name Private member data */ + //@{ + /// Effectiveness + double effectiveness_; + /// If cut has global validity i.e. can be used anywhere in tree + int globallyValid_; +#if 0 + /// Times used + int timesUsed_; + /// Times tested + int timesTested_; +#endif + //@} +}; + + +//------------------------------------------------------------------- +// Set/Get member data +//------------------------------------------------------------------- +void OsiCut::setEffectiveness(double e) { effectiveness_=e; } +double OsiCut::effectiveness() const { return effectiveness_; } + +#if 0 +void OsiCut::setTimesUsed( int t ) { timesUsed_=t; } +void OsiCut::incrementTimesUsed() { timesUsed_++; } +int OsiCut::timesUsed() const { return timesUsed_; } + +void OsiCut::setTimesTested( int t ) { timesTested_=t; } +void OsiCut::incrementTimesTested() { timesTested_++; } +int OsiCut::timesTested() const{ return timesTested_; } +#endif + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiCut::operator==(const OsiCut& rhs) const +{ + return effectiveness()==rhs.effectiveness(); +} +bool +OsiCut::operator!=(const OsiCut& rhs) const +{ + return !( (*this)==rhs ); +} +bool +OsiCut::operator< (const OsiCut& rhs) const +{ + return effectiveness()<rhs.effectiveness(); +} +bool +OsiCut::operator> (const OsiCut& rhs) const +{ + return effectiveness()>rhs.effectiveness(); +} +#endif diff --git a/thirdparty/linux/include/coin1/OsiCuts.hpp b/thirdparty/linux/include/coin1/OsiCuts.hpp new file mode 100644 index 0000000..d454402 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiCuts.hpp @@ -0,0 +1,474 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiCuts_H +#define OsiCuts_H + +#include "CoinPragma.hpp" + +#include <cmath> +#include <cfloat> +#include "OsiCollections.hpp" +#include "OsiRowCut.hpp" +#include "OsiColCut.hpp" +#include "CoinFloatEqual.hpp" + +/** Collections of row cuts and column cuts +*/ +class OsiCuts { + friend void OsiCutsUnitTest(); + +public: + /**@name Iterator classes + */ + //@{ + /** Iterator + + This is a class for iterating over the collection of cuts. + */ + class iterator { + friend class OsiCuts; + public: + iterator(OsiCuts& cuts); + iterator(const iterator & src); + iterator & operator=( const iterator& rhs); + ~iterator (); + OsiCut* operator*() const { return cutP_; } + iterator operator++(); + + iterator operator++(int) + { + iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const iterator& it) const { + return !((*this)==it); + } + + bool operator<(const iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + + private: + iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + iterator begin(); + iterator end(); + OsiCuts& cuts_; + int rowCutIndex_; + int colCutIndex_; + OsiCut * cutP_; + }; + + /** Const Iterator + + This is a class for iterating over the collection of cuts. + */ + class const_iterator { + friend class OsiCuts; + public: + typedef std::bidirectional_iterator_tag iterator_category; + typedef OsiCut* value_type; + typedef size_t difference_type; + typedef OsiCut ** pointer; + typedef OsiCut *& reference; + + public: + const_iterator(const OsiCuts& cuts); + const_iterator(const const_iterator & src); + const_iterator & operator=( const const_iterator& rhs); + ~const_iterator (); + const OsiCut* operator*() const { return cutP_; } + + const_iterator operator++(); + + const_iterator operator++(int) + { + const_iterator temp = *this; + ++*this; + return temp; + } + + bool operator==(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)==(it.colCutIndex_+it.rowCutIndex_); + } + + bool operator!=(const const_iterator& it) const { + return !((*this)==it); + } + + bool operator<(const const_iterator& it) const { + return (colCutIndex_+rowCutIndex_)<(it.colCutIndex_+it.rowCutIndex_); + } + private: + inline const_iterator(); + // *THINK* : how to inline these without sticking the code here (ugly...) + const_iterator begin(); + const_iterator end(); + const OsiCuts * cutsPtr_; + int rowCutIndex_; + int colCutIndex_; + const OsiCut * cutP_; + }; + //@} + + //------------------------------------------------------------------- + // + // Cuts class definition begins here: + // + //------------------------------------------------------------------- + + /** \name Inserting a cut into collection */ + //@{ + /** \brief Insert a row cut */ + inline void insert( const OsiRowCut & rc ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinAbsFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinAbsFltEq treatAsSame=CoinAbsFltEq(1.0e-12) ); + /** \brief Insert a row cut unless it is a duplicate - cut may get sorted. + Duplicate is defined as CoinRelFltEq says same*/ + void insertIfNotDuplicate( OsiRowCut & rc , CoinRelFltEq treatAsSame ); + /** \brief Insert a column cut */ + inline void insert( const OsiColCut & cc ); + + /** \brief Insert a row cut. + + The OsiCuts object takes control of the cut object. + On return, \c rcPtr is NULL. + */ + inline void insert( OsiRowCut * & rcPtr ); + /** \brief Insert a column cut. + + The OsiCuts object takes control of the cut object. + On return \c ccPtr is NULL. + */ + inline void insert( OsiColCut * & ccPtr ); +#if 0 + inline void insert( OsiCut * & cPtr ); +#endif + + /** \brief Insert a set of cuts */ + inline void insert(const OsiCuts & cs); + + //@} + + /**@name Number of cuts in collection */ + //@{ + /// Number of row cuts in collection + inline int sizeRowCuts() const; + /// Number of column cuts in collection + inline int sizeColCuts() const; + /// Number of cuts in collection + inline int sizeCuts() const; + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + inline void printCuts() const; + //@} + + /**@name Get a cut from collection */ + //@{ + /// Get pointer to i'th row cut + inline OsiRowCut * rowCutPtr(int i); + /// Get const pointer to i'th row cut + inline const OsiRowCut * rowCutPtr(int i) const; + /// Get pointer to i'th column cut + inline OsiColCut * colCutPtr(int i); + /// Get const pointer to i'th column cut + inline const OsiColCut * colCutPtr(int i) const; + + /// Get reference to i'th row cut + inline OsiRowCut & rowCut(int i); + /// Get const reference to i'th row cut + inline const OsiRowCut & rowCut(int i) const; + /// Get reference to i'th column cut + inline OsiColCut & colCut(int i); + /// Get const reference to i'th column cut + inline const OsiColCut & colCut(int i) const; + + /// Get const pointer to the most effective cut + inline const OsiCut * mostEffectiveCutPtr() const; + /// Get pointer to the most effective cut + inline OsiCut * mostEffectiveCutPtr(); + //@} + + /**@name Deleting cut from collection */ + //@{ + /// Remove i'th row cut from collection + inline void eraseRowCut(int i); + /// Remove i'th column cut from collection + inline void eraseColCut(int i); + /// Get pointer to i'th row cut and remove ptr from collection + inline OsiRowCut * rowCutPtrAndZap(int i); + /*! \brief Clear all row cuts without deleting them + + Handy in case one wants to use CGL without managing cuts in one of + the OSI containers. Client is ultimately responsible for deleting the + data structures holding the row cuts. + */ + inline void dumpCuts() ; + /*! \brief Selective delete and clear for row cuts. + + Deletes the cuts specified in \p to_erase then clears remaining cuts + without deleting them. A hybrid of eraseRowCut(int) and dumpCuts(). + Client is ultimately responsible for deleting the data structures + for row cuts not specified in \p to_erase. + */ + inline void eraseAndDumpCuts(const std::vector<int> to_erase) ; + //@} + + /**@name Sorting collection */ + //@{ + /// Cuts with greatest effectiveness are first. + inline void sort(); + //@} + + + /**@name Iterators + Example of using an iterator to sum effectiveness + of all cuts in the collection. + <pre> + double sumEff=0.0; + for ( OsiCuts::iterator it=cuts.begin(); it!=cuts.end(); ++it ) + sumEff+= (*it)->effectiveness(); + </pre> + */ + //@{ + /// Get iterator to beginning of collection + inline iterator begin() { iterator it(*this); it.begin(); return it; } + /// Get const iterator to beginning of collection + inline const_iterator begin() const { const_iterator it(*this); it.begin(); return it; } + /// Get iterator to end of collection + inline iterator end() { iterator it(*this); it.end(); return it; } + /// Get const iterator to end of collection + inline const_iterator end() const { const_iterator it(*this); it.end(); return it; } + //@} + + + /**@name Constructors and destructors */ + //@{ + /// Default constructor + OsiCuts (); + + /// Copy constructor + OsiCuts ( const OsiCuts &); + + /// Assignment operator + OsiCuts & operator=( const OsiCuts& rhs); + + /// Destructor + virtual ~OsiCuts (); + //@} + +private: + //*@name Function operator for sorting cuts by efectiveness */ + //@{ + class OsiCutCompare + { + public: + /// Function for sorting cuts by effectiveness + inline bool operator()(const OsiCut * c1P,const OsiCut * c2P) + { return c1P->effectiveness() > c2P->effectiveness(); } + }; + //@} + + /**@name Private methods */ + //@{ + /// Copy internal data + void gutsOfCopy( const OsiCuts & source ); + /// Delete internal data + void gutsOfDestructor(); + //@} + + /**@name Private member data */ + //@{ + /// Vector of row cuts pointers + OsiVectorRowCutPtr rowCutPtrs_; + /// Vector of column cuts pointers + OsiVectorColCutPtr colCutPtrs_; + //@} + +}; + + +//------------------------------------------------------------------- +// insert cuts into collection +//------------------------------------------------------------------- +void OsiCuts::insert( const OsiRowCut & rc ) +{ + OsiRowCut * newCutPtr = rc.clone(); + //assert(dynamic_cast<OsiRowCut*>(newCutPtr) != NULL ); + rowCutPtrs_.push_back(static_cast<OsiRowCut*>(newCutPtr)); +} +void OsiCuts::insert( const OsiColCut & cc ) +{ + OsiColCut * newCutPtr = cc.clone(); + //assert(dynamic_cast<OsiColCut*>(newCutPtr) != NULL ); + colCutPtrs_.push_back(static_cast<OsiColCut*>(newCutPtr)); +} + +void OsiCuts::insert( OsiRowCut* & rcPtr ) +{ + rowCutPtrs_.push_back(rcPtr); + rcPtr = NULL; +} +void OsiCuts::insert( OsiColCut* &ccPtr ) +{ + colCutPtrs_.push_back(ccPtr); + ccPtr = NULL; +} +#if 0 +void OsiCuts::insert( OsiCut* & cPtr ) +{ + OsiRowCut * rcPtr = dynamic_cast<OsiRowCut*>(cPtr); + if ( rcPtr != NULL ) { + insert( rcPtr ); + cPtr = rcPtr; + } + else { + OsiColCut * ccPtr = dynamic_cast<OsiColCut*>(cPtr); + assert( ccPtr != NULL ); + insert( ccPtr ); + cPtr = ccPtr; + } +} +#endif + +// LANNEZ SEBASTIEN added Thu May 25 01:22:51 EDT 2006 +void OsiCuts::insert(const OsiCuts & cs) +{ + for (OsiCuts::const_iterator it = cs.begin (); it != cs.end (); it++) + { + const OsiRowCut * rCut = dynamic_cast <const OsiRowCut * >(*it); + const OsiColCut * cCut = dynamic_cast <const OsiColCut * >(*it); + assert (rCut || cCut); + if (rCut) + insert (*rCut); + else + insert (*cCut); + } +} + +//------------------------------------------------------------------- +// sort +//------------------------------------------------------------------- +void OsiCuts::sort() +{ + std::sort(colCutPtrs_.begin(),colCutPtrs_.end(),OsiCutCompare()); + std::sort(rowCutPtrs_.begin(),rowCutPtrs_.end(),OsiCutCompare()); +} + + +//------------------------------------------------------------------- +// Get number of in collections +//------------------------------------------------------------------- +int OsiCuts::sizeRowCuts() const { + return static_cast<int>(rowCutPtrs_.size()); } +int OsiCuts::sizeColCuts() const { + return static_cast<int>(colCutPtrs_.size()); } +int OsiCuts::sizeCuts() const { + return static_cast<int>(sizeRowCuts()+sizeColCuts()); } + +//---------------------------------------------------------------- +// Get i'th cut from the collection +//---------------------------------------------------------------- +const OsiRowCut * OsiCuts::rowCutPtr(int i) const { return rowCutPtrs_[i]; } +const OsiColCut * OsiCuts::colCutPtr(int i) const { return colCutPtrs_[i]; } +OsiRowCut * OsiCuts::rowCutPtr(int i) { return rowCutPtrs_[i]; } +OsiColCut * OsiCuts::colCutPtr(int i) { return colCutPtrs_[i]; } + +const OsiRowCut & OsiCuts::rowCut(int i) const { return *rowCutPtr(i); } +const OsiColCut & OsiCuts::colCut(int i) const { return *colCutPtr(i); } +OsiRowCut & OsiCuts::rowCut(int i) { return *rowCutPtr(i); } +OsiColCut & OsiCuts::colCut(int i) { return *colCutPtr(i); } + +//---------------------------------------------------------------- +// Get most effective cut from collection +//---------------------------------------------------------------- +const OsiCut * OsiCuts::mostEffectiveCutPtr() const +{ + const_iterator b=begin(); + const_iterator e=end(); + return *(std::min_element(b,e,OsiCutCompare())); +} +OsiCut * OsiCuts::mostEffectiveCutPtr() +{ + iterator b=begin(); + iterator e=end(); + //return *(std::min_element(b,e,OsiCutCompare())); + OsiCut * retVal = NULL; + double maxEff = COIN_DBL_MIN; + for ( OsiCuts::iterator it=b; it!=e; ++it ) { + if (maxEff < (*it)->effectiveness() ) { + maxEff = (*it)->effectiveness(); + retVal = *it; + } + } + return retVal; +} + +//---------------------------------------------------------------- +// Print all cuts +//---------------------------------------------------------------- +void +OsiCuts::printCuts() const +{ + // do all column cuts first + int i; + int numberColCuts=sizeColCuts(); + for (i=0;i<numberColCuts;i++) { + const OsiColCut * cut = colCutPtr(i); + cut->print(); + } + int numberRowCuts=sizeRowCuts(); + for (i=0;i<numberRowCuts;i++) { + const OsiRowCut * cut = rowCutPtr(i); + cut->print(); + } +} + +//---------------------------------------------------------------- +// Erase i'th cut from the collection +//---------------------------------------------------------------- +void OsiCuts::eraseRowCut(int i) +{ + delete rowCutPtrs_[i]; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); +} +void OsiCuts::eraseColCut(int i) +{ + delete colCutPtrs_[i]; + colCutPtrs_.erase( colCutPtrs_.begin()+i ); +} +/// Get pointer to i'th row cut and remove ptr from collection +OsiRowCut * +OsiCuts::rowCutPtrAndZap(int i) +{ + OsiRowCut * cut = rowCutPtrs_[i]; + rowCutPtrs_[i]=NULL; + rowCutPtrs_.erase( rowCutPtrs_.begin()+i ); + return cut; +} +void OsiCuts::dumpCuts() +{ + rowCutPtrs_.clear() ; +} +void OsiCuts::eraseAndDumpCuts(const std::vector<int> to_erase) +{ + for (unsigned i=0; i<to_erase.size(); i++) { + delete rowCutPtrs_[to_erase[i]]; + } + rowCutPtrs_.clear(); +} + + +#endif diff --git a/thirdparty/linux/include/coin1/OsiPresolve.hpp b/thirdparty/linux/include/coin1/OsiPresolve.hpp new file mode 100644 index 0000000..9ec3d2a --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiPresolve.hpp @@ -0,0 +1,252 @@ +// Copyright (C) 2003, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiPresolve_H +#define OsiPresolve_H +#include "OsiSolverInterface.hpp" + +class CoinPresolveAction; +#include "CoinPresolveMatrix.hpp" + + +/*! \class OsiPresolve + \brief OSI interface to COIN problem simplification capabilities + + COIN provides a number of classes which implement problem simplification + algorithms (CoinPresolveAction, CoinPrePostsolveMatrix, and derived + classes). The model of operation is as follows: + <ul> + <li> + Create a copy of the original problem. + </li> + <li> + Subject the copy to a series of transformations (the <i>presolve</i> + methods) to produce a presolved model. Each transformation is also + expected to provide a method to reverse the transformation (the + <i>postsolve</i> method). The postsolve methods are collected in a + linked list; the postsolve method for the final presolve transformation + is at the head of the list. + </li> + <li> + Hand the presolved problem to the solver for optimization. + </li> + <li> + Apply the collected postsolve methods to the presolved problem + and solution, restating the solution in terms of the original problem. + </li> + </ul> + + The COIN presolve algorithms are unaware of OSI. The OsiPresolve class takes + care of the interface. Given an OsiSolverInterface \c origModel, it will take + care of creating a clone properly loaded with the presolved problem and ready + for optimization. After optimization, it will apply postsolve + transformations and load the result back into \c origModel. + + Assuming a problem has been loaded into an + \c OsiSolverInterface \c origModel, a bare-bones application looks like this: + \code + OsiPresolve pinfo ; + OsiSolverInterface *presolvedModel ; + // Return an OsiSolverInterface loaded with the presolved problem. + presolvedModel = pinfo.presolvedModel(*origModel,1.0e-8,false,numberPasses) ; + presolvedModel->initialSolve() ; + // Restate the solution and load it back into origModel. + pinfo.postsolve(true) ; + delete presolvedModel ; + \endcode +*/ + + + +class OsiPresolve { +public: + /// Default constructor (empty object) + OsiPresolve(); + + /// Virtual destructor + virtual ~OsiPresolve(); + + /*! \brief Create a new OsiSolverInterface loaded with the presolved problem. + + This method implements the first two steps described in the class + documentation. It clones \c origModel and applies presolve + transformations, storing the resulting list of postsolve + transformations. It returns a pointer to a new OsiSolverInterface loaded + with the presolved problem, or NULL if the problem is infeasible or + unbounded. If \c keepIntegers is true then bounds may be tightened in + the original. Bounds will be moved by up to \c feasibilityTolerance to + try and stay feasible. When \c doStatus is true, the current solution will + be transformed to match the presolved model. + + This should be paired with postsolve(). It is up to the client to + destroy the returned OsiSolverInterface, <i>after</i> calling postsolve(). + + This method is virtual. Override this method if you need to customize + the steps of creating a model to apply presolve transformations. + + In some sense, a wrapper for presolve(CoinPresolveMatrix*). + */ + virtual OsiSolverInterface *presolvedModel(OsiSolverInterface & origModel, + double feasibilityTolerance=0.0, + bool keepIntegers=true, + int numberPasses=5, + const char * prohibited=NULL, + bool doStatus=true, + const char * rowProhibited=NULL); + + /*! \brief Restate the solution to the presolved problem in terms of the + original problem and load it into the original model. + + postsolve() restates the solution in terms of the original problem and + updates the original OsiSolverInterface supplied to presolvedModel(). If + the problem has not been solved to optimality, there are no guarantees. + If you are using an algorithm like simplex that has a concept of a basic + solution, then set updateStatus + + The advantage of going back to the original problem is that it + will be exactly as it was, <i>i.e.</i>, 0.0 will not become 1.0e-19. + + Note that if you modified the original problem after presolving, then you + must ``undo'' these modifications before calling postsolve(). + + In some sense, a wrapper for postsolve(CoinPostsolveMatrix&). + */ + virtual void postsolve(bool updateStatus=true); + + /*! \brief Return a pointer to the presolved model. */ + OsiSolverInterface * model() const; + + /// Return a pointer to the original model + OsiSolverInterface * originalModel() const; + + /// Set the pointer to the original model + void setOriginalModel(OsiSolverInterface *model); + + /// Return a pointer to the original columns + const int * originalColumns() const; + + /// Return a pointer to the original rows + const int * originalRows() const; + + /// Return number of rows in original model + inline int getNumRows() const + { return nrows_;} + + /// Return number of columns in original model + inline int getNumCols() const + { return ncols_;} + + /** "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + */ + inline void setNonLinearValue(double value) + { nonLinearValue_ = value;} + inline double nonLinearValue() const + { return nonLinearValue_;} + /*! \brief Fine control over presolve actions + + Set/clear the following bits to allow or suppress actions: + - 0x01 allow duplicate column processing on integer columns + and dual stuff on integers + - 0x02 switch off actions which can change +1 to something else + (doubleton, tripleton, implied free) + - 0x04 allow transfer of costs from singletons and between integer + variables (when advantageous) + - 0x08 do not allow x+y+z=1 transform + - 0x10 allow actions that don't easily unroll + - 0x20 allow dubious gub element reduction + + GUB element reduction is only partially implemented in CoinPresolve (see + gubrow_action) and willl cause an abort at postsolve. It's not clear + what's meant by `dual stuff on integers'. + -- lh, 110605 -- + */ + inline void setPresolveActions(int action) + { presolveActions_ = (presolveActions_&0xffff0000)|(action&0xffff);} + +private: + /*! Original model (solver interface loaded with the original problem). + + Must not be destroyed until after postsolve(). + */ + OsiSolverInterface * originalModel_; + + /*! Presolved model (solver interface loaded with the presolved problem) + + Must be destroyed by the client (using delete) after postsolve(). + */ + OsiSolverInterface * presolvedModel_; + + /*! "Magic" number. If this is non-zero then any elements with this value + may change and so presolve is very limited in what can be done + to the row and column. This is for non-linear problems. + One could also allow for cases where sign of coefficient is known. + */ + double nonLinearValue_; + + /// Original column numbers + int * originalColumn_; + + /// Original row numbers + int * originalRow_; + + /// The list of transformations applied. + const CoinPresolveAction *paction_; + + /*! \brief Number of columns in original model. + + The problem will expand back to its former size as postsolve + transformations are applied. It is efficient to allocate data structures + for the final size of the problem rather than expand them as needed. + */ + int ncols_; + + /*! \brief Number of rows in original model. */ + int nrows_; + + /*! \brief Number of nonzero matrix coefficients in the original model. */ + CoinBigIndex nelems_; + + /** Whether we want to skip dual part of presolve etc. + 1 bit allows duplicate column processing on integer columns + and dual stuff on integers + 4 transfers costs to integer variables + */ + int presolveActions_; + /// Number of major passes + int numberPasses_; + +protected: + /*! \brief Apply presolve transformations to the problem. + + Handles the core activity of applying presolve transformations. + + If you want to apply the individual presolve routines differently, or + perhaps add your own to the mix, define a derived class and override + this method + */ + virtual const CoinPresolveAction *presolve(CoinPresolveMatrix *prob); + + /*! \brief Reverse presolve transformations to recover the solution + to the original problem. + + Handles the core activity of applying postsolve transformations. + + Postsolving is pretty generic; just apply the transformations in reverse + order. You will probably only be interested in overriding this method if + you want to add code to test for consistency while debugging new presolve + techniques. + */ + virtual void postsolve(CoinPostsolveMatrix &prob); + + /*! \brief Destroys queued postsolve actions. + + <i>E.g.</i>, when presolve() determines the problem is infeasible, so that + it will not be necessary to actually solve the presolved problem and + convert the result back to the original problem. + */ + void gutsOfDestroy(); +}; +#endif diff --git a/thirdparty/linux/include/coin1/OsiRowCut.hpp b/thirdparty/linux/include/coin1/OsiRowCut.hpp new file mode 100644 index 0000000..1332802 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiRowCut.hpp @@ -0,0 +1,331 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCut_H +#define OsiRowCut_H + +#include "CoinPackedVector.hpp" + +#include "OsiCollections.hpp" +#include "OsiCut.hpp" + +//#define OSI_INLINE_ROWCUT_METHODS +#ifdef OSI_INLINE_ROWCUT_METHODS +#define OsiRowCut_inline inline +#else +#define OsiRowCut_inline +#endif + +/** Row Cut Class + +A row cut has: + <ul> + <li>a lower bound<br> + <li>an upper bound<br> + <li>a vector of row elements + </ul> +*/ +class OsiRowCut : public OsiCut { + friend void OsiRowCutUnitTest(const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +public: + + /**@name Row bounds */ + //@{ + /// Get lower bound + OsiRowCut_inline double lb() const; + /// Set lower bound + OsiRowCut_inline void setLb(double lb); + /// Get upper bound + OsiRowCut_inline double ub() const; + /// Set upper bound + OsiRowCut_inline void setUb(double ub); + //@} + + /**@name Row rhs, sense, range */ + //@{ + /// Get sense ('E', 'G', 'L', 'N', 'R') + char sense() const; + /// Get right-hand side + double rhs() const; + /// Get range (ub - lb for 'R' rows, 0 otherwise) + double range() const; + //@} + + //------------------------------------------------------------------- + /**@name Row elements */ + //@{ + /// Set row elements + OsiRowCut_inline void setRow( + int size, + const int * colIndices, + const double * elements, + bool testForDuplicateIndex = COIN_DEFAULT_VALUE_FOR_DUPLICATE); + /// Set row elements from a packed vector + OsiRowCut_inline void setRow( const CoinPackedVector & v ); + /// Get row elements + OsiRowCut_inline const CoinPackedVector & row() const; + /// Get row elements for changing + OsiRowCut_inline CoinPackedVector & mutableRow() ; + //@} + + /**@name Comparison operators */ + //@{ +#if __GNUC__ != 2 + using OsiCut::operator== ; +#endif + /** equal - true if lower bound, upper bound, row elements, + and OsiCut are equal. + */ + OsiRowCut_inline bool operator==(const OsiRowCut& rhs) const; + +#if __GNUC__ != 2 + using OsiCut::operator!= ; +#endif + /// not equal + OsiRowCut_inline bool operator!=(const OsiRowCut& rhs) const; + //@} + + + //---------------------------------------------------------------- + /**@name Sanity checks on cut */ + //@{ + /** Returns true if the cut is consistent. + This checks to ensure that: + <ul> + <li>The row element vector does not have duplicate indices + <li>The row element vector indices are >= 0 + </ul> + */ + OsiRowCut_inline bool consistent() const; + + /** Returns true if cut is consistent with respect to the solver + interface's model. + This checks to ensure that + <ul> + <li>The row element vector indices are < the number of columns + in the model + </ul> + */ + OsiRowCut_inline bool consistent(const OsiSolverInterface& im) const; + + /** Returns true if the row cut itself is infeasible and cannot be satisfied. + This checks whether + <ul> + <li>the lower bound is strictly greater than the + upper bound. + </ul> + */ + OsiRowCut_inline bool infeasible(const OsiSolverInterface &im) const; + /** Returns infeasibility of the cut with respect to solution + passed in i.e. is positive if cuts off that solution. + solution is getNumCols() long.. + */ + virtual double violated(const double * solution) const; + //@} + + /**@name Arithmetic operators. Apply CoinPackedVector methods to the vector */ + //@{ + /// add <code>value</code> to every vector entry + void operator+=(double value) + { row_ += value; } + + /// subtract <code>value</code> from every vector entry + void operator-=(double value) + { row_ -= value; } + + /// multiply every vector entry by <code>value</code> + void operator*=(double value) + { row_ *= value; } + + /// divide every vector entry by <code>value</code> + void operator/=(double value) + { row_ /= value; } + //@} + + /// Allow access row sorting function + void sortIncrIndex() + {row_.sortIncrIndex();} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut & operator=( const OsiRowCut& rhs); + + /// Copy constructor + OsiRowCut ( const OsiRowCut &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut (); + + /** \brief Ownership Constructor + + This constructor assumes ownership of the vectors passed as parameters + for indices and elements. \p colIndices and \p elements will be NULL + on return. + */ + OsiRowCut(double cutlb, double cutub, + int capacity, int size, + int *&colIndices, double *&elements); + + /// Destructor + virtual ~OsiRowCut (); + //@} + + /**@name Debug stuff */ + //@{ + /// Print cuts in collection + virtual void print() const ; + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Row elements + CoinPackedVector row_; + /// Row lower bound + double lb_; + /// Row upper bound + double ub_; + //@} +}; + +#ifdef OSI_INLINE_ROWCUT_METHODS + +//------------------------------------------------------------------- +// Set/Get lower & upper bounds +//------------------------------------------------------------------- +double OsiRowCut::lb() const { return lb_; } +void OsiRowCut::setLb(double lb) { lb_ = lb; } +double OsiRowCut::ub() const { return ub_; } +void OsiRowCut::setUb(double ub) { ub_ = ub; } + +//------------------------------------------------------------------- +// Set row elements +//------------------------------------------------------------------- +void OsiRowCut::setRow(int size, + const int * colIndices, const double * elements) +{ + row_.setVector(size,colIndices,elements); +} +void OsiRowCut::setRow( const CoinPackedVector & v ) +{ + row_ = v; +} + +//------------------------------------------------------------------- +// Get the row +//------------------------------------------------------------------- +const CoinPackedVector & OsiRowCut::row() const +{ + return row_; +} + +//------------------------------------------------------------------- +// Get the row so we can change +//------------------------------------------------------------------- +CoinPackedVector & OsiRowCut::mutableRow() +{ + return row_; +} + +//---------------------------------------------------------------- +// == operator +//------------------------------------------------------------------- +bool +OsiRowCut::operator==(const OsiRowCut& rhs) const +{ + if ( this->OsiCut::operator!=(rhs) ) return false; + if ( row() != rhs.row() ) return false; + if ( lb() != rhs.lb() ) return false; + if ( ub() != rhs.ub() ) return false; + return true; +} +bool +OsiRowCut::operator!=(const OsiRowCut& rhs) const +{ + return !( (*this)==rhs ); +} + + +//---------------------------------------------------------------- +// consistent & infeasible +//------------------------------------------------------------------- +bool OsiRowCut::consistent() const +{ + const CoinPackedVector & r=row(); + r.duplicateIndex("consistent", "OsiRowCut"); + if ( r.getMinIndex() < 0 ) return false; + return true; +} +bool OsiRowCut::consistent(const OsiSolverInterface& im) const +{ + const CoinPackedVector & r=row(); + if ( r.getMaxIndex() >= im.getNumCols() ) return false; + + return true; +} +bool OsiRowCut::infeasible(const OsiSolverInterface &im) const +{ + if ( lb() > ub() ) return true; + + return false; +} + +#endif + +/** Row Cut Class which refers back to row which created it. + It may be useful to strengthen a row rather than add a cut. To do this + we need to know which row is strengthened. This trivial extension + to OsiRowCut does that. + +*/ +class OsiRowCut2 : public OsiRowCut { + +public: + + /**@name Which row */ + //@{ + /// Get row + inline int whichRow() const + { return whichRow_;} + /// Set row + inline void setWhichRow(int row) + { whichRow_=row;} + //@} + + /**@name Constructors and destructors */ + //@{ + /// Assignment operator + OsiRowCut2 & operator=( const OsiRowCut2& rhs); + + /// Copy constructor + OsiRowCut2 ( const OsiRowCut2 &); + + /// Clone + virtual OsiRowCut * clone() const; + + /// Default Constructor + OsiRowCut2 (int row=-1); + + /// Destructor + virtual ~OsiRowCut2 (); + //@} + +private: + + + /**@name Private member data */ + //@{ + /// Which row + int whichRow_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/OsiRowCutDebugger.hpp b/thirdparty/linux/include/coin1/OsiRowCutDebugger.hpp new file mode 100644 index 0000000..548e8e3 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiRowCutDebugger.hpp @@ -0,0 +1,187 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiRowCutDebugger_H +#define OsiRowCutDebugger_H + +/*! \file OsiRowCutDebugger.hpp + + \brief Provides a facility to validate cut constraints to ensure that they + do not cut off a given solution. +*/ + +#include <string> + +#include "OsiCuts.hpp" +#include "OsiSolverInterface.hpp" + +/*! \brief Validate cuts against a known solution + + OsiRowCutDebugger provides a facility for validating cuts against a known + solution for a problem. The debugger knows an optimal solution for many of + the miplib3 problems. Check the source for + #activate(const OsiSolverInterface&,const char*) + in OsiRowCutDebugger.cpp for the full set of known problems. + + A full solution vector can be supplied as a parameter with + (#activate(const OsiSolverInterface&,const double*,bool)). + Only the integer values need to be valid. + The default behaviour is to solve an lp relaxation with the integer + variables fixed to the specified values and use the optimal solution to fill + in the continuous variables in the solution. + The debugger can be instructed to preserve the continuous variables (useful + when debugging solvers where the linear relaxation doesn't capture all the + constraints). + + Note that the solution must match the problem held in the solver interface. + If you want to use the row cut debugger on a problem after applying presolve + transformations, your solution must match the presolved problem. (But see + #redoSolution().) +*/ +class OsiRowCutDebugger { + friend void OsiRowCutDebuggerUnitTest(const OsiSolverInterface * siP, + const std::string & mpsDir); + +public: + + /*! @name Validate Row Cuts + + Check that the specified cuts do not cut off the known solution. + */ + //@{ + /*! \brief Check that the set of cuts does not cut off the solution known + to the debugger. + + Check if any generated cuts cut off the solution known to the debugger! + If so then print offending cuts. Return the number of invalid cuts. + */ + virtual int validateCuts(const OsiCuts & cs, int first, int last) const; + + /*! \brief Check that the cut does not cut off the solution known to the + debugger. + + Return true if cut is invalid + */ + virtual bool invalidCut(const OsiRowCut & rowcut) const; + + /*! \brief Returns true if the solution held in the solver is compatible + with the known solution. + + More specifically, returns true if the known solution satisfies the column + bounds held in the solver. + */ + bool onOptimalPath(const OsiSolverInterface &si) const; + //@} + + /*! @name Activate the Debugger + + The debugger is considered to be active when it holds a known solution. + */ + //@{ + /*! \brief Activate a debugger using the name of a problem. + + The debugger knows an optimal solution for most of miplib3. Check the + source code for the full list. Returns true if the debugger is + successfully activated. + */ + bool activate(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Activate a debugger using a full solution array. + + The solution must have one entry for every variable, but only the entries + for integer values are used. By default the debugger will solve an lp + relaxation with the integer variables fixed and fill in values for the + continuous variables from this solution. If the debugger should preserve + the given values for the continuous variables, set \p keepContinuous to + \c true. + + Returns true if debugger activates successfully. + */ + bool activate(const OsiSolverInterface &si, const double* solution, + bool keepContinuous = false) ; + + /// Returns true if the debugger is active + bool active() const; + //@} + + /*! @name Query or Manipulate the Known Solution */ + //@{ + /// Return the known solution + inline const double * optimalSolution() const + { return knownSolution_;} + + /// Return the number of columns in the known solution + inline int numberColumns() const { return (numberColumns_) ; } + + /// Return the value of the objective for the known solution + inline double optimalValue() const { return knownValue_;} + + /*! \brief Edit the known solution to reflect column changes + + Given a translation array \p originalColumns[numberColumns] which can + translate current column indices to original column indices, this method + will edit the solution held in the debugger so that it matches the current + set of columns. + + Useful when the original problem is preprocessed prior to cut generation. + The debugger does keep a record of the changes. + */ + void redoSolution(int numberColumns, const int *originalColumns); + + /// Print optimal solution (returns -1 bad debug, 0 on optimal, 1 not) + int printOptimalSolution(const OsiSolverInterface & si) const; + //@} + + /**@name Constructors and Destructors */ + //@{ + /// Default constructor - no checking + OsiRowCutDebugger (); + + /*! \brief Constructor with name of model. + + See #activate(const OsiSolverInterface&,const char*). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const char *model) ; + + /*! \brief Constructor with full solution. + + See #activate(const OsiSolverInterface&,const double*,bool). + */ + OsiRowCutDebugger(const OsiSolverInterface &si, const double *solution, + bool enforceOptimality = false) ; + + /// Copy constructor + OsiRowCutDebugger(const OsiRowCutDebugger &); + + /// Assignment operator + OsiRowCutDebugger& operator=(const OsiRowCutDebugger& rhs); + + /// Destructor + virtual ~OsiRowCutDebugger (); + //@} + +private: + + // Private member data + + /**@name Private member data */ + //@{ + /// Value of known solution + double knownValue_; + + /*! \brief Number of columns in known solution + + This must match the number of columns reported by the solver. + */ + int numberColumns_; + + /// array specifying integer variables + bool * integerVariable_; + + /// array specifying known solution + double * knownSolution_; + //@} +}; + +#endif diff --git a/thirdparty/linux/include/coin1/OsiSolverBranch.hpp b/thirdparty/linux/include/coin1/OsiSolverBranch.hpp new file mode 100644 index 0000000..98c4343 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiSolverBranch.hpp @@ -0,0 +1,152 @@ +// Copyright (C) 2005, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverBranch_H +#define OsiSolverBranch_H + +class OsiSolverInterface; +#include "CoinWarmStartBasis.hpp" + +//############################################################################# + +/** Solver Branch Class + + This provides information on a branch as a set of tighter bounds on both ways +*/ + +class OsiSolverBranch { + +public: + ///@name Add and Get methods + //@{ + /// Add a simple branch (i.e. first sets ub of floor(value), second lb of ceil(value)) + void addBranch(int iColumn, double value); + + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberTighterLower, const int * whichLower, const double * newLower, + int numberTighterUpper, const int * whichUpper, const double * newUpper); + /// Add bounds - way =-1 is first , +1 is second + void addBranch(int way,int numberColumns,const double * oldLower, const double * newLower, + const double * oldUpper, const double * newUpper); + + /// Apply bounds + void applyBounds(OsiSolverInterface & solver,int way) const; + /// Returns true if current solution satsifies one side of branch + bool feasibleOneWay(const OsiSolverInterface & solver) const; + /// Starts + inline const int * starts() const + { return start_;} + /// Which variables + inline const int * which() const + { return indices_;} + /// Bounds + inline const double * bounds() const + { return bound_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverBranch(); + + /// Copy constructor + OsiSolverBranch(const OsiSolverBranch & rhs); + + /// Assignment operator + OsiSolverBranch & operator=(const OsiSolverBranch & rhs); + + /// Destructor + ~OsiSolverBranch (); + + //@} + +private: + ///@name Private member data + //@{ + /// Start of lower first, upper first, lower second, upper second + int start_[5]; + /// Column numbers (if >= numberColumns treat as rows) + int * indices_; + /// New bounds + double * bound_; + //@} +}; +//############################################################################# + +/** Solver Result Class + + This provides information on a result as a set of tighter bounds on both ways +*/ + +class OsiSolverResult { + +public: + ///@name Add and Get methods + //@{ + /// Create result + void createResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Restore result + void restoreResult(OsiSolverInterface & solver) const; + + /// Get basis + inline const CoinWarmStartBasis & basis() const + { return basis_;} + + /// Objective value (as minimization) + inline double objectiveValue() const + { return objectiveValue_;} + + /// Primal solution + inline const double * primalSolution() const + { return primalSolution_;} + + /// Dual solution + inline const double * dualSolution() const + { return dualSolution_;} + + /// Extra fixed + inline const OsiSolverBranch & fixed() const + { return fixed_;} + //@} + + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverResult(); + + /// Constructor from solver + OsiSolverResult(const OsiSolverInterface & solver,const double * lowerBefore, + const double * upperBefore); + + /// Copy constructor + OsiSolverResult(const OsiSolverResult & rhs); + + /// Assignment operator + OsiSolverResult & operator=(const OsiSolverResult & rhs); + + /// Destructor + ~OsiSolverResult (); + + //@} + +private: + ///@name Private member data + //@{ + /// Value of objective (if >= OsiSolverInterface::getInfinity() then infeasible) + double objectiveValue_; + /// Warm start information + CoinWarmStartBasis basis_; + /// Primal solution (numberColumns) + double * primalSolution_; + /// Dual solution (numberRows) + double * dualSolution_; + /// Which extra variables have been fixed (only way==-1 counts) + OsiSolverBranch fixed_; + //@} +}; +#endif diff --git a/thirdparty/linux/include/coin1/OsiSolverInterface.hpp b/thirdparty/linux/include/coin1/OsiSolverInterface.hpp new file mode 100644 index 0000000..a581961 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiSolverInterface.hpp @@ -0,0 +1,2143 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverInterface_H +#define OsiSolverInterface_H + +#include <cstdlib> +#include <string> +#include <vector> + +#include "CoinTypes.hpp" +#include "CoinMessageHandler.hpp" +#include "CoinPackedVectorBase.hpp" +#include "CoinPackedMatrix.hpp" +#include "CoinWarmStart.hpp" +#include "CoinFinite.hpp" +#include "CoinError.hpp" + +#include "OsiCollections.hpp" +#include "OsiSolverParameters.hpp" + +class CoinSnapshot; +class CoinLpIO; +class CoinMpsIO; + +class OsiCuts; +class OsiAuxInfo; +class OsiRowCut; +class OsiRowCutDebugger; +class CoinSet; +class CoinBuild; +class CoinModel; +class OsiSolverBranch; +class OsiSolverResult; +class OsiObject; + + +//############################################################################# + +/*! \brief Abstract Base Class for describing an interface to a solver. + + Many OsiSolverInterface query methods return a const pointer to the + requested read-only data. If the model data is changed or the solver + is called, these pointers may no longer be valid and should be + refreshed by invoking the member function to obtain an updated copy + of the pointer. + For example: + \code + OsiSolverInterface solverInterfacePtr ; + const double * ruBnds = solverInterfacePtr->getRowUpper(); + solverInterfacePtr->applyCuts(someSetOfCuts); + // ruBnds is no longer a valid pointer and must be refreshed + ruBnds = solverInterfacePtr->getRowUpper(); + \endcode + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. +*/ + +class OsiSolverInterface { + friend void OsiSolverInterfaceCommonUnitTest( + const OsiSolverInterface* emptySi, + const std::string & mpsDir, + const std::string & netlibDir); + friend void OsiSolverInterfaceMpsUnitTest( + const std::vector<OsiSolverInterface*> & vecSiP, + const std::string & mpsDir); + +public: + + /// Internal class for obtaining status from the applyCuts method + class ApplyCutsReturnCode { + friend class OsiSolverInterface; + friend class OsiClpSolverInterface; + friend class OsiGrbSolverInterface; + + public: + ///@name Constructors and desctructors + //@{ + /// Default constructor + ApplyCutsReturnCode(): + intInconsistent_(0), + extInconsistent_(0), + infeasible_(0), + ineffective_(0), + applied_(0) {} + /// Copy constructor + ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs): + intInconsistent_(rhs.intInconsistent_), + extInconsistent_(rhs.extInconsistent_), + infeasible_(rhs.infeasible_), + ineffective_(rhs.ineffective_), + applied_(rhs.applied_) {} + /// Assignment operator + ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs) + { + if (this != &rhs) { + intInconsistent_ = rhs.intInconsistent_; + extInconsistent_ = rhs.extInconsistent_; + infeasible_ = rhs.infeasible_; + ineffective_ = rhs.ineffective_; + applied_ = rhs.applied_; + } + return *this; + } + /// Destructor + ~ApplyCutsReturnCode(){} + //@} + + /**@name Accessing return code attributes */ + //@{ + /// Number of logically inconsistent cuts + inline int getNumInconsistent() const + {return intInconsistent_;} + /// Number of cuts inconsistent with the current model + inline int getNumInconsistentWrtIntegerModel() const + {return extInconsistent_;} + /// Number of cuts that cause obvious infeasibility + inline int getNumInfeasible() const + {return infeasible_;} + /// Number of redundant or ineffective cuts + inline int getNumIneffective() const + {return ineffective_;} + /// Number of cuts applied + inline int getNumApplied() const + {return applied_;} + //@} + + private: + /**@name Private methods */ + //@{ + /// Increment logically inconsistent cut counter + inline void incrementInternallyInconsistent(){intInconsistent_++;} + /// Increment model-inconsistent counter + inline void incrementExternallyInconsistent(){extInconsistent_++;} + /// Increment infeasible cut counter + inline void incrementInfeasible(){infeasible_++;} + /// Increment ineffective cut counter + inline void incrementIneffective(){ineffective_++;} + /// Increment applied cut counter + inline void incrementApplied(){applied_++;} + //@} + + ///@name Private member data + //@{ + /// Counter for logically inconsistent cuts + int intInconsistent_; + /// Counter for model-inconsistent cuts + int extInconsistent_; + /// Counter for infeasible cuts + int infeasible_; + /// Counter for ineffective cuts + int ineffective_; + /// Counter for applied cuts + int applied_; + //@} + }; + + //--------------------------------------------------------------------------- + + ///@name Solve methods + //@{ + /// Solve initial LP relaxation + virtual void initialSolve() = 0; + + /*! \brief Resolve an LP relaxation after problem modification + + Note the `re-' in `resolve'. initialSolve() should be used to solve the + problem for the first time. + */ + virtual void resolve() = 0; + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound() = 0; + +#ifdef CBC_NEXT_VERSION + /* + Would it make sense to collect all of these routines in a `MIP Helper' + section? It'd make it easier for users and implementors to find them. + */ + /** + Solve 2**N (N==depth) problems and return solutions and bases. + There are N branches each of which changes bounds on both sides + as given by branch. The user should provide an array of (empty) + results which will be filled in. See OsiSolveResult for more details + (in OsiSolveBranch.?pp) but it will include a basis and primal solution. + + The order of results is left to right at feasible leaf nodes so first one + is down, down, ..... + + Returns number of feasible leaves. Also sets number of solves done and number + of iterations. + + This is provided so a solver can do faster. + + If forceBranch true then branch done even if satisfied + */ + virtual int solveBranches(int depth,const OsiSolverBranch * branch, + OsiSolverResult * result, + int & numberSolves, int & numberIterations, + bool forceBranch=false); +#endif + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. When a set method returns false, the original value (if + any) should be unchanged. There can be various reasons for failure: the + given parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet + implemented for the solver or simply the value of the parameter is out + of the range the solver accepts. If a parameter setting call returns + false check the details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + \note + There is a default implementation of the set/get + methods, namely to store/retrieve the given value using an array in the + base class. A specific solver implementation can use this feature, for + example, to store parameters that should be used later on. Implementors + of a solver interface should overload these functions to provide the + proper interface to and accurately reflect the capabilities of a + specific solver. + + The format for hints is slightly different in that a boolean specifies + the sense of the hint and an enum specifies the strength of the hint. + Hints should be initialised when a solver is instantiated. + (See OsiSolverParameters.hpp for defined hint parameters and strength.) + When specifying the sense of the hint, a value of true means to work with + the hint, false to work against it. For example, + <ul> + <li> \code setHintParam(OsiDoScale,true,OsiHintTry) \endcode + is a mild suggestion to the solver to scale the constraint + system. + <li> \code setHintParam(OsiDoScale,false,OsiForceDo) \endcode + tells the solver to disable scaling, or throw an exception if + it cannot comply. + </ul> + As another example, a solver interface could use the value and strength + of the \c OsiDoReducePrint hint to adjust the amount of information + printed by the interface and/or solver. The extent to which a solver + obeys hints is left to the solver. The value and strength returned by + \c getHintParam will match the most recent call to \c setHintParam, + and will not necessarily reflect the solver's ability to comply with the + hint. If the hint strength is \c OsiForceDo, the solver is required to + throw an exception if it cannot perform the specified action. + + \note + As with the other set/get methods, there is a default implementation + which maintains arrays in the base class for hint sense and strength. + The default implementation does not store the \c otherInformation + pointer, and always throws an exception for strength \c OsiForceDo. + Implementors of a solver interface should override these functions to + provide the proper interface to and accurately reflect the capabilities + of a specific solver. + */ + //@{ + //! Set an integer parameter + virtual bool setIntParam(OsiIntParam key, int value) { + if (key == OsiLastIntParam) return (false) ; + intParam_[key] = value; + return true; + } + //! Set a double parameter + virtual bool setDblParam(OsiDblParam key, double value) { + if (key == OsiLastDblParam) return (false) ; + dblParam_[key] = value; + return true; + } + //! Set a string parameter + virtual bool setStrParam(OsiStrParam key, const std::string & value) { + if (key == OsiLastStrParam) return (false) ; + strParam_[key] = value; + return true; + } + /*! \brief Set a hint parameter + + The \c otherInformation parameter can be used to pass in an arbitrary + block of information which is interpreted by the OSI and the underlying + solver. Users are cautioned that this hook is solver-specific. + + Implementors: + The default implementation completely ignores \c otherInformation and + always throws an exception for OsiForceDo. This is almost certainly not + the behaviour you want; you really should override this method. + */ + virtual bool setHintParam(OsiHintParam key, bool yesNo=true, + OsiHintStrength strength=OsiHintTry, + void * /*otherInformation*/ = NULL) { + if (key==OsiLastHintParam) + return false; + hintParam_[key] = yesNo; + hintStrength_[key] = strength; + if (strength == OsiForceDo) + throw CoinError("OsiForceDo illegal", + "setHintParam", "OsiSolverInterface"); + return true; + } + //! Get an integer parameter + virtual bool getIntParam(OsiIntParam key, int& value) const { + if (key == OsiLastIntParam) return (false) ; + value = intParam_[key]; + return true; + } + //! Get a double parameter + virtual bool getDblParam(OsiDblParam key, double& value) const { + if (key == OsiLastDblParam) return (false) ; + value = dblParam_[key]; + return true; + } + //! Get a string parameter + virtual bool getStrParam(OsiStrParam key, std::string& value) const { + if (key == OsiLastStrParam) return (false) ; + value = strParam_[key]; + return true; + } + /*! \brief Get a hint parameter (all information) + + Return all available information for the hint: sense, strength, + and any extra information associated with the hint. + + Implementors: The default implementation will always set + \c otherInformation to NULL. This is almost certainly not the + behaviour you want; you really should override this method. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength, + void *& otherInformation) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + otherInformation=NULL; + return true; + } + /*! \brief Get a hint parameter (sense and strength only) + + Return only the sense and strength of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo, + OsiHintStrength& strength) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + strength = hintStrength_[key]; + return true; + } + /*! \brief Get a hint parameter (sense only) + + Return only the sense (true/false) of the hint. + */ + virtual bool getHintParam(OsiHintParam key, bool& yesNo) const { + if (key==OsiLastHintParam) + return false; + yesNo = hintParam_[key]; + return true; + } + /*! \brief Copy all parameters in this section from one solver to another + + Note that the current implementation also copies the appData block, + message handler, and rowCutDebugger. Arguably these should have + independent copy methods. + */ + void copyParameters(OsiSolverInterface & rhs); + + /** \brief Return the integrality tolerance of the underlying solver. + + We should be able to get an integrality tolerance, but + until that time just use the primal tolerance + + \todo + This method should be replaced; it's architecturally wrong. This + should be an honest dblParam with a keyword. Underlying solvers + that do not support integer variables should return false for set and + get on this parameter. Underlying solvers that support integrality + should add this to the parameters they support, using whatever + tolerance is appropriate. -lh, 091021- + */ + inline double getIntegerTolerance() const + { return dblParam_[OsiPrimalTolerance];} + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there numerical difficulties? + virtual bool isAbandoned() const = 0; + /// Is optimality proven? + virtual bool isProvenOptimal() const = 0; + /// Is primal infeasibility proven? + virtual bool isProvenPrimalInfeasible() const = 0; + /// Is dual infeasibility proven? + virtual bool isProvenDualInfeasible() const = 0; + /// Is the given primal objective limit reached? + virtual bool isPrimalObjectiveLimitReached() const; + /// Is the given dual objective limit reached? + virtual bool isDualObjectiveLimitReached() const; + /// Iteration limit reached? + virtual bool isIterationLimitReached() const = 0; + //@} + + //--------------------------------------------------------------------------- + /** \name Warm start methods + + Note that the warm start methods return a generic CoinWarmStart object. + The precise characteristics of this object are solver-dependent. Clients + who wish to maintain a maximum degree of solver independence should take + care to avoid unnecessary assumptions about the properties of a warm start + object. + */ + //@{ + /*! \brief Get an empty warm start object + + This routine returns an empty warm start object. Its purpose is + to provide a way for a client to acquire a warm start object of the + appropriate type for the solver, which can then be resized and modified + as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const = 0 ; + + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. + */ + virtual CoinWarmStart* getWarmStart() const = 0; + /** \brief Get warm start information. + + Return warm start information for the current state of the solver + interface. If there is no valid warm start information, an empty warm + start object wil be returned. This does not necessarily create an + object - may just point to one. must Delete set true if user + should delete returned object. + */ + virtual CoinWarmStart* getPointerToWarmStart(bool & mustDelete) ; + + /** \brief Set warm start information. + + Return true or false depending on whether the warm start information was + accepted or not. + By definition, a call to setWarmStart with a null parameter should + cause the solver interface to refresh its warm start information + from the underlying solver. + */ + virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0; + //@} + + //--------------------------------------------------------------------------- + /**@name Hot start methods + + Primarily used in strong branching. The user can create a hot start + object --- a snapshot of the optimization process --- then reoptimize + over and over again, starting from the same point. + + \note + <ul> + <li> Between hot started optimizations only bound changes are allowed. + <li> The copy constructor and assignment operator should NOT copy any + hot start information. + <li> The default implementation simply extracts a warm start object in + \c markHotStart, resets to the warm start object in + \c solveFromHotStart, and deletes the warm start object in + \c unmarkHotStart. + <em>Actual solver implementations are encouraged to do better.</em> + </ul> + + */ + //@{ + /// Create a hot start snapshot of the optimization process. + virtual void markHotStart(); + /// Optimize starting from the hot start snapshot. + virtual void solveFromHotStart(); + /// Delete the hot start snapshot. + virtual void unmarkHotStart(); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from the + methods that return vectors. + + Const pointers returned from any data-query method are valid as long as + the data is unchanged and the solver is not called. + */ + //@{ + /// Get the number of columns + virtual int getNumCols() const = 0; + + /// Get the number of rows + virtual int getNumRows() const = 0; + + /// Get the number of nonzero elements + virtual int getNumElements() const = 0; + + /// Get the number of integer variables + virtual int getNumIntegers() const ; + + /// Get a pointer to an array[getNumCols()] of column lower bounds + virtual const double * getColLower() const = 0; + + /// Get a pointer to an array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row constraint senses. + + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row right-hand sides + + <ul> + <li> if getRowSense()[i] == 'L' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'G' then + getRightHandSide()[i] == getRowLower()[i] + <li> if getRowSense()[i] == 'R' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'N' then + getRightHandSide()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const = 0; + + /*! \brief Get a pointer to an array[getNumRows()] of row ranges. + + <ul> + <li> if getRowSense()[i] == 'R' then + getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] + <li> if getRowSense()[i] != 'R' then + getRowRange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const = 0; + + /// Get a pointer to an array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const = 0; + + /// Get a pointer to an array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const = 0; + + /*! \brief Get a pointer to an array[getNumCols()] of objective + function coefficients. + */ + virtual const double * getObjCoefficients() const = 0; + + /*! \brief Get the objective function sense + + - 1 for minimisation (default) + - -1 for maximisation + */ + virtual double getObjSense() const = 0; + + /// Return true if the variable is continuous + virtual bool isContinuous(int colIndex) const = 0; + + /// Return true if the variable is binary + virtual bool isBinary(int colIndex) const; + + /*! \brief Return true if the variable is integer. + + This method returns true if the variable is binary or general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if the variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if the variable is binary and not fixed + virtual bool isFreeBinary(int colIndex) const; + + /*! \brief Return an array[getNumCols()] of column types + + \deprecated See #getColType + */ + inline const char *columnType(bool refresh=false) const + { return getColType(refresh); } + + /*! \brief Return an array[getNumCols()] of column types + + - 0 - continuous + - 1 - binary + - 2 - general integer + + If \p refresh is true, the classification of integer variables as + binary or general integer will be reevaluated. If the current bounds + are [0,1], or if the variable is fixed at 0 or 1, it will be classified + as binary, otherwise it will be classified as general integer. + */ + virtual const char * getColType(bool refresh=false) const; + + /// Get a pointer to a row-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByRow() const = 0; + + /// Get a pointer to a column-wise copy of the matrix + virtual const CoinPackedMatrix * getMatrixByCol() const = 0; + + /*! \brief Get a pointer to a mutable row-wise copy of the matrix. + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByRow() const {return NULL;} + + /*! \brief Get a pointer to a mutable column-wise copy of the matrix + + Returns NULL if the request is not meaningful (i.e., the OSI will not + recognise any modifications to the matrix). + */ + virtual CoinPackedMatrix * getMutableMatrixByCol() const {return NULL;} + + /// Get the solver's value for infinity + virtual double getInfinity() const = 0; + //@} + + /**@name Solution query methods */ + //@{ + /// Get a pointer to an array[getNumCols()] of primal variable values + virtual const double * getColSolution() const = 0; + + /** Get a pointer to an array[getNumCols()] of primal variable values + guaranteed to be between the column lower and upper bounds. + */ + virtual const double * getStrictColSolution(); + + /// Get pointer to array[getNumRows()] of dual variable values + virtual const double * getRowPrice() const = 0; + + /// Get a pointer to an array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const = 0; + + /** Get a pointer to array[getNumRows()] of row activity levels. + + The row activity for a row is the left-hand side evaluated at the + current solution. + */ + virtual const double * getRowActivity() const = 0; + + /// Get the objective function value. + virtual double getObjValue() const = 0; + + /** Get the number of iterations it took to solve the problem (whatever + `iteration' means to the solver). + */ + virtual int getIterationCount() const = 0; + + /** Get as many dual rays as the solver can provide. In case of proven + primal infeasibility there should (with high probability) be at least + one. + + The first getNumRows() ray components will always be associated with + the row duals (as returned by getRowPrice()). If \c fullRay is true, + the final getNumCols() entries will correspond to the ray components + associated with the nonbasic variables. If the full ray is requested + and the method cannot provide it, it will throw an exception. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumRows() (fullRay = + false) or (getNumRows()+getNumCols()) (fullRay = true) and they should + be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const = 0; + + /** Get as many primal rays as the solver can provide. In case of proven + dual infeasibility there should (with high probability) be at least + one. + + \note + Implementors of solver interfaces note that the double pointers in + the vector should point to arrays of length getNumCols() and they + should be allocated with new[]. + + \note + Clients of solver interfaces note that it is the client's + responsibility to free the double pointers in the vector using + delete[]. Clients are reminded that a problem can be dual and primal + infeasible. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0; + + /** Get vector of indices of primal variables which are integer variables + but have fractional values in the current solution. */ + virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05) + const; + //@} + + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + + For functions which take a set of indices as parameters + (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), + \c setRowSetTypes()), the parameters follow the C++ STL iterator + convention: \c indexFirst points to the first index in the + set, and \c indexLast points to a position one past the last index + in the set. + + */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ) = 0; + + /** Set a set of objective function coefficients */ + virtual void setObjCoeffSet(const int* indexFirst, + const int* indexLast, + const double* coeffList); + + /** Set the objective coefficients for all columns. + + array [getNumCols()] is an array of values for the objective. + This defaults to a series of set operations and is here for speed. + */ + virtual void setObjective(const double * array); + + /** Set the objective function sense. + + Use 1 for minimisation (default), -1 for maximisation. + + \note + Implementors note that objective function sense is a parameter of + the OSI, not a property of the problem. Objective sense can be + set prior to problem load and should not be affected by loading a + new problem. + */ + virtual void setObjSense(double s) = 0; + + + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ) = 0; + + /** Set the lower bounds for all columns. + + array [getNumCols()] is an array of values for the lower bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColLower(const double * array); + + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ) = 0; + + /** Set the upper bounds for all columns. + + array [getNumCols()] is an array of values for the upper bounds. + This defaults to a series of set operations and is here for speed. + */ + virtual void setColUpper(const double * array); + + + /** Set a single column lower and upper bound. + The default implementation just invokes setColLower() and + setColUpper() */ + virtual void setColBounds( int elementIndex, + double lower, double upper ) { + setColLower(elementIndex, lower); + setColUpper(elementIndex, upper); + } + + /** Set the upper and lower bounds of a set of columns. + + The default implementation just invokes setColBounds() over and over + again. For each column, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setColSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ) = 0; + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ) = 0; + + /** Set a single row lower and upper bound. + The default implementation just invokes setRowLower() and + setRowUpper() */ + virtual void setRowBounds( int elementIndex, + double lower, double upper ) { + setRowLower(elementIndex, lower); + setRowUpper(elementIndex, upper); + } + + /** Set the bounds on a set of rows. + + The default implementation just invokes setRowBounds() over and over + again. For each row, boundList must contain both a lower and + upper bound, in that order. + */ + virtual void setRowSetBounds(const int* indexFirst, + const int* indexLast, + const double* boundList); + + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range) = 0; + + /** Set the type of a set of rows. + The default implementation just invokes setRowType() + over and over again. + */ + virtual void setRowSetTypes(const int* indexFirst, + const int* indexLast, + const char* senseList, + const double* rhsList, + const double* rangeList); + + /** Set the primal solution variable values + + colsol[getNumCols()] is an array of values for the primal variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getColSolution() until changed by another call to setColSolution() or + by a call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setColSolution(const double *colsol) = 0; + + /** Set dual solution variable values + + rowprice[getNumRows()] is an array of values for the dual variables. + These values are copied to memory owned by the solver interface + object or the solver. They will be returned as the result of + getRowPrice() until changed by another call to setRowPrice() or by a + call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + virtual void setRowPrice(const double * rowprice) = 0; + + /** Fix variables at bound based on reduced cost + + For variables currently at bound, fix the variable at bound if the + reduced cost exceeds the gap. Return the number of variables fixed. + + If justInteger is set to false, the routine will also fix continuous + variables, but the test still assumes a delta of 1.0. + */ + virtual int reducedCostFix(double gap, bool justInteger=true); + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index) = 0; + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index) = 0; + /** Set the variables listed in indices (which is of length len) to be + continuous variables */ + virtual void setContinuous(const int* indices, int len); + /** Set the variables listed in indices (which is of length len) to be + integer variables */ + virtual void setInteger(const int* indices, int len); + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + + /*! \brief Data type for name vectors. */ + typedef std::vector<std::string> OsiNameVec ; + + /*! \name Methods for row and column names + + Osi defines three name management disciplines: `auto names' (0), `lazy + names' (1), and `full names' (2). See the description of + #OsiNameDiscipline for details. Changing the name discipline (via + setIntParam()) will not automatically add or remove name information, + but setting the discipline to auto will make existing information + inaccessible until the discipline is reset to lazy or full. + + By definition, a row index of getNumRows() (<i>i.e.</i>, one larger than + the largest valid row index) refers to the objective function. + + OSI users and implementors: While the OSI base class can define an + interface and provide rudimentary support, use of names really depends + on support by the OsiXXX class to ensure that names are managed + correctly. If an OsiXXX class does not support names, it should return + false for calls to getIntParam() or setIntParam() that reference + OsiNameDiscipline. + */ + //@{ + + /*! \brief Generate a standard name of the form Rnnnnnnn or Cnnnnnnn + + Set \p rc to 'r' for a row name, 'c' for a column name. + The `nnnnnnn' part is generated from ndx and will contain 7 digits + by default, padded with zeros if necessary. As a special case, + ndx = getNumRows() is interpreted as a request for the name of the + objective function. OBJECTIVE is returned, truncated to digits+1 + characters to match the row and column names. + */ + virtual std::string dfltRowColName(char rc, + int ndx, unsigned digits = 7) const ; + + /*! \brief Return the name of the objective function */ + + virtual std::string getObjName (unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Set the name of the objective function */ + + virtual inline void setObjName (std::string name) + { objName_ = name ; } + + /*! \brief Return the name of the row. + + The routine will <i>always</i> return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getRowName(int rowIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of row names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. In particular, the objective name is <i>not</i> + included in the vector for lazy names. If the name discipline is + full, the vector will have getNumRows() names, either supplied or + generated, plus one additional entry for the objective name. + */ + virtual const OsiNameVec &getRowNames() ; + + /*! \brief Set a row name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the row index is invalid. + */ + virtual void setRowName(int ndx, std::string name) ; + + /*! \brief Set multiple row names + + The run of len entries starting at srcNames[srcStart] are installed as + row names starting at row index tgtStart. The base class implementation + makes repeated calls to setRowName. + */ + virtual void setRowNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len row names starting at index tgtStart + + The specified row names are removed and the remaining row names are + copied down to close the gap. + */ + virtual void deleteRowNames(int tgtStart, int len) ; + + /*! \brief Return the name of the column + + The routine will <i>always</i> return some name, regardless of the name + discipline or the level of support by an OsiXXX derived class. Use + maxLen to limit the length. + */ + virtual std::string getColName(int colIndex, + unsigned maxLen = static_cast<unsigned>(std::string::npos)) const ; + + /*! \brief Return a pointer to a vector of column names + + If the name discipline (#OsiNameDiscipline) is auto, the return value + will be a vector of length zero. If the name discipline is lazy, the + vector will contain only names supplied by the client and will be no + larger than needed to hold those names; entries not supplied will be + null strings. If the name discipline is full, the vector will have + getNumCols() names, either supplied or generated. + */ + virtual const OsiNameVec &getColNames() ; + + /*! \brief Set a column name + + Quietly does nothing if the name discipline (#OsiNameDiscipline) is + auto. Quietly fails if the column index is invalid. + */ + virtual void setColName(int ndx, std::string name) ; + + /*! \brief Set multiple column names + + The run of len entries starting at srcNames[srcStart] are installed as + column names starting at column index tgtStart. The base class + implementation makes repeated calls to setColName. + */ + virtual void setColNames(OsiNameVec &srcNames, + int srcStart, int len, int tgtStart) ; + + /*! \brief Delete len column names starting at index tgtStart + + The specified column names are removed and the remaining column names + are copied down to close the gap. + */ + virtual void deleteColNames(int tgtStart, int len) ; + + + /*! \brief Set row and column names from a CoinMpsIO object. + + Also sets the name of the objective function. If the name discipline + is auto, you get what you asked for. This routine does not use + setRowName or setColName. + */ + void setRowColNames(const CoinMpsIO &mps) ; + + /*! \brief Set row and column names from a CoinModel object. + + If the name discipline is auto, you get what you asked for. + This routine does not use setRowName or setColName. + */ + void setRowColNames(CoinModel &mod) ; + + /*! \brief Set row and column names from a CoinLpIO object. + + Also sets the name of the objective function. If the name discipline is + auto, you get what you asked for. This routine does not use setRowName + or setColName. + */ + void setRowColNames(CoinLpIO &mod) ; + + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + /**@name Methods to modify the constraint system. + + Note that new columns are added as continuous variables. + */ + //@{ + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj) = 0; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a column (primal variable) to the problem. */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj) ; + + /*! \brief Add a named column (primal variable) to the problem. + + The default implementation adds the column, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addCol(int numberElements, + const int* rows, const double* elements, + const double collb, const double colub, + const double obj, std::string name) ; + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, + const CoinPackedVectorBase * const * cols, + const double* collb, const double* colub, + const double* obj); + + /** Add a set of columns (primal variables) to the problem. + + The default implementation simply makes repeated calls to + addCol(). + */ + virtual void addCols(const int numcols, const int* columnStarts, + const int* rows, const double* elements, + const double* collb, const double* colub, + const double* obj); + + /// Add columns using a CoinBuild object + void addCols(const CoinBuild & buildObject); + + /** Add columns from a model object. returns + -1 if object in bad state (i.e. has row information) + otherwise number of errors + modelObject non const as can be regularized as part of build + */ + int addCols(CoinModel & modelObject); + +#if 0 + /** */ + virtual void addCols(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj); +#endif + + /** \brief Remove a set of columns (primal variables) from the + problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted variables are nonbasic. + */ + virtual void deleteCols(const int num, const int * colIndices) = 0; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub, + std::string name) ; + + /*! \brief Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng) = 0; + + /*! \brief Add a named row (constraint) to the problem. + + The default implementation adds the row, then changes the name. This + can surely be made more efficient within an OsiXXX class. + */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng, std::string name) ; + + /*! Add a row (constraint) to the problem. + + Converts to addRow(CoinPackedVectorBase&,const double,const double). + */ + virtual void addRow(int numberElements, + const int *columns, const double *element, + const double rowlb, const double rowub) ; + + /*! Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const double* rowlb, const double* rowub); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, + const CoinPackedVectorBase * const * rows, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Add a set of rows (constraints) to the problem. + + The default implementation simply makes repeated calls to + addRow(). + */ + virtual void addRows(const int numrows, const int *rowStarts, + const int *columns, const double *element, + const double *rowlb, const double *rowub); + + /// Add rows using a CoinBuild object + void addRows(const CoinBuild &buildObject); + + /*! Add rows from a CoinModel object. + + Returns -1 if the object is in the wrong state (<i>i.e.</i>, has + column-major information), otherwise the number of errors. + + The modelObject is not const as it can be regularized as part of + the build. + */ + int addRows(CoinModel &modelObject); + +#if 0 + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const double* rowlb, const double* rowub); + /** */ + virtual void addRows(const CoinPackedMatrix& matrix, + const char* rowsen, const double* rowrhs, + const double* rowrng); +#endif + + /** \brief Delete a set of rows (constraints) from the problem. + + The solver interface for a basis-oriented solver will maintain valid + warm start information if all deleted rows are loose. + */ + virtual void deleteRows(const int num, const int * rowIndices) = 0; + + /** \brief Replace the constraint matrix + + I (JJF) am getting annoyed because I can't just replace a matrix. + The default behavior of this is do nothing so only use where that would + not matter, e.g. strengthening a matrix for MIP. + */ + virtual void replaceMatrixOptional(const CoinPackedMatrix & ) {} + + /** \brief Replace the constraint matrix + + And if it does matter (not used at present) + */ + virtual void replaceMatrix(const CoinPackedMatrix & ) {abort();} + + /** \brief Save a copy of the base model + + If solver wants it can save a copy of "base" (continuous) model here. + */ + virtual void saveBaseModel() {} + + /** \brief Reduce the constraint system to the specified number of + constraints. + + If solver wants it can restore a copy of "base" (continuous) model + here. + + \note + The name is somewhat misleading. Implementors should consider + the opportunity to optimise behaviour in the common case where + \p numberRows is exactly the number of original constraints. Do not, + however, neglect the possibility that \p numberRows does not equal + the number of original constraints. + */ + virtual void restoreBaseModel(int numberRows); + //----------------------------------------------------------------------- + /** Apply a collection of cuts. + + Only cuts which have an <code>effectiveness >= effectivenessLb</code> + are applied. + <ul> + <li> ReturnCode.getNumineffective() -- number of cuts which were + not applied because they had an + <code>effectiveness < effectivenessLb</code> + <li> ReturnCode.getNuminconsistent() -- number of invalid cuts + <li> ReturnCode.getNuminconsistentWrtIntegerModel() -- number of + cuts that are invalid with respect to this integer model + <li> ReturnCode.getNuminfeasible() -- number of cuts that would + make this integer model infeasible + <li> ReturnCode.getNumApplied() -- number of integer cuts which + were applied to the integer model + <li> cs.size() == getNumineffective() + + getNuminconsistent() + + getNuminconsistentWrtIntegerModel() + + getNuminfeasible() + + getNumApplied() + </ul> + */ + virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs, + double effectivenessLb = 0.0); + + /** Apply a collection of row cuts which are all effective. + applyCuts seems to do one at a time which seems inefficient. + Would be even more efficient to pass an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts); + + /** Apply a collection of row cuts which are all effective. + This is passed in as an array of pointers. + */ + virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts); + + /// Deletes branching information before columns deleted + void deleteBranchingInfo(int numberDeleted, const int * which); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods for problem input and output */ + //@{ + /*! \brief Load in a problem by copying the arguments. The constraints on + the rows are given by lower and upper bounds. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + + Note that the default values for rowub and rowlb produce the + constraint -infty <= ax <= infty. This is probably not what you want. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by lower and upper bounds. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ <code>delete</code> and <code>delete[]</code> functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + If a pointer is 0 then the following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + + Note that the default values for rowsen, rowrhs, and rowrng produce the + constraint ax >= 0. + */ + virtual void loadProblem (const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load in a problem by assuming ownership of the arguments. + The constraints on the rows are given by sense/rhs/range triplets. + + For default argument values see the matching loadProblem method. + + \warning + The arguments passed to this method will be freed using the + C++ <code>delete</code> and <code>delete[]</code> functions. + */ + virtual void assignProblem (CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by lower and upper bounds. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadProblem method using rowlb and rowub for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub) = 0; + + /*! \brief Load in a problem by copying the arguments. The constraint + matrix is is specified with standard column-major + column starts / row indices / coefficients vectors. + The constraints on the rows are given by sense/rhs/range triplets. + + The matrix vectors must be gap-free. Note that <code>start</code> must + have <code>numcols+1</code> entries so that the length of the last column + can be calculated as <code>start[numcols]-start[numcols-1]</code>. + + See the previous loadProblem method using sense/rhs/range for default + argument values. + */ + virtual void loadProblem (const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng) = 0; + + /*! \brief Load a model from a CoinModel object. Return the number of + errors encountered. + + The modelObject parameter cannot be const as it may be changed as part + of process. If keepSolution is true will try and keep warmStart. + */ + virtual int loadFromCoinModel (CoinModel & modelObject, + bool keepSolution=false); + + /*! \brief Read a problem in MPS format from the given filename. + + The default implementation uses CoinMpsIO::readMps() to read + the MPS file and returns the number of errors encountered. + */ + virtual int readMps (const char *filename, + const char *extension = "mps") ; + + /*! \brief Read a problem in MPS format from the given full filename. + + This uses CoinMpsIO::readMps() to read the MPS file and returns the + number of errors encountered. It also may return an array of set + information + */ + virtual int readMps (const char *filename, const char*extension, + int & numberSets, CoinSet ** & sets); + + /*! \brief Read a problem in GMPL format from the given filenames. + + The default implementation uses CoinMpsIO::readGMPL(). This capability + is available only if the third-party package Glpk is installed. + */ + virtual int readGMPL (const char *filename, const char *dataname=NULL); + + /*! \brief Write the problem in MPS format to the specified file. + + If objSense is non-zero, a value of -1.0 causes the problem to be + written with a maximization objective; +1.0 forces a minimization + objective. If objSense is zero, the choice is left to the implementation. + */ + virtual void writeMps (const char *filename, + const char *extension = "mps", + double objSense=0.0) const = 0; + + /*! \brief Write the problem in MPS format to the specified file with + more control over the output. + + Row and column names may be null. + formatType is + <ul> + <li> 0 - normal + <li> 1 - extra accuracy + <li> 2 - IEEE hex + </ul> + + Returns non-zero on I/O error + */ + int writeMpsNative (const char *filename, + const char ** rowNames, const char ** columnNames, + int formatType=0,int numberAcross=2, + double objSense=0.0, int numberSOS=0, + const CoinSet * setInfo=NULL) const ; + +/***********************************************************************/ +// Lp files + + /** Write the problem into an Lp file of the given filename with the + specified extension. + Coefficients with value less than epsilon away from an integer value + are written as integers. + Write at most numberAcross monomials on a line. + Write non integer numbers with decimals digits after the decimal point. + + The written problem is always a minimization problem. + If the current problem is a maximization problem, the + intended objective function for the written problem is the current + objective function multiplied by -1. If the current problem is a + minimization problem, the intended objective function for the + written problem is the current objective function. + If objSense < 0, the intended objective function is multiplied by -1 + before writing the problem. It is left unchanged otherwise. + + Write objective function name and constraint names if useRowNames is + true. This version calls writeLpNative(). + */ + virtual void writeLp(const char *filename, + const char *extension = "lp", + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLp() with first parameter filename. + */ + virtual void writeLp(FILE *fp, + double epsilon = 1e-5, + int numberAcross = 10, + int decimals = 5, + double objSense = 0.0, + bool useRowNames = true) const; + + /** Write the problem into an Lp file. Parameters are similar to + those of writeLp(), but in addition row names and column names + may be given. + + Parameter rowNames may be NULL, in which case default row names + are used. If rowNames is not NULL, it must have exactly one entry + per row in the problem and one additional + entry (rowNames[getNumRows()] with the objective function name. + These getNumRows()+1 entries must be distinct. If this is not the + case, default row names + are used. In addition, format restrictions are imposed on names + (see CoinLpIO::is_invalid_name() for details). + + Similar remarks can be made for the parameter columnNames which + must either be NULL or have exactly getNumCols() distinct entries. + + Write objective function name and constraint names if + useRowNames is true. */ + int writeLpNative(const char *filename, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /** Write the problem into the file pointed to by the parameter fp. + Other parameters are similar to + those of writeLpNative() with first parameter filename. + */ + int writeLpNative(FILE *fp, + char const * const * const rowNames, + char const * const * const columnNames, + const double epsilon = 1.0e-5, + const int numberAcross = 10, + const int decimals = 5, + const double objSense = 0.0, + const bool useRowNames = true) const; + + /// Read file in LP format from file with name filename. + /// See class CoinLpIO for description of this format. + virtual int readLp(const char *filename, const double epsilon = 1e-5); + + /// Read file in LP format from the file pointed to by fp. + /// See class CoinLpIO for description of this format. + int readLp(FILE *fp, const double epsilon = 1e-5); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Miscellaneous */ + //@{ + /** Check two models against each other. Return nonzero if different. + Ignore names if that set. + (Note initial version does not check names) + May modify both models by cleaning up + */ + int differentModel(OsiSolverInterface & other, + bool ignoreNames=true); +#ifdef COIN_SNAPSHOT + /// Return a CoinSnapshot + virtual CoinSnapshot * snapshot(bool createArrays=true) const; +#endif +#ifdef COIN_FACTORIZATION_INFO + /// Return number of entries in L part of current factorization + virtual CoinBigIndex getSizeL() const; + /// Return number of entries in U part of current factorization + virtual CoinBigIndex getSizeU() const; +#endif + //@} + + //--------------------------------------------------------------------------- + + /**@name Setting/Accessing application data */ + //@{ + /** Set application data. + + This is a pointer that the application can store into and + retrieve from the solver interface. + This field is available for the application to optionally + define and use. + */ + void setApplicationData (void * appData); + /** Create a clone of an Auxiliary Information object. + The base class just stores an application data pointer + but can be more general. Application data pointer is + designed for one user while this can be extended to cope + with more general extensions. + */ + void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo); + + /// Get application data + void * getApplicationData() const; + /// Get pointer to auxiliary info object + OsiAuxInfo * getAuxiliaryInfo() const; + //@} + //--------------------------------------------------------------------------- + + /**@name Message handling + + See the COIN library documentation for additional information about + COIN message facilities. + + */ + //@{ + /** Pass in a message handler + + It is the client's responsibility to destroy a message handler installed + by this routine; it will not be destroyed when the solver interface is + destroyed. + */ + virtual void passInMessageHandler(CoinMessageHandler * handler); + /// Set language + void newLanguage(CoinMessages::Language language); + inline void setLanguage(CoinMessages::Language language) + {newLanguage(language);} + /// Return a pointer to the current message handler + inline CoinMessageHandler * messageHandler() const + {return handler_;} + /// Return the current set of messages + inline CoinMessages messages() + {return messages_;} + /// Return a pointer to the current set of messages + inline CoinMessages * messagesPointer() + {return &messages_;} + /// Return true if default handler + inline bool defaultHandler() const + { return defaultHandler_;} + //@} + //--------------------------------------------------------------------------- + /**@name Methods for dealing with discontinuities other than integers. + + Osi should be able to know about SOS and other types. This is an optional + section where such information can be stored. + + */ + //@{ + /** \brief Identify integer variables and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If justCount then no objects created and we just store numberIntegers_ + */ + + void findIntegers(bool justCount); + /** \brief Identify integer variables and SOS and create corresponding objects. + + Record integer variables and create an OsiSimpleInteger object for each + one. All existing OsiSimpleInteger objects will be destroyed. + If the solver supports SOS then do the same for SOS. + + If justCount then no objects created and we just store numberIntegers_ + Returns number of SOS + */ + + virtual int findIntegersAndSOS(bool justCount); + /// Get the number of objects + inline int numberObjects() const { return numberObjects_;} + /// Set the number of objects + inline void setNumberObjects(int number) + { numberObjects_=number;} + + /// Get the array of objects + inline OsiObject ** objects() const { return object_;} + + /// Get the specified object + const inline OsiObject * object(int which) const { return object_[which];} + /// Get the specified object + inline OsiObject * modifiableObject(int which) const { return object_[which];} + + /// Delete all object information + void deleteObjects(); + + /** Add in object information. + + Objects are cloned; the owner can delete the originals. + */ + void addObjects(int numberObjects, OsiObject ** objects); + /** Use current solution to set bounds so current integer feasible solution will stay feasible. + Only feasible bounds will be used, even if current solution outside bounds. The amount of + such violation will be returned (and if small can be ignored) + */ + double forceFeasible(); + //@} + //--------------------------------------------------------------------------- + + /*! @name Methods related to testing generated cuts + + See the documentation for OsiRowCutDebugger for additional details. + */ + //@{ + /*! \brief Activate the row cut debugger. + + If \p modelName is in the set of known models then all cuts are + checked to see that they do NOT cut off the optimal solution known + to the debugger. + */ + virtual void activateRowCutDebugger (const char *modelName); + + /*! \brief Activate the row cut debugger using a full solution array. + + + Activate the debugger for a model not included in the debugger's + internal database. Cuts will be checked to see that they do NOT + cut off the given solution. + + \p solution must be a full solution vector, but only the integer + variables need to be correct. The debugger will fill in the continuous + variables by solving an lp relaxation with the integer variables + fixed as specified. If the given values for the continuous variables + should be preserved, set \p keepContinuous to true. + */ + virtual void activateRowCutDebugger(const double *solution, + bool enforceOptimality = true); + + /*! \brief Get the row cut debugger provided the solution known to the + debugger is within the feasible region held in the solver. + + If there is a row cut debugger object associated with model AND if + the solution known to the debugger is within the solver's current + feasible region (i.e., the column bounds held in the solver are + compatible with the known solution) then a pointer to the debugger + is returned which may be used to test validity of cuts. + + Otherwise NULL is returned + */ + const OsiRowCutDebugger *getRowCutDebugger() const; + + /*! \brief Get the row cut debugger object + + Return the row cut debugger object if it exists. One common usage of + this method is to obtain a debugger object in order to execute + OsiRowCutDebugger::redoSolution (so that the stored solution is again + compatible with the problem held in the solver). + */ + OsiRowCutDebugger * getRowCutDebuggerAlways() const; + //@} + + /*! \name OsiSimplexInterface + \brief Simplex Interface + + Methods for an advanced interface to a simplex solver. The interface + comprises two groups of methods. Group 1 contains methods for tableau + access. Group 2 contains methods for dictating individual simplex pivots. + */ + //@{ + + /*! \brief Return the simplex implementation level. + + The return codes are: + - 0: the simplex interface is not implemented. + - 1: the Group 1 (tableau access) methods are implemented. + - 2: the Group 2 (pivoting) methods are implemented + + The codes are cumulative - a solver which implements Group 2 also + implements Group 1. + */ + virtual int canDoSimplexInterface() const ; + //@} + + /*! \name OsiSimplex Group 1 + \brief Tableau access methods. + + This group of methods provides access to rows and columns of the basis + inverse and to rows and columns of the tableau. + */ + //@{ + + /*! \brief Prepare the solver for the use of tableau access methods. + + Prepares the solver for the use of the tableau access methods, if + any such preparation is required. + + The \c const attribute is required due to the places this method + may be called (e.g., within CglCutGenerator::generateCuts()). + */ + virtual void enableFactorization() const ; + + /*! \brief Undo the effects of #enableFactorization. */ + virtual void disableFactorization() const ; + + /*! \brief Check if an optimal basis is available. + + Returns true if the problem has been solved to optimality and a + basis is available. This should be used to see if the tableau access + operations are possible and meaningful. + + \note + Implementors please note that this method may be called + before #enableFactorization. + */ + virtual bool basisIsAvailable() const ; + + /// Synonym for #basisIsAvailable + inline bool optimalBasisIsAvailable() const { return basisIsAvailable() ; } + + /*! \brief Retrieve status information for column and row variables. + + This method returns status as integer codes: + <ul> + <li> 0: free + <li> 1: basic + <li> 2: nonbasic at upper bound + <li> 3: nonbasic at lower bound + </ul> + + The #getWarmStart method provides essentially the same functionality + for a simplex-oriented solver, but the implementation details are very + different. + + \note + Logical variables associated with rows are all assumed to have +1 + coefficients, so for a <= constraint the logical will be at lower + bound if the constraint is tight. + + \note + Implementors may choose to implement this method as a wrapper which + converts a CoinWarmStartBasis to the requested representation. + */ + virtual void getBasisStatus(int* cstat, int* rstat) const ; + + /*! \brief Set the status of column and row variables and update + the basis factorization and solution. + + Status information should be coded as documented for #getBasisStatus. + Returns 0 if all goes well, 1 if something goes wrong. + + This method differs from #setWarmStart in the format of the input + and in its immediate effect. Think of it as #setWarmStart immediately + followed by #resolve, but no pivots are allowed. + + \note + Implementors may choose to implement this method as a wrapper that calls + #setWarmStart and #resolve if the no pivot requirement can be satisfied. + */ + virtual int setBasisStatus(const int* cstat, const int* rstat) ; + + /*! \brief Calculate duals and reduced costs for the given objective + coefficients. + + The solver's objective coefficient vector is not changed. + */ + virtual void getReducedGradient(double* columnReducedCosts, + double* duals, const double* c) const ; + + /*! \brief Get a row of the tableau + + If \p slack is not null, it will be loaded with the coefficients for + the artificial (logical) variables (i.e., the row of the basis inverse). + */ + virtual void getBInvARow(int row, double* z, double* slack = NULL) const ; + + /*! \brief Get a row of the basis inverse */ + virtual void getBInvRow(int row, double* z) const ; + + /*! \brief Get a column of the tableau */ + virtual void getBInvACol(int col, double* vec) const ; + + /*! \brief Get a column of the basis inverse */ + virtual void getBInvCol(int col, double* vec) const ; + + /*! \brief Get indices of basic variables + + If the logical (artificial) for row i is basic, the index should be coded + as (#getNumCols + i). + The order of indices must match the order of elements in the vectors + returned by #getBInvACol and #getBInvCol. + */ + virtual void getBasics(int* index) const ; + + //@} + + /*! \name OsiSimplex Group 2 + \brief Pivoting methods + + This group of methods provides for control of individual pivots by a + simplex solver. + */ + //@{ + + /**Enables normal operation of subsequent functions. + This method is supposed to ensure that all typical things (like + reduced costs, etc.) are updated when individual pivots are executed + and can be queried by other methods. says whether will be + doing primal or dual + */ + virtual void enableSimplexInterface(bool doingPrimal) ; + + ///Undo whatever setting changes the above method had to make + virtual void disableSimplexInterface() ; + /** Perform a pivot by substituting a colIn for colOut in the basis. + The status of the leaving variable is given in outStatus. Where + 1 is to upper bound, -1 to lower bound + Return code was undefined - now for OsiClp is 0 for okay, + 1 if inaccuracy forced re-factorization (should be okay) and + -1 for singular factorization + */ + virtual int pivot(int colIn, int colOut, int outStatus) ; + + /** Obtain a result of the primal pivot + Outputs: colOut -- leaving column, outStatus -- its status, + t -- step size, and, if dx!=NULL, *dx -- primal ray direction. + Inputs: colIn -- entering column, sign -- direction of its change (+/-1). + Both for colIn and colOut, artificial variables are index by + the negative of the row index minus 1. + Return code (for now): 0 -- leaving variable found, + -1 -- everything else? + Clearly, more informative set of return values is required + Primal and dual solutions are updated + */ + virtual int primalPivotResult(int colIn, int sign, + int& colOut, int& outStatus, + double& t, CoinPackedVector* dx); + + /** Obtain a result of the dual pivot (similar to the previous method) + Differences: entering variable and a sign of its change are now + the outputs, the leaving variable and its statuts -- the inputs + If dx!=NULL, then *dx contains dual ray + Return code: same + */ + virtual int dualPivotResult(int& colIn, int& sign, + int colOut, int outStatus, + double& t, CoinPackedVector* dx) ; + //@} + + //--------------------------------------------------------------------------- + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSolverInterface(); + + /** Clone + + The result of calling clone(false) is defined to be equivalent to + calling the default constructor OsiSolverInterface(). + */ + virtual OsiSolverInterface * clone(bool copyData = true) const = 0; + + /// Copy constructor + OsiSolverInterface(const OsiSolverInterface &); + + /// Assignment operator + OsiSolverInterface & operator=(const OsiSolverInterface& rhs); + + /// Destructor + virtual ~OsiSolverInterface (); + + /** Reset the solver interface. + + A call to reset() returns the solver interface to the same state as + it would have if it had just been constructed by calling the default + constructor OsiSolverInterface(). + */ + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to the constraint matrix). */ + virtual void applyRowCut( const OsiRowCut & rc ) = 0; + + /** Apply a column cut (adjust the bounds of one or more variables). */ + virtual void applyColCut( const OsiColCut & cc ) = 0; + + /** A quick inlined function to convert from the lb/ub style of + constraint definition to the sense/rhs/range style */ + inline void + convertBoundToSense(const double lower, const double upper, + char& sense, double& right, double& range) const; + /** A quick inlined function to convert from the sense/rhs/range style + of constraint definition to the lb/ub style */ + inline void + convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const; + /** A quick inlined function to force a value to be between a minimum and + a maximum value */ + template <class T> inline T + forceIntoRange(const T value, const T lower, const T upper) const { + return value < lower ? lower : (value > upper ? upper : value); + } + /** Set OsiSolverInterface object state for default constructor + + This routine establishes the initial values of data fields in the + OsiSolverInterface object when the object is created using the + default constructor. + */ + void setInitialData(); + //@} + + ///@name Protected member data + //@{ + /*! \brief Pointer to row cut debugger object + + Mutable so that we can update the solution held in the debugger while + maintaining const'ness for the Osi object. + */ + mutable OsiRowCutDebugger * rowCutDebugger_; + // Why not just make useful stuff protected? + /// Message handler + CoinMessageHandler * handler_; + /** Flag to say if the currrent handler is the default handler. + Indicates if the solver interface object is responsible + for destruction of the handler (true) or if the client is + responsible (false). + */ + bool defaultHandler_; + /// Messages + CoinMessages messages_; + /// Number of integers + int numberIntegers_; + /// Total number of objects + int numberObjects_; + + /// Integer and ... information (integer info normally at beginning) + OsiObject ** object_; + /** Column type + 0 - continuous + 1 - binary (may get fixed later) + 2 - general integer (may get fixed later) + */ + mutable char * columnType_; + + //@} + + //--------------------------------------------------------------------------- + +private: + ///@name Private member data + //@{ + /// Pointer to user-defined data structure - and more if user wants + OsiAuxInfo * appDataEtc_; + /// Array of integer parameters + int intParam_[OsiLastIntParam]; + /// Array of double parameters + double dblParam_[OsiLastDblParam]; + /// Array of string parameters + std::string strParam_[OsiLastStrParam]; + /// Array of hint parameters + bool hintParam_[OsiLastHintParam]; + /// Array of hint strengths + OsiHintStrength hintStrength_[OsiLastHintParam]; + /** Warm start information used for hot starts when the default + hot start implementation is used. */ + CoinWarmStart* ws_; + /// Column solution satisfying lower and upper column bounds + std::vector<double> strictColSolution_; + + /// Row names + OsiNameVec rowNames_ ; + /// Column names + OsiNameVec colNames_ ; + /// Objective name + std::string objName_ ; + + //@} +}; + +//############################################################################# +/** A quick inlined function to convert from the lb/ub style of constraint + definition to the sense/rhs/range style */ +inline void +OsiSolverInterface::convertBoundToSense(const double lower, const double upper, + char& sense, double& right, + double& range) const +{ + double inf = getInfinity(); + range = 0.0; + if (lower > -inf) { + if (upper < inf) { + right = upper; + if (upper==lower) { + sense = 'E'; + } else { + sense = 'R'; + range = upper - lower; + } + } else { + sense = 'G'; + right = lower; + } + } else { + if (upper < inf) { + sense = 'L'; + right = upper; + } else { + sense = 'N'; + right = 0.0; + } + } +} + +//----------------------------------------------------------------------------- +/** A quick inlined function to convert from the sense/rhs/range style of + constraint definition to the lb/ub style */ +inline void +OsiSolverInterface::convertSenseToBound(const char sense, const double right, + const double range, + double& lower, double& upper) const +{ + double inf=getInfinity(); + switch (sense) { + case 'E': + lower = upper = right; + break; + case 'L': + lower = -inf; + upper = right; + break; + case 'G': + lower = right; + upper = inf; + break; + case 'R': + lower = right - range; + upper = right; + break; + case 'N': + lower = -inf; + upper = inf; + break; + } +} + +#endif diff --git a/thirdparty/linux/include/coin1/OsiSolverParameters.hpp b/thirdparty/linux/include/coin1/OsiSolverParameters.hpp new file mode 100644 index 0000000..5f607f5 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiSolverParameters.hpp @@ -0,0 +1,142 @@ +// Copyright (C) 2000, International Business Machines +// Corporation and others. All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +#ifndef OsiSolverParameters_H +#define OsiSolverParameters_H + +enum OsiIntParam { + /*! \brief Iteration limit for initial solve and resolve. + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the OsiSolverinterface::initialSolve() + and OsiSolverinterface::resolve() methods before terminating. + */ + OsiMaxNumIteration = 0, + /*! \brief Iteration limit for hot start + + The maximum number of iterations (whatever that means for the given + solver) the solver can execute in the + OsiSolverinterface::solveFromHotStart() method before terminating. + */ + OsiMaxNumIterationHotStart, + /*! \brief Handling of row and column names. + + The name discipline specifies how the solver will handle row and column + names: + - 0: Auto names: Names cannot be set by the client. Names of the form + Rnnnnnnn or Cnnnnnnn are generated on demand when a name for a + specific row or column is requested; nnnnnnn is derived from the row + or column index. Requests for a vector of names return a vector with + zero entries. + - 1: Lazy names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to the largest index of a name supplied by the client; + some entries in the vector may be null strings. + - 2: Full names: Names supplied by the client are retained. Names of the + form Rnnnnnnn or Cnnnnnnn are generated on demand if no name has been + supplied by the client. Requests for a vector of names return a + vector sized to match the constraint system, and all entries will + contain either the name specified by the client or a generated name. + */ + OsiNameDiscipline, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + integer parameters. + */ + OsiLastIntParam +} ; + +enum OsiDblParam { + /*! \brief Dual objective limit. + + This is to be used as a termination criteria in algorithms where the dual + objective changes monotonically (e.g., dual simplex, volume algorithm). + */ + OsiDualObjectiveLimit = 0, + /*! \brief Primal objective limit. + + This is to be used as a termination criteria in algorithms where the + primal objective changes monotonically (e.g., primal simplex) + */ + OsiPrimalObjectiveLimit, + /*! \brief Dual feasibility tolerance. + + The maximum amount a dual constraint can be violated and still be + considered feasible. + */ + OsiDualTolerance, + /*! \brief Primal feasibility tolerance. + + The maximum amount a primal constraint can be violated and still be + considered feasible. + */ + OsiPrimalTolerance, + /** The value of any constant term in the objective function. */ + OsiObjOffset, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + double parameters. + */ + OsiLastDblParam +}; + + +enum OsiStrParam { + /*! \brief The name of the loaded problem. + + This is the string specified on the Name card of an mps file. + */ + OsiProbName = 0, + /*! \brief The name of the solver. + + This parameter is read-only. + */ + OsiSolverName, + /*! \brief End marker. + + Used by OsiSolverInterface to allocate a fixed-sized array to store + string parameters. + */ + OsiLastStrParam +}; + +enum OsiHintParam { + /** Whether to do a presolve in initialSolve */ + OsiDoPresolveInInitial = 0, + /** Whether to use a dual algorithm in initialSolve. + The reverse is to use a primal algorithm */ + OsiDoDualInInitial, + /** Whether to do a presolve in resolve */ + OsiDoPresolveInResolve, + /** Whether to use a dual algorithm in resolve. + The reverse is to use a primal algorithm */ + OsiDoDualInResolve, + /** Whether to scale problem */ + OsiDoScale, + /** Whether to create a non-slack basis (only in initialSolve) */ + OsiDoCrash, + /** Whether to reduce amount of printout, e.g., for branch and cut */ + OsiDoReducePrint, + /** Whether we are in branch and cut - so can modify behavior */ + OsiDoInBranchAndCut, + /** Just a marker, so that OsiSolverInterface can allocate a static sized + array to store parameters. */ + OsiLastHintParam +}; + +enum OsiHintStrength { + /** Ignore hint (default) */ + OsiHintIgnore = 0, + /** This means it is only a hint */ + OsiHintTry, + /** This means do hint if at all possible */ + OsiHintDo, + /** And this means throw an exception if not possible */ + OsiForceDo +}; + +#endif diff --git a/thirdparty/linux/include/coin1/OsiSymSolverInterface.hpp b/thirdparty/linux/include/coin1/OsiSymSolverInterface.hpp new file mode 100644 index 0000000..46f6514 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiSymSolverInterface.hpp @@ -0,0 +1,806 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef OsiSymSolverInterface_hpp +#define OsiSymSolverInterface_hpp + +#include "OsiSolverInterface.hpp" +#include "OsiSymSolverParameters.hpp" +#include "SymWarmStart.hpp" + +#include <string> + +typedef struct SYM_ENVIRONMENT sym_environment; + +//############################################################################# + +/** OSI Solver Interface for SYMPHONY + + Many OsiSolverInterface query methods return a const pointer to the + requested read-only data. If the model data is changed or the solver + is called, these pointers may no longer be valid and should be + refreshed by invoking the member function to obtain an updated copy + of the pointer. + For example: + \code + OsiSolverInterface solverInterfacePtr ; + const double * ruBnds = solverInterfacePtr->getRowUpper(); + solverInterfacePtr->applyCuts(someSetOfCuts); + // ruBnds is no longer a valid pointer and must be refreshed + ruBnds = solverInterfacePtr->getRowUpper(); + \endcode + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. +*/ + +class OsiSymSolverInterface : virtual public OsiSolverInterface { + friend void OsiSymSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +public: + ///@name Solve methods + //@{ + /// Solve initial LP relaxation + virtual void initialSolve(); + + /// Resolve an IP problem modification + virtual void resolve(); + + /// Invoke solver's built-in enumeration algorithm + virtual void branchAndBound(); + + /// Invoke solver's multi-criteria enumeration algorithm + virtual void multiCriteriaBranchAndBound(); + + /// Get a lower bound for the new rhs problem using the warm start tree. + virtual double getLbForNewRhs(int cnt, int *index, + double * value); + /// Get an upper bound for the new rhs problem using the warm start tree. + virtual double getUbForNewRhs(int cnt, int *index, + double * value); +#if 0 + /// Get a lower bound for the new obj problem using the warm start tree. + virtual double getLbForNewObj(int cnt, int *index, + double * value); + /// Get an upper bound for the new obj problem using the warm start tree. +#endif + virtual double getUbForNewObj(int cnt, int *index, + double * value); + + //@} + + //--------------------------------------------------------------------------- + /**@name Parameter set/get methods + + The set methods return true if the parameter was set to the given value, + false otherwise. There can be various reasons for failure: the given + parameter is not applicable for the solver (e.g., refactorization + frequency for the volume algorithm), the parameter is not yet implemented + for the solver or simply the value of the parameter is out of the range + the solver accepts. If a parameter setting call returns false check the + details of your solver. + + The get methods return true if the given parameter is applicable for the + solver and is implemented. In this case the value of the parameter is + returned in the second argument. Otherwise they return false. + + */ + //@{ + // Set an integer parameter + virtual bool setIntParam(OsiIntParam key, int value); + + // Set SYMPHONY int parameter + virtual bool setSymParam(OsiSymIntParam key, int value); + + // Set SYMPHONY int parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, int value); + + + // Set an double parameter + virtual bool setDblParam(OsiDblParam key, double value); + + // Set SYMPHONY double parameter + virtual bool setSymParam(OsiSymDblParam key, double value); + + // Set SYMPHONY double parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, double value); + + + + // Set a string parameter + virtual bool setStrParam(OsiStrParam key, const std::string & value); + + // Set SYMPHONY string parameter + virtual bool setSymParam(OsiSymStrParam key, const std::string & value); + + // Set SYMPHONY string parameter directly by the C interface parameter name + virtual bool setSymParam(const std::string key, const std::string value); + + + + // Get an integer parameter + virtual bool getIntParam(OsiIntParam key, int& value) const; + + // Get SYMPHONY int parameter + virtual bool getSymParam(OsiSymIntParam key, int& value) const; + + // Get SYMPHONY int parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, int& value) const; + + + // Get an double parameter + virtual bool getDblParam(OsiDblParam key, double& value) const; + + // Get SYMPHONY double parameter + virtual bool getSymParam(OsiSymDblParam key, double& value) const; + + // Get SYMPHONY double parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, double& value) const; + + + + // Get a string parameter + virtual bool getStrParam(OsiStrParam key, std::string& value) const; + + // Get SYMPHONY string parameter + virtual bool getSymParam(OsiSymStrParam key, std::string& value) const; + + // Get SYMPHONY string parameter directly by the C interface parameter name + virtual bool getSymParam(const std::string key, std::string& value) const; + + //@} + + //--------------------------------------------------------------------------- + ///@name Methods returning info on how the solution process terminated + //@{ + /// Are there numerical difficulties? + virtual bool isAbandoned() const; + + /// Is optimality proven? + virtual bool isProvenOptimal() const; + + /// Is primal infeasiblity proven? + virtual bool isProvenPrimalInfeasible() const; + + /// Is dual infeasiblity proven? + virtual bool isProvenDualInfeasible() const { + throw CoinError("Error: Function not implemented", + "isProvenDualInfeasible", "OsiSymSolverInterface"); + } + /// Is the given primal objective limit reached? + //virtual bool isPrimalObjectiveLimitReached() const; + + /// Is the given dual objective limit reached? + //virtual bool isDualObjectiveLimitReached() const{ + // throw CoinError("Error: Function not implemented", + // "isDualObjectiveLimitReached", "OsiSymSolverInterface"); + //} + /// Iteration limit reached? + virtual bool isIterationLimitReached() const; + + /// Time limit reached? + virtual bool isTimeLimitReached() const; + + /// Target gap achieved? + virtual bool isTargetGapReached() const; + + //@} + + //--------------------------------------------------------------------------- + /**@name Warm start methods */ + //@{ + /*! \brief Get an empty warm start object + + This routine returns an empty warm start object. Its purpose is + to provide a way to give a client a warm start object of the + appropriate type, which can resized and modified as desired. + */ + + virtual CoinWarmStart *getEmptyWarmStart () const{ + throw CoinError("Error: Function not implemented", + "getEmptyWarmStart", "OsiSymSolverInterface"); + } + + /** Get warm start information. + + If there is no valid solution, an empty warm start object (0 rows, 0 + columns) wil be returned. + */ + + /* + virtual CoinWarmStart* getWarmStart(bool keepTreeInSymEnv = false) const; + */ + + virtual CoinWarmStart* getWarmStart() const; + + /** Set warm start information. + + Return true/false depending on whether the warm start information was + accepted or not. */ + virtual bool setWarmStart(const CoinWarmStart* warmstart); + //@} + + //--------------------------------------------------------------------------- + /**@name Problem query methods + + Querying a problem that has no data associated with it will result in + zeros for the number of rows and columns, and NULL pointers from + the methods that return vectors. + + Const pointers returned from any data-query method are valid as + long as the data is unchanged and the solver is not called. + */ + //@{ + /// Get pointer to SYMPHONY environment (eventually we won't need this) + sym_environment *getSymphonyEnvironment() const {return env_;} + + /// Get number of columns + virtual int getNumCols() const; + + /// Get number of rows + virtual int getNumRows() const; + + /// Get number of nonzero elements + virtual int getNumElements() const; + + /// Get pointer to array[getNumCols()] of column lower bounds + virtual const double * getColLower() const; + + /// Get pointer to array[getNumCols()] of column upper bounds + virtual const double * getColUpper() const; + + /** Get pointer to array[getNumRows()] of row constraint senses. + <ul> + <li>'L': <= constraint + <li>'E': = constraint + <li>'G': >= constraint + <li>'R': ranged constraint + <li>'N': free constraint + </ul> + */ + virtual const char * getRowSense() const; + + /** Get pointer to array[getNumRows()] of row right-hand sides + <ul> + <li> if getRowSense()[i] == 'L' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'G' then + getRightHandSide()[i] == getRowLower()[i] + <li> if getRowSense()[i] == 'R' then + getRightHandSide()[i] == getRowUpper()[i] + <li> if getRowSense()[i] == 'N' then + getRightHandSide()[i] == 0.0 + </ul> + */ + virtual const double * getRightHandSide() const; + + /** Get pointer to array[getNumRows()] of row ranges. + <ul> + <li> if getRowSense()[i] == 'R' then + getRowRange()[i] == getRowUpper()[i] - getRowLower()[i] + <li> if getRowSense()[i] != 'R' then + getRowRange()[i] is 0.0 + </ul> + */ + virtual const double * getRowRange() const; + + /// Get pointer to array[getNumRows()] of row lower bounds + virtual const double * getRowLower() const; + + /// Get pointer to array[getNumRows()] of row upper bounds + virtual const double * getRowUpper() const; + + /// Get pointer to array[getNumCols()] of objective function coefficients + virtual const double * getObjCoefficients() const; + + /** Get pointer to array[getNumCols()] of second + objective function coefficients if loaded before. + */ + virtual const double * getObj2Coefficients() const; + + /// Get objective function sense (1 for min (default), -1 for max) + virtual double getObjSense() const; + + /// Return true if variable is continuous + virtual bool isContinuous(int colIndex) const; + + /// Return true if variable is binary + virtual bool isBinary(int colIndex) const; + + /** Return true if column is integer. + Note: This function returns true if the the column + is binary or a general integer. + */ + virtual bool isInteger(int colIndex) const; + + /// Return true if variable is general integer + virtual bool isIntegerNonBinary(int colIndex) const; + + /// Return true if variable is binary and not fixed at either bound + virtual bool isFreeBinary(int colIndex) const; + + /// Get pointer to row-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByRow() const; + + /// Get pointer to column-wise copy of matrix + virtual const CoinPackedMatrix * getMatrixByCol() const; + + /// Get solver's value for infinity + virtual double getInfinity() const; + + //@} + + /**@name Solution query methods */ + //@{ + /// Get pointer to array[getNumCols()] of primal variable values + virtual const double * getColSolution() const; + + /// Get pointer to array[getNumRows()] of dual variable values + virtual const double * getRowPrice() const; + + /// Get a pointer to array[getNumCols()] of reduced costs + virtual const double * getReducedCost() const; + + /** Get pointer to array[getNumRows()] of row activity levels (constraint + matrix times the solution vector). */ + virtual const double * getRowActivity() const; + + /// Get objective function value + virtual double getObjValue() const; + + /// Get the current upper/lower bound + virtual double getPrimalBound() const; + + /** Get the number of iterations it took to solve the problem (whatever + ``iteration'' means to the solver). */ + virtual int getIterationCount() const; + + /** Get as many dual rays as the solver can provide. In case of proven + primal infeasibility there should be at least one. + + \note + Implementors of solver interfaces note that + the double pointers in the vector should point to arrays of length + getNumRows() and they should be allocated via new[]. + + \note + Clients of solver interfaces note that + it is the client's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getDualRays(int maxNumRays, + bool fullRay = false) const{ + throw CoinError("Error: Function not implemented", + "getDualRays", "OsiSymSolverInterface"); + } + /** Get as many primal rays as the solver can provide. (In case of proven + dual infeasibility there should be at least one.) + + <strong>NOTE for implementers of solver interfaces:</strong> <br> + The double pointers in the vector should point to arrays of length + getNumCols() and they should be allocated via new[]. <br> + + <strong>NOTE for users of solver interfaces:</strong> <br> + It is the user's responsibility to free the double pointers in the + vector using delete[]. + */ + virtual std::vector<double*> getPrimalRays(int maxNumRays) const{ + throw CoinError("Error: Function not implemented", + "getPrimalRays", "OsiSymSolverInterface"); + } + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to modify the objective, bounds, and solution + + For functions which take a set of indices as parameters + (\c setObjCoeffSet(), \c setColSetBounds(), \c setRowSetBounds(), + \c setRowSetTypes()), the parameters follow the C++ STL iterator + convention: \c indexFirst points to the first index in the + set, and \c indexLast points to a position one past the last index + in the set. + + */ + //@{ + /** Set an objective function coefficient */ + virtual void setObjCoeff( int elementIndex, double elementValue ); + + /** Set an objective function coefficient for the second objective */ + virtual void setObj2Coeff( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColLower ; + /** Set a single column lower bound. + Use -getInfinity() for -infinity. */ + virtual void setColLower( int elementIndex, double elementValue ); + + using OsiSolverInterface::setColUpper ; + /** Set a single column upper bound. + Use getInfinity() for infinity. */ + virtual void setColUpper( int elementIndex, double elementValue ); + + /** Set a single row lower bound. + Use -getInfinity() for -infinity. */ + virtual void setRowLower( int elementIndex, double elementValue ); + + /** Set a single row upper bound. + Use getInfinity() for infinity. */ + virtual void setRowUpper( int elementIndex, double elementValue ); + + /** Set the type of a single row */ + virtual void setRowType(int index, char sense, double rightHandSide, + double range); + + /// Set the objective function sense. + /// (1 for min (default), -1 for max) + virtual void setObjSense(double s); + + /** Set the primal solution variable values + + colsol[getNumCols()] is an array of values for the primal variables. + These values are copied to memory owned by the solver interface object + or the solver. They will be returned as the result of getColSolution() + until changed by another call to setColSolution() or by a call to any + solver routine. Whether the solver makes use of the solution in any + way is solver-dependent. + */ + virtual void setColSolution(const double *colsol); + + /** Set the a priori upper/lower bound */ + + virtual void setPrimalBound(const double bound); + + /** Set dual solution variable values + + rowprice[getNumRows()] is an array of values for the dual + variables. These values are copied to memory owned by the solver + interface object or the solver. They will be returned as the result of + getRowPrice() until changed by another call to setRowPrice() or by a + call to any solver routine. Whether the solver makes use of the + solution in any way is solver-dependent. + */ + + virtual void setRowPrice(const double * rowprice); + + //@} + + //------------------------------------------------------------------------- + /**@name Methods to set variable type */ + //@{ + + using OsiSolverInterface::setContinuous ; + /** Set the index-th variable to be a continuous variable */ + virtual void setContinuous(int index); + + using OsiSolverInterface::setInteger ; + /** Set the index-th variable to be an integer variable */ + virtual void setInteger(int index); + + + using OsiSolverInterface::setColName ; + virtual void setColName(char **colname); + + //@} + //------------------------------------------------------------------------- + + //------------------------------------------------------------------------- + /**@name Methods to expand a problem. + + Note that new columns are added as continuous variables. + + */ + //@{ + + using OsiSolverInterface::addCol ; + /** Add a column (primal variable) to the problem. */ + virtual void addCol(const CoinPackedVectorBase& vec, + const double collb, const double colub, + const double obj); + + /** Remove a set of columns (primal variables) from the problem. */ + virtual void deleteCols(const int num, const int * colIndices); + + using OsiSolverInterface::addRow ; + /** Add a row (constraint) to the problem. */ + virtual void addRow(const CoinPackedVectorBase& vec, + const double rowlb, const double rowub); + /** */ + virtual void addRow(const CoinPackedVectorBase& vec, + const char rowsen, const double rowrhs, + const double rowrng); + + /** Delete a set of rows (constraints) from the problem. */ + virtual void deleteRows(const int num, const int * rowIndices); + + //@} + + //--------------------------------------------------------------------------- + + /**@name Methods to input a problem */ + //@{ + + virtual void loadProblem(); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by lower and upper bounds). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>rowub</code>: all rows have upper bound infinity + <li> <code>rowlb</code>: all rows have lower bound -infinity + <li> <code>obj</code>: all variables have 0 objective coefficient + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by lower and upper bounds). + For default values see the previous method. + + \warning + The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + double*& rowlb, double*& rowub); + + /** Load in an problem by copying the arguments (the constraints on the + rows are given by sense/rhs/range triplets). If a pointer is 0 then the + following values are the default: + <ul> + <li> <code>colub</code>: all columns have upper bound infinity + <li> <code>collb</code>: all columns have lower bound 0 + <li> <code>obj</code>: all variables have 0 objective coefficient + <li> <code>rowsen</code>: all rows are >= + <li> <code>rowrhs</code>: all right hand sides are 0 + <li> <code>rowrng</code>: 0 for the ranged rows + </ul> + */ + virtual void loadProblem(const CoinPackedMatrix& matrix, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Load in an problem by assuming ownership of the arguments (the + constraints on the rows are given by sense/rhs/range triplets). For + default values see the previous method. + + \warning + The arguments passed to this method will be + freed using the C++ <code>delete</code> and <code>delete[]</code> + functions. + */ + virtual void assignProblem(CoinPackedMatrix*& matrix, + double*& collb, double*& colub, double*& obj, + char*& rowsen, double*& rowrhs, + double*& rowrng); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const double* rowlb, const double* rowub); + + /** Just like the other loadProblem() methods except that the matrix is + given in a standard column major ordered format (without gaps). */ + virtual void loadProblem(const int numcols, const int numrows, + const CoinBigIndex * start, const int* index, + const double* value, + const double* collb, const double* colub, + const double* obj, + const char* rowsen, const double* rowrhs, + const double* rowrng); + + /** Write the problem in MPS format to the specified file. + + If objSense is non-zero, a value of -1.0 causes the problem to be + written with a maximization objective; +1.0 forces a minimization + objective. If objSense is zero, the choice is left to implementation. + */ + virtual void writeMps(const char *filename, + const char *extension = "mps", + double objSense=0.0) const; + + void parseCommandLine(int argc, char **argv); + + using OsiSolverInterface::readMps ; + virtual int readMps(const char * infile, const char *extension = "mps"); + + virtual int readGMPL(const char * modelFile, const char * dataFile=NULL); + + void findInitialBounds(); + + int createPermanentCutPools(); + + //@} + + //--------------------------------------------------------------------------- + + enum keepCachedFlag { + /// discard all cached data (default) + KEEPCACHED_NONE = 0, + /// column information: objective values, lower and upper bounds, variable types + KEEPCACHED_COLUMN = 1, + /// row information: right hand sides, ranges and senses, lower and upper bounds for row + KEEPCACHED_ROW = 2, + /// problem matrix: matrix ordered by column and by row + KEEPCACHED_MATRIX = 4, + /// LP solution: primal and dual solution, reduced costs, row activities + KEEPCACHED_RESULTS = 8, + /// only discard cached LP solution + KEEPCACHED_PROBLEM = KEEPCACHED_COLUMN | KEEPCACHED_ROW | KEEPCACHED_MATRIX, + /// keep all cached data (similar to getMutableLpPtr()) + KEEPCACHED_ALL = KEEPCACHED_PROBLEM | KEEPCACHED_RESULTS, + /// free only cached column and LP solution information + FREECACHED_COLUMN = KEEPCACHED_PROBLEM & ~KEEPCACHED_COLUMN, + /// free only cached row and LP solution information + FREECACHED_ROW = KEEPCACHED_PROBLEM & ~KEEPCACHED_ROW, + /// free only cached matrix and LP solution information + FREECACHED_MATRIX = KEEPCACHED_PROBLEM & ~KEEPCACHED_MATRIX, + /// free only cached LP solution information + FREECACHED_RESULTS = KEEPCACHED_ALL & ~KEEPCACHED_RESULTS + }; + + ///@name Constructors and destructors + //@{ + /// Default Constructor + OsiSymSolverInterface(); + + /** Clone + + The result of calling clone(false) is defined to be equivalent to + calling the default constructor OsiSolverInterface(). + */ + virtual OsiSolverInterface * clone(bool copyData = true) const; + + /// Copy constructor + OsiSymSolverInterface(const OsiSymSolverInterface &); + + /// Assignment operator + OsiSymSolverInterface & operator=(const OsiSymSolverInterface& rhs); + + /// Destructor + virtual ~OsiSymSolverInterface (); + + /** Reset the solver interface. + + A call to reset() returns the solver interface to the same state as + it would have if it had just been constructed by calling the default + constructor OsiSolverInterface(). + */ + virtual void reset(); + //@} + + //--------------------------------------------------------------------------- + +protected: + ///@name Protected methods + //@{ + /** Apply a row cut (append to the constraint matrix). */ + virtual void applyRowCut( const OsiRowCut & rc ); + + /** Apply a column cut (adjust the bounds of one or more variables). */ + virtual void applyColCut( const OsiColCut & cc ); + + /** Set OsiSolverInterface object state for default constructor + + This routine establishes the initial values of data fields in the + OsiSolverInterface object when the object is created using the + default constructor. + */ + + void setInitialData(); + //@} + +private: + + /// The real work of the constructor + void gutsOfConstructor(); + + /// The real work of the destructor + void gutsOfDestructor(); + + /// free cached column rim vectors + void freeCachedColRim(); + + /// free cached row rim vectors + void freeCachedRowRim(); + + /// free cached result vectors + void freeCachedResults(); + + /// free cached matrices + void freeCachedMatrix(); + + /// free all cached data (except specified entries, see getLpPtr()) + void freeCachedData( int keepCached = KEEPCACHED_NONE ); + + /// free all allocated memory + void freeAllMemory(); + + /**@name Private member data */ + //@{ + /// The pointer to the SYMPHONY problem environment + sym_environment *env_; + //@} + + /// Pointer to objective vector + mutable double *obj_; + + /// Pointer to second objective vector to be used in bicriteria solver + mutable double *obj2_; + + /// Pointer to dense vector of variable lower bounds + mutable double *collower_; + + /// Pointer to dense vector of variable lower bounds + mutable double *colupper_; + + /// Pointer to dense vector of variable lower bounds + mutable double *colredcost_; + + /// Pointer to dense vector of row sense indicators + mutable char *rowsense_; + + /// Pointer to dense vector of row right-hand side values + mutable double *rhs_; + + /** Pointer to dense vector of slack upper bounds for range constraints + (undefined for non-range rows) + */ + mutable double *rowrange_; + + /// Pointer to dense vector of row lower bounds + mutable double *rowlower_; + + /// Pointer to dense vector of row upper bounds + mutable double *rowupper_; + + /// Pointer to dense vector of row prices + mutable double *rowprice_; + + /// Pointer to primal solution vector + mutable double *colsol_; + + /// Pointer to row activity (slack) vector + mutable double *rowact_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByRow_; + + /// Pointer to row-wise copy of problem matrix coefficients. + mutable CoinPackedMatrix *matrixByCol_; + +}; + +//############################################################################# +/** A function that tests the methods in the OsiSymSolverInterface class. */ +void OsiSymSolverInterfaceUnitTest(const std::string & mpsDir, const std::string & netlibDir); + +#endif diff --git a/thirdparty/linux/include/coin1/OsiSymSolverParameters.hpp b/thirdparty/linux/include/coin1/OsiSymSolverParameters.hpp new file mode 100644 index 0000000..041acce --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiSymSolverParameters.hpp @@ -0,0 +1,64 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef OsiSymSolverParameters_hpp +#define OsiSymSolverParameters_hpp + +enum OsiSymIntParam { + /** This controls the level of output */ + OsiSymMaxActiveNodes, + OsiSymVerbosity, + OsiSymNodeLimit, + OsiSymFindFirstFeasible, + OsiSymSearchStrategy, + OsiSymUsePermanentCutPools, + OsiSymKeepWarmStart, + OsiSymDoReducedCostFixing, + OsiSymMCFindSupportedSolutions, + OsiSymSensitivityAnalysis, + OsiSymRandomSeed, + OsiSymDivingStrategy, + OsiSymDivingK, + OsiSymDivingThreshold, + OsiSymTrimWarmTree, + OsiSymGenerateCglGomoryCuts, + OsiSymGenerateCglKnapsackCuts, + OsiSymGenerateCglOddHoleCuts, + OsiSymGenerateCglProbingCuts, + OsiSymGenerateCglFlowAndCoverCuts, + OsiSymGenerateCglRoundingCuts, + OsiSymGenerateCglLiftAndProjectCuts, + OsiSymGenerateCglCliqueCuts +}; + +enum OsiSymDblParam { + /** The granularity is the actual minimum difference in objective function + value for two solutions that actually have do different objective + function values. For integer programs with integral objective function + coefficients, this would be 1, for instance. */ + OsiSymGranularity, + OsiSymTimeLimit, + OsiSymGapLimit, + OsiSymUpperBound, + OsiSymLowerBound +}; + +enum OsiSymStrParam { +}; + +#endif diff --git a/thirdparty/linux/include/coin1/OsiUnitTests.hpp b/thirdparty/linux/include/coin1/OsiUnitTests.hpp new file mode 100644 index 0000000..fbb4fc1 --- /dev/null +++ b/thirdparty/linux/include/coin1/OsiUnitTests.hpp @@ -0,0 +1,374 @@ +// Copyright (C) 2010 +// All Rights Reserved. +// This code is licensed under the terms of the Eclipse Public License (EPL). + +/*! \file OsiUnitTests.hpp + + Utility methods for OSI unit tests. +*/ + +#ifndef OSISOLVERINTERFACETEST_HPP_ +#define OSISOLVERINTERFACETEST_HPP_ + +#include <cstdio> +#include <cstdlib> +#include <iostream> +#include <string> +#include <sstream> +#include <vector> +#include <list> +#include <map> + +class OsiSolverInterface; +class CoinPackedVectorBase; + +/** A function that tests that a lot of problems given in MPS files (mostly the NETLIB problems) solve properly with all the specified solvers. + * + * The routine creates a vector of NetLib problems (problem name, objective, + * various other characteristics), and a vector of solvers to be tested. + * + * Each solver is run on each problem. The run is deemed successful if the + * solver reports the correct problem size after loading and returns the + * correct objective value after optimization. + + * If multiple solvers are available, the results are compared pairwise against + * the results reported by adjacent solvers in the solver vector. Due to + * limitations of the volume solver, it must be the last solver in vecEmptySiP. + */ +void OsiSolverInterfaceMpsUnitTest + (const std::vector<OsiSolverInterface*> & vecEmptySiP, + const std::string& mpsDir); + +/** A function that tests the methods in the OsiSolverInterface class. + * Some time ago, if this method is compiled with optimization, + * the compilation took 10-15 minutes and the machine pages (has 256M core memory!)... + */ +void OsiSolverInterfaceCommonUnitTest + (const OsiSolverInterface* emptySi, + const std::string& mpsDir, + const std::string& netlibDir); + +/** A function that tests the methods in the OsiColCut class. */ +void OsiColCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCut class. */ +void OsiRowCutUnitTest + (const OsiSolverInterface * baseSiP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiRowCutDebugger class. */ +void OsiRowCutDebuggerUnitTest + (const OsiSolverInterface * siP, + const std::string & mpsDir); + +/** A function that tests the methods in the OsiCuts class. */ +void OsiCutsUnitTest(); + +/// A namespace so we can define a few `global' variables to use during tests. +namespace OsiUnitTest { + +class TestOutcomes; + +/*! \brief Verbosity level of unit tests + + 0 (default) for minimal output; larger numbers produce more output +*/ +extern unsigned int verbosity; + +/*! \brief Behaviour on failing a test + + - 0 (= default) continue + - 1 press any key to continue + - 2 stop with abort() +*/ +extern unsigned int haltonerror; + +/*! \brief Test outcomes + + A global TestOutcomes object to store test outcomes during the run of the unit test + for an OSI. + */ +extern TestOutcomes outcomes; + +/*! \brief Print an error message + + Formatted as "XxxSolverInterface testing issue: message" where Xxx is the string + provided as \p solverName. + + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &message) ; +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &message) ; + +/*! \brief Print an error message, specifying the test name and condition + + Formatted as "XxxSolverInterface testing issue: testname failed: testcond" where + Xxx is the OsiStrParam::OsiSolverName parameter of the \p si. + Flushes std::cout before printing to std::cerr. +*/ +void failureMessage(const std::string &solverName, + const std::string &testname, const std::string &testcond) ; + +/// \overload +void failureMessage(const OsiSolverInterface &si, + const std::string &testname, const std::string &testcond) ; + +/*! \brief Print a message. + + Prints the message as given. Flushes std::cout before printing to std::cerr. +*/ +void testingMessage(const char *const msg) ; + +/*! \brief Utility method to check equality + + Tests for equality using CoinRelFltEq with tolerance \p tol. Understands the + notion of solver infinity and obtains the value for infinity from the solver + interfaces supplied as parameters. +*/ +bool equivalentVectors(const OsiSolverInterface * si1, + const OsiSolverInterface * si2, + double tol, const double * v1, const double * v2, int size) ; + +/*! \brief Compare two problems for equality + + Compares the problems held in the two solvers: constraint matrix, row and column + bounds, column type, and objective. Rows are checked using upper and lower bounds + and using sense, bound, and range. +*/ +bool compareProblems(OsiSolverInterface *osi1, OsiSolverInterface *osi2) ; + +/*! \brief Compare a packed vector with an expanded vector + + Checks that all values present in the packed vector are present in the full vector + and checks that there are no extra entries in the full vector. Uses CoinRelFltEq + with the default tolerance. +*/ +bool isEquivalent(const CoinPackedVectorBase &pv, int n, const double *fv) ; + +/*! \brief Process command line parameters. + + An unrecognised keyword which is not in the \p ignorekeywords map will trigger the + help message and a return value of false. For each keyword in \p ignorekeywords, you + can specify the number of following parameters that should be ignored. + + This should be replaced with the one of the standard CoinUtils parameter mechanisms. + */ +bool processParameters (int argc, const char **argv, + std::map<std::string,std::string>& parms, + const std::map<std::string,int>& ignorekeywords = std::map<std::string,int>()); + +/// A single test outcome record. +class TestOutcome { + public: + /// Test result + typedef enum { + NOTE = 0, + PASSED = 1, + WARNING = 2, + ERROR = 3, + LAST = 4 + } SeverityLevel; + /// Print strings for SeverityLevel + static std::string SeverityLevelName[LAST]; + /// Name of component under test + std::string component; + /// Name of test + std::string testname; + /// Condition being tested + std::string testcond; + /// Test result + SeverityLevel severity; + /// Set to true if problem is expected + bool expected; + /// Name of code file where test executed + std::string filename; + /// Line number in code file where test executed + int linenumber; + /// Standard constructor + TestOutcome(const std::string& comp, const std::string& tst, + const char* cond, SeverityLevel sev, + const char* file, int line, bool exp = false) + : component(comp),testname(tst),testcond(cond),severity(sev), + expected(exp),filename(file),linenumber(line) + { } + /// Print the test outcome + void print() const; +}; + +/// Utility class to maintain a list of test outcomes. +class TestOutcomes : public std::list<TestOutcome> { + public: + /// Add an outcome to the list + void add(std::string comp, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false) + { push_back(TestOutcome(comp,tst,cond,sev,file,line,exp)); } + + /*! \brief Add an outcome to the list + + Get the component name from the solver interface. + */ + void add(const OsiSolverInterface& si, std::string tst, const char* cond, + TestOutcome::SeverityLevel sev, const char* file, int line, + bool exp = false); + /// Print the list of outcomes + void print() const; + /*! \brief Count total and expected outcomes at given severity level + + Given a severity level, walk the list of outcomes and count the total number + of outcomes at this severity level and the number expected. + */ + void getCountBySeverity(TestOutcome::SeverityLevel sev, + int& total, int& expected) const; +}; + +/// Convert parameter to a string (stringification) +#define OSIUNITTEST_QUOTEME_(x) #x +/// Convert to string with one level of expansion of the parameter +#define OSIUNITTEST_QUOTEME(x) OSIUNITTEST_QUOTEME_(x) + +template <typename Component> +bool OsiUnitTestAssertSeverityExpected( + bool condition, const char * condition_str, const char *filename, + int line, const Component& component, const std::string& testname, + TestOutcome::SeverityLevel severity, bool expected) +{ + if (condition) { + OsiUnitTest::outcomes.add(component, testname, condition_str, + OsiUnitTest::TestOutcome::PASSED, filename, line, false); + if (OsiUnitTest::verbosity >= 2) { + std::ostringstream successmsg; + successmsg << __FILE__ << ":" << __LINE__ << ": " << testname + << " (condition \'" << condition_str << "\') passed.\n"; + OsiUnitTest::testingMessage(successmsg.str().c_str()); + } + return true; + } + OsiUnitTest::outcomes.add(component, testname, condition_str, + severity, filename, line, expected); + OsiUnitTest::failureMessage(component, testname, condition_str); + switch (OsiUnitTest::haltonerror) { + case 2: + { if (severity >= OsiUnitTest::TestOutcome::ERROR ) std::abort(); break; } + case 1: + { std::cout << std::endl << "press any key to continue..." << std::endl; + std::getchar(); + break ; } + default: ; + } + return false; +} + +/// Add a test outcome to the list held in OsiUnitTest::outcomes +#define OSIUNITTEST_ADD_OUTCOME(component,testname,testcondition,severity,expected) \ + OsiUnitTest::outcomes.add(component,testname,testcondition,severity,\ + __FILE__,__LINE__,expected) +/*! \brief Test for a condition and record the result + + Test \p condition and record the result in OsiUnitTest::outcomes. + If it succeeds, record the result as OsiUnitTest::TestOutcome::PASSED and print + a message for OsiUnitTest::verbosity >= 2. + If it fails, record the test as failed with \p severity and \p expected and + react as specified by OsiUnitTest::haltonerror. + + \p failurecode is executed when failure is not fatal. +*/ +#define OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,\ + testname, severity, expected) \ +{ \ + if (!OsiUnitTestAssertSeverityExpected(condition, #condition, \ + __FILE__, __LINE__, component, testname, severity, expected)) { \ + failurecode; \ + } \ +} + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::ERROR, failure not + expected. +*/ +#define OSIUNITTEST_ASSERT_ERROR(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::ERROR,false) + +/*! \brief Perform a test with severity OsiUnitTest::TestOutcome::WARNING, failure + not expected. +*/ +#define OSIUNITTEST_ASSERT_WARNING(condition, failurecode, component, testname) \ + OSIUNITTEST_ASSERT_SEVERITY_EXPECTED(condition,failurecode,component,testname,\ + OsiUnitTest::TestOutcome::WARNING,false) + +/*! \brief Perform a test surrounded by a try/catch block + + \p trycode is executed in a try/catch block; if there's no throw the test is deemed + to have succeeded and is recorded in OsiUnitTest::outcomes with status + OsiUnitTest::TestOutcome::PASSED. If the \p trycode throws a CoinError, the failure + is recorded with status \p severity and \p expected and the value of + OsiUnitTest::haltonerror is consulted. If the failure is not fatal, \p catchcode is + executed. If any other error is thrown, the failure is recorded as for a CoinError + and \p catchcode is executed (haltonerror is not consulted). +*/ +#define OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname,\ + severity, expected) \ +{ \ + try { \ + trycode; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,#trycode " did not throw exception",\ + OsiUnitTest::TestOutcome::PASSED,false); \ + if (OsiUnitTest::verbosity >= 2) { \ + std::string successmsg( __FILE__ ":" OSIUNITTEST_QUOTEME(__LINE__) ": "); \ + successmsg = successmsg + testname; \ + successmsg = successmsg + " (code \'" #trycode "\') did not throw exception"; \ + successmsg = successmsg + ".\n" ; \ + OsiUnitTest::testingMessage(successmsg.c_str()); \ + } \ + } catch (CoinError& e) { \ + std::stringstream errmsg; \ + errmsg << #trycode " threw CoinError: " << e.message(); \ + if (e.className().length() > 0) \ + errmsg << " in " << e.className(); \ + if (e.methodName().length() > 0) \ + errmsg << " in " << e.methodName(); \ + if (e.lineNumber() >= 0) \ + errmsg << " at " << e.fileName() << ":" << e.lineNumber(); \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.str().c_str(),\ + severity,expected); \ + OsiUnitTest::failureMessage(component,testname,errmsg.str().c_str()); \ + switch(OsiUnitTest::haltonerror) { \ + case 2: \ + { if (severity >= OsiUnitTest::TestOutcome::ERROR) abort(); break; } \ + case 1: \ + { std::cout << std::endl << "press any key to continue..." << std::endl; \ + getchar(); \ + break ; } \ + default: ; \ + } \ + catchcode; \ + } catch (...) { \ + std::string errmsg; \ + errmsg = #trycode; \ + errmsg = errmsg + " threw unknown exception"; \ + OSIUNITTEST_ADD_OUTCOME(component,testname,errmsg.c_str(),severity,false); \ + OsiUnitTest::failureMessage(component,testname,errmsg.c_str()); \ + catchcode; \ + } \ +} + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::ERROR, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_ERROR(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::ERROR, false) + +/*! \brief Perform a try/catch test with severity OsiUnitTest::TestOutcome::WARNING, + failure not expected. +*/ +#define OSIUNITTEST_CATCH_WARNING(trycode, catchcode, component, testname) \ + OSIUNITTEST_CATCH_SEVERITY_EXPECTED(trycode, catchcode, component, testname, OsiUnitTest::TestOutcome::WARNING, false) + +} // end namespace OsiUnitTest + +#endif /*OSISOLVERINTERFACETEST_HPP_*/ diff --git a/thirdparty/linux/include/coin1/PardisoLoader.h b/thirdparty/linux/include/coin1/PardisoLoader.h new file mode 100644 index 0000000..0942521 --- /dev/null +++ b/thirdparty/linux/include/coin1/PardisoLoader.h @@ -0,0 +1,41 @@ +/* Copyright (C) 2008 GAMS Development and others + All Rights Reserved. + This code is published under the Eclipse Public License. + + $Id: PardisoLoader.h 2204 2013-04-13 13:49:26Z stefan $ + + Author: Stefan Vigerske +*/ + +#ifndef PARDISOLOADER_H_ +#define PARDISOLOADER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + /** Tries to load a dynamically linked library with Pardiso. + * Return a failure if the library cannot be loaded or not all Pardiso symbols are found. + * @param libname The name under which the Pardiso lib can be found, or NULL to use a default name (libpardiso.SHAREDLIBEXT). + * @param msgbuf A buffer where we can store a failure message. Assumed to be NOT NULL! + * @param msglen Length of the message buffer. + * @return Zero on success, nonzero on failure. + */ + int LSL_loadPardisoLib(const char* libname, char* msgbuf, int msglen); + + /** Unloads a loaded Pardiso library. + * @return Zero on success, nonzero on failure. + */ + int LSL_unloadPardisoLib(); + + /** Indicates whether a Pardiso library has been successfully loaded. + * @return Zero if not loaded, nonzero if handle is loaded + */ + int LSL_isPardisoLoaded(); + + /** Returns name of the shared library that should contain Pardiso */ + char* LSL_PardisoLibraryName(); +#ifdef __cplusplus +} +#endif + +#endif /*PARADISOLOADER_H_*/ diff --git a/thirdparty/linux/include/coin1/SymConfig.h b/thirdparty/linux/include/coin1/SymConfig.h new file mode 100644 index 0000000..d3c548e --- /dev/null +++ b/thirdparty/linux/include/coin1/SymConfig.h @@ -0,0 +1,19 @@ +/* include/config_sym.h. Generated by configure. */ +/* include/config_sym.h.in. */ + +#ifndef __CONFIG_SYM_H__ +#define __CONFIG_SYM_H__ + +/* Version number of project */ +#define SYMPHONY_VERSION "5.6.10" + +/* Major Version number of project */ +#define SYMPHONY_VERSION_MAJOR 5 + +/* Minor Version number of project */ +#define SYMPHONY_VERSION_MINOR 6 + +/* Release Version number of project */ +#define SYMPHONY_VERSION_RELEASE 10 + +#endif diff --git a/thirdparty/linux/include/coin1/SymWarmStart.hpp b/thirdparty/linux/include/coin1/SymWarmStart.hpp new file mode 100644 index 0000000..74089d1 --- /dev/null +++ b/thirdparty/linux/include/coin1/SymWarmStart.hpp @@ -0,0 +1,72 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY Branch, Cut, and Price Callable */ +/* Library. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (tkralphs@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2004-2006 Ted Ralphs and Lehigh University. */ +/* All Rights Reserved. */ +/* */ +/* The authors of this file are Menal Guzelsoy and Ted Ralphs */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef SymWarmStart_H +#define SymWarmStart_H + +#include "CoinWarmStart.hpp" + +typedef struct WARM_START_DESC warm_start_desc; + +//############################################################################# + +class SymWarmStart : public CoinWarmStart +{ + +public: + + /* Default constructor. Will do nothing! */ + SymWarmStart(){} + + /* Initialize the warmStart_ using the given warm start. If dominate + WarmStart is set, then, SymWarmStart will take the control of the + given description, otherwise, will copy everything. + */ + SymWarmStart(warm_start_desc * ws); + + /*Get the warmStart info from a file*/ + SymWarmStart(char *f); + + /* Copy constructor */ + SymWarmStart(const SymWarmStart & symWS); + + /* Destructor */ + virtual ~SymWarmStart(); + + /* Clone the warmstart */ + virtual CoinWarmStart * clone() const; + + /* Get the pointer to the loaded warmStart_ */ + virtual warm_start_desc * getCopyOfWarmStartDesc(); + + /* Move the pointer to the rootnode of the warmStart to another + node which will change the underlying tree + */ + // virtual void setRoot(bc_node *root) {} //FIX_ME! Ask Prof. Ralphs. + + /* Write the current warm start info to a file */ + virtual int writeToFile(char * f); + +private: + + /* Private warm start desc. to keep everything */ + warm_start_desc *warmStart_; + +}; + +#endif diff --git a/thirdparty/linux/include/coin1/ThirdParty/defs.h b/thirdparty/linux/include/coin1/ThirdParty/defs.h new file mode 100644 index 0000000..2209540 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/defs.h @@ -0,0 +1,161 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * defs.h + * + * This file contains constant definitions + * + * Started 8/27/94 + * George + * + * $Id: defs.h,v 1.1 1998/11/27 17:59:13 karypis Exp $ + * + */ + +#define METISTITLE " METIS 4.0.3 Copyright 1998, Regents of the University of Minnesota\n\n" +#define MAXLINE 1280000 + +#define LTERM (void **) 0 /* List terminator for GKfree() */ + +#define MAXNCON 16 /* The maximum number of constrains */ +#define MAXNOBJ 16 /* The maximum number of objectives */ + +#define PLUS_GAINSPAN 500 /* Parameters for FM buckets */ +#define NEG_GAINSPAN 500 + +#define HTLENGTH ((1<<11)-1) + +/* Meaning of various options[] parameters */ +#define OPTION_PTYPE 0 +#define OPTION_CTYPE 1 +#define OPTION_ITYPE 2 +#define OPTION_RTYPE 3 +#define OPTION_DBGLVL 4 +#define OPTION_OFLAGS 5 +#define OPTION_PFACTOR 6 +#define OPTION_NSEPS 7 + +#define OFLAG_COMPRESS 1 /* Try to compress the graph */ +#define OFLAG_CCMP 2 /* Find and order connected components */ + + +/* Default options for PMETIS */ +#define PMETIS_CTYPE MATCH_SHEM +#define PMETIS_ITYPE IPART_GGPKL +#define PMETIS_RTYPE RTYPE_FM +#define PMETIS_DBGLVL 0 + +/* Default options for KMETIS */ +#define KMETIS_CTYPE MATCH_SHEM +#define KMETIS_ITYPE IPART_PMETIS +#define KMETIS_RTYPE RTYPE_KWAYRANDOM_MCONN +#define KMETIS_DBGLVL 0 + +/* Default options for OEMETIS */ +#define OEMETIS_CTYPE MATCH_SHEM +#define OEMETIS_ITYPE IPART_GGPKL +#define OEMETIS_RTYPE RTYPE_FM +#define OEMETIS_DBGLVL 0 + +/* Default options for ONMETIS */ +#define ONMETIS_CTYPE MATCH_SHEM +#define ONMETIS_ITYPE IPART_GGPKL +#define ONMETIS_RTYPE RTYPE_SEP1SIDED +#define ONMETIS_DBGLVL 0 +#define ONMETIS_OFLAGS OFLAG_COMPRESS +#define ONMETIS_PFACTOR -1 +#define ONMETIS_NSEPS 1 + +/* Default options for McPMETIS */ +#define McPMETIS_CTYPE MATCH_SHEBM_ONENORM +#define McPMETIS_ITYPE IPART_RANDOM +#define McPMETIS_RTYPE RTYPE_FM +#define McPMETIS_DBGLVL 0 + +/* Default options for McKMETIS */ +#define McKMETIS_CTYPE MATCH_SHEBM_ONENORM +#define McKMETIS_ITYPE IPART_McHPMETIS +#define McKMETIS_RTYPE RTYPE_KWAYRANDOM +#define McKMETIS_DBGLVL 0 + +/* Default options for KVMETIS */ +#define KVMETIS_CTYPE MATCH_SHEM +#define KVMETIS_ITYPE IPART_PMETIS +#define KVMETIS_RTYPE RTYPE_KWAYRANDOM +#define KVMETIS_DBGLVL 0 + + +/* Operations supported by stand-alone code */ +#define OP_PMETIS 1 +#define OP_KMETIS 2 +#define OP_OEMETIS 3 +#define OP_ONMETIS 4 +#define OP_ONWMETIS 5 +#define OP_KVMETIS 6 + + +/* Matching Schemes */ +#define MATCH_RM 1 +#define MATCH_HEM 2 +#define MATCH_SHEM 3 +#define MATCH_SHEMKWAY 4 +#define MATCH_SHEBM_ONENORM 5 +#define MATCH_SHEBM_INFNORM 6 +#define MATCH_SBHEM_ONENORM 7 +#define MATCH_SBHEM_INFNORM 8 + +/* Initial partitioning schemes for PMETIS and ONMETIS */ +#define IPART_GGPKL 1 +#define IPART_GGPKLNODE 2 +#define IPART_RANDOM 2 + +/* Refinement schemes for PMETIS */ +#define RTYPE_FM 1 + +/* Initial partitioning schemes for KMETIS */ +#define IPART_PMETIS 1 + +/* Refinement schemes for KMETIS */ +#define RTYPE_KWAYRANDOM 1 +#define RTYPE_KWAYGREEDY 2 +#define RTYPE_KWAYRANDOM_MCONN 3 + +/* Refinement schemes for ONMETIS */ +#define RTYPE_SEP2SIDED 1 +#define RTYPE_SEP1SIDED 2 + +/* Initial Partitioning Schemes for McKMETIS */ +#define IPART_McPMETIS 1 /* Simple McPMETIS */ +#define IPART_McHPMETIS 2 /* horizontally relaxed McPMETIS */ + +#define UNMATCHED -1 + +#define HTABLE_EMPTY -1 + +#define NGR_PASSES 4 /* Number of greedy refinement passes */ +#define NLGR_PASSES 5 /* Number of GR refinement during IPartition */ + +#define LARGENIPARTS 8 /* Number of random initial partitions */ +#define SMALLNIPARTS 3 /* Number of random initial partitions */ + +#define COARSEN_FRACTION 0.75 /* Node reduction between succesive coarsening levels */ +#define COARSEN_FRACTION2 0.90 /* Node reduction between succesive coarsening levels */ +#define UNBALANCE_FRACTION 1.05 + +#define COMPRESSION_FRACTION 0.85 + +#define ORDER_UNBALANCE_FRACTION 1.10 + +#define MMDSWITCH 200 + +#define HORIZONTAL_IMBALANCE 1.05 + +/* Debug Levels */ +#define DBG_TIME 1 /* Perform timing analysis */ +#define DBG_OUTPUT 2 +#define DBG_COARSEN 4 /* Show the coarsening progress */ +#define DBG_REFINE 8 /* Show info on communication during folding */ +#define DBG_IPART 16 /* Show info on initial partition */ +#define DBG_MOVEINFO 32 /* Show info on communication during folding */ +#define DBG_KWAYPINFO 64 /* Show info on communication during folding */ +#define DBG_SEPINFO 128 /* Show info on communication during folding */ diff --git a/thirdparty/linux/include/coin1/ThirdParty/dmumps_c.h b/thirdparty/linux/include/coin1/ThirdParty/dmumps_c.h new file mode 100644 index 0000000..1d5c2c9 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/dmumps_c.h @@ -0,0 +1,159 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Mostly written in march 2002 (JYL) */ + +#ifndef DMUMPS_C_H +#define DMUMPS_C_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "mumps_compat.h" +/* Next line defines MUMPS_INT, DMUMPS_COMPLEX and DMUMPS_REAL */ +#include "mumps_c_types.h" + +#ifndef MUMPS_VERSION +/* Protected in case headers of other arithmetics are included */ +#define MUMPS_VERSION "4.10.0" +#endif +#ifndef MUMPS_VERSION_MAX_LEN +#define MUMPS_VERSION_MAX_LEN 14 +#endif + +/* + * Definition of the (simplified) MUMPS C structure. + * NB: DMUMPS_COMPLEX are REAL types in s and d arithmetics. + */ +typedef struct { + + MUMPS_INT sym, par, job; + MUMPS_INT comm_fortran; /* Fortran communicator */ + MUMPS_INT icntl[40]; + DMUMPS_REAL cntl[15]; + MUMPS_INT n; + + MUMPS_INT nz_alloc; /* used in matlab interface to decide if we + free + malloc when we have large variation */ + + /* Assembled entry */ + MUMPS_INT nz; + MUMPS_INT *irn; + MUMPS_INT *jcn; + DMUMPS_COMPLEX *a; + + /* Distributed entry */ + MUMPS_INT nz_loc; + MUMPS_INT *irn_loc; + MUMPS_INT *jcn_loc; + DMUMPS_COMPLEX *a_loc; + + /* Element entry */ + MUMPS_INT nelt; + MUMPS_INT *eltptr; + MUMPS_INT *eltvar; + DMUMPS_COMPLEX *a_elt; + + /* Ordering, if given by user */ + MUMPS_INT *perm_in; + + /* Orderings returned to user */ + MUMPS_INT *sym_perm; /* symmetric permutation */ + MUMPS_INT *uns_perm; /* column permutation */ + + /* Scaling (input only in this version) */ + DMUMPS_REAL *colsca; + DMUMPS_REAL *rowsca; + + /* RHS, solution, ouptput data and statistics */ + DMUMPS_COMPLEX *rhs, *redrhs, *rhs_sparse, *sol_loc; + MUMPS_INT *irhs_sparse, *irhs_ptr, *isol_loc; + MUMPS_INT nrhs, lrhs, lredrhs, nz_rhs, lsol_loc; + MUMPS_INT schur_mloc, schur_nloc, schur_lld; + MUMPS_INT mblock, nblock, nprow, npcol; + MUMPS_INT info[40],infog[40]; + DMUMPS_REAL rinfo[40], rinfog[40]; + + /* Null space */ + MUMPS_INT deficiency; + MUMPS_INT *pivnul_list; + MUMPS_INT *mapping; + + /* Schur */ + MUMPS_INT size_schur; + MUMPS_INT *listvar_schur; + DMUMPS_COMPLEX *schur; + + /* Internal parameters */ + MUMPS_INT instance_number; + DMUMPS_COMPLEX *wk_user; + + /* Version number: length=14 in FORTRAN + 1 for final \0 + 1 for alignment */ + char version_number[MUMPS_VERSION_MAX_LEN + 1 + 1]; + /* For out-of-core */ + char ooc_tmpdir[256]; + char ooc_prefix[64]; + /* To save the matrix in matrix market format */ + char write_problem[256]; + MUMPS_INT lwk_user; + +} DMUMPS_STRUC_C; + + +void MUMPS_CALL +dmumps_c( DMUMPS_STRUC_C * dmumps_par ); + +#ifdef __cplusplus +} +#endif + +#endif /* DMUMPS_C_H */ + diff --git a/thirdparty/linux/include/coin1/ThirdParty/macros.h b/thirdparty/linux/include/coin1/ThirdParty/macros.h new file mode 100644 index 0000000..fdf0ade --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/macros.h @@ -0,0 +1,143 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * macros.h + * + * This file contains macros used in multilevel + * + * Started 9/25/94 + * George + * + * $Id: macros.h,v 1.1 1998/11/27 17:59:18 karypis Exp $ + * + */ + + +/************************************************************************* +* The following macro returns a random number in the specified range +**************************************************************************/ +#ifdef __VC__ +#define RandomInRange(u) ((rand()>>3)%(u)) +#define RandomInRangeFast(u) ((rand()>>3)%(u)) +#else +#define RandomInRange(u) ((int)(drand48()*((double)(u)))) +#define RandomInRangeFast(u) ((rand()>>3)%(u)) +#endif + + + +#define amax(a, b) ((a) >= (b) ? (a) : (b)) +#define amin(a, b) ((a) >= (b) ? (b) : (a)) + +#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) +#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) +#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) + +#define SWAP(a, b, tmp) \ + do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) + +#define INC_DEC(a, b, val) \ + do {(a) += (val); (b) -= (val);} while(0) + + +#define scopy(n, a, b) (float *)memcpy((void *)(b), (void *)(a), sizeof(float)*(n)) +#define idxcopy(n, a, b) (idxtype *)memcpy((void *)(b), (void *)(a), sizeof(idxtype)*(n)) + +#define HASHFCT(key, size) ((key)%(size)) + + +/************************************************************************* +* Timer macros +**************************************************************************/ +#define cleartimer(tmr) (tmr = 0.0) +#define starttimer(tmr) (tmr -= seconds()) +#define stoptimer(tmr) (tmr += seconds()) +#define gettimer(tmr) (tmr) + + +/************************************************************************* +* This macro is used to handle dbglvl +**************************************************************************/ +#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd); + +/************************************************************************* +* These macros are used for debuging memory leaks +**************************************************************************/ +#ifdef DMALLOC +#define imalloc(n, msg) (malloc(sizeof(int)*(n))) +#define fmalloc(n, msg) (malloc(sizeof(float)*(n))) +#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n))) +#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n)))) +#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n)))) +#define GKmalloc(a, b) (malloc((a))) +#endif + +#ifdef DMALLOC +# define MALLOC_CHECK(ptr) \ + if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) { \ + printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define MALLOC_CHECK(ptr) ; +#endif + + + +/************************************************************************* +* This macro converts a length array in a CSR one +**************************************************************************/ +#define MAKECSR(i, n, a) \ + do { \ + for (i=1; i<n; i++) a[i] += a[i-1]; \ + for (i=n; i>0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + +/************************************************************************* +* These macros insert and remove nodes from the boundary list +**************************************************************************/ +#define BNDInsert(nbnd, bndind, bndptr, vtx) \ + do { \ + ASSERT(bndptr[vtx] == -1); \ + bndind[nbnd] = vtx; \ + bndptr[vtx] = nbnd++;\ + } while(0) + +#define BNDDelete(nbnd, bndind, bndptr, vtx) \ + do { \ + ASSERT(bndptr[vtx] != -1); \ + bndind[bndptr[vtx]] = bndind[--nbnd]; \ + bndptr[bndind[nbnd]] = bndptr[vtx]; \ + bndptr[vtx] = -1; \ + } while(0) + + + +/************************************************************************* +* These are debugging macros +**************************************************************************/ +#ifdef DEBUG +# define ASSERT(expr) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERT(expr) ; +#endif + +#ifdef DEBUG +# define ASSERTP(expr, msg) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + printf msg ; \ + abort(); \ + } +#else +# define ASSERTP(expr, msg) ; +#endif diff --git a/thirdparty/linux/include/coin1/ThirdParty/mpi.h b/thirdparty/linux/include/coin1/ThirdParty/mpi.h new file mode 100644 index 0000000..7ab0c37 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/mpi.h @@ -0,0 +1,77 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +#ifndef MUMPS_MPI_H +#define MUMPS_MPI_H + +/* We define all symbols as extern "C" for users who call MUMPS with its + libseq from a C++ driver. */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the minimum to have the C interface of MUMPS work. + * Most of the time, users who need this file have no call to MPI functions in + * their own code. Hence it is not worth declaring all MPI functions here. + * However if some users come to request some more stub functions of the MPI + * standards, we may add them. But it is not worth doing it until then. */ + +typedef int MPI_Comm; /* Simple type for MPI communicator */ +static MPI_Comm MPI_COMM_WORLD=(MPI_Comm)0; + +int MPI_Init(int *pargc, char ***pargv); +int MPI_Comm_rank(int comm, int *rank); +int MPI_Finalize(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MUMPS_MPI_H */ diff --git a/thirdparty/linux/include/coin1/ThirdParty/mumps_c_types.h b/thirdparty/linux/include/coin1/ThirdParty/mumps_c_types.h new file mode 100644 index 0000000..aef6212 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/mumps_c_types.h @@ -0,0 +1,92 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + + +#ifndef MUMPS_C_TYPES_H +#define MUMPS_C_TYPES_H + +#define MUMPS_INT int + +#define SMUMPS_COMPLEX float +#define SMUMPS_REAL float + +#define DMUMPS_COMPLEX double +#define DMUMPS_REAL double + +/* Complex datatypes */ +typedef struct {float r,i;} mumps_complex; +typedef struct {double r,i;} mumps_double_complex; + +#define CMUMPS_COMPLEX mumps_complex +#define CMUMPS_REAL float + +#define ZMUMPS_COMPLEX mumps_double_complex +#define ZMUMPS_REAL double + + +#ifndef mumps_ftnlen +/* When passing a string, what is the type of the extra argument + * passed by value ? */ +# define mumps_ftnlen int +#endif + + +#define MUMPS_ARITH_s 1 +#define MUMPS_ARITH_d 2 +#define MUMPS_ARITH_c 4 +#define MUMPS_ARITH_z 8 + +#define MUMPS_ARITH_REAL ( MUMPS_ARITH_s | MUMPS_ARITH_d ) +#define MUMPS_ARITH_CMPLX ( MUMPS_ARITH_c | MUMPS_ARITH_z ) +#define MUMPS_ARITH_SINGLE ( MUMPS_ARITH_s | MUMPS_ARITH_c ) +#define MUMPS_ARITH_DBL ( MUMPS_ARITH_d | MUMPS_ARITH_z ) + + +#endif /* MUMPS_C_TYPES_H */ diff --git a/thirdparty/linux/include/coin1/ThirdParty/mumps_compat.h b/thirdparty/linux/include/coin1/ThirdParty/mumps_compat.h new file mode 100644 index 0000000..d63120e --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/mumps_compat.h @@ -0,0 +1,78 @@ +/* + * + * This file is part of MUMPS 4.10.0, built on Tue May 10 12:56:32 UTC 2011 + * + * + * This version of MUMPS is provided to you free of charge. It is public + * domain, based on public domain software developed during the Esprit IV + * European project PARASOL (1996-1999). Since this first public domain + * version in 1999, research and developments have been supported by the + * following institutions: CERFACS, CNRS, ENS Lyon, INPT(ENSEEIHT)-IRIT, + * INRIA, and University of Bordeaux. + * + * The MUMPS team at the moment of releasing this version includes + * Patrick Amestoy, Maurice Bremond, Alfredo Buttari, Abdou Guermouche, + * Guillaume Joslin, Jean-Yves L'Excellent, Francois-Henry Rouet, Bora + * Ucar and Clement Weisbecker. + * + * We are also grateful to Emmanuel Agullo, Caroline Bousquet, Indranil + * Chowdhury, Philippe Combes, Christophe Daniel, Iain Duff, Vincent Espirat, + * Aurelia Fevre, Jacko Koster, Stephane Pralet, Chiara Puglisi, Gregoire + * Richard, Tzvetomila Slavova, Miroslav Tuma and Christophe Voemel who + * have been contributing to this project. + * + * Up-to-date copies of the MUMPS package can be obtained + * from the Web pages: + * http://mumps.enseeiht.fr/ or http://graal.ens-lyon.fr/MUMPS + * + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY + * EXPRESSED OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * + * User documentation of any code that uses this software can + * include this complete notice. You can acknowledge (using + * references [1] and [2]) the contribution of this package + * in any scientific publication dependent upon the use of the + * package. You shall use reasonable endeavours to notify + * the authors of the package of this publication. + * + * [1] P. R. Amestoy, I. S. Duff, J. Koster and J.-Y. L'Excellent, + * A fully asynchronous multifrontal solver using distributed dynamic + * scheduling, SIAM Journal of Matrix Analysis and Applications, + * Vol 23, No 1, pp 15-41 (2001). + * + * [2] P. R. Amestoy and A. Guermouche and J.-Y. L'Excellent and + * S. Pralet, Hybrid scheduling for the parallel solution of linear + * systems. Parallel Computing Vol 32 (2), pp 136-156 (2006). + * + */ + +/* Compatibility issues between various Windows versions */ +#ifndef MUMPS_COMPAT_H +#define MUMPS_COMPAT_H + + +#if defined(_WIN32) && ! defined(__MINGW32__) +# define MUMPS_WIN32 1 +#endif + +#ifndef MUMPS_CALL +# ifdef MUMPS_WIN32 +/* Modify/choose between next 2 lines depending + * on your Windows calling conventions */ +/* # define MUMPS_CALL __stdcall */ +# define MUMPS_CALL +# else +# define MUMPS_CALL +# endif +#endif + +#if (__STDC_VERSION__ >= 199901L) +# define MUMPS_INLINE static inline +#else +# define MUMPS_INLINE +#endif + + +#endif /* MUMPS_COMPAT_H */ diff --git a/thirdparty/linux/include/coin1/ThirdParty/proto.h b/thirdparty/linux/include/coin1/ThirdParty/proto.h new file mode 100644 index 0000000..9b65adf --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/proto.h @@ -0,0 +1,505 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * proto.h + * + * This file contains header files + * + * Started 10/19/95 + * George + * + * $Id: proto.h,v 1.1 1998/11/27 17:59:28 karypis Exp $ + * + */ + +/* balance.c */ +void Balance2Way(CtrlType *, GraphType *, int *, float); +void Bnd2WayBalance(CtrlType *, GraphType *, int *); +void General2WayBalance(CtrlType *, GraphType *, int *); + +/* bucketsort.c */ +void BucketSortKeysInc(int, int, idxtype *, idxtype *, idxtype *); + +/* ccgraph.c */ +void CreateCoarseGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *); +void CreateCoarseGraphNoMask(CtrlType *, GraphType *, int, idxtype *, idxtype *); +void CreateCoarseGraph_NVW(CtrlType *, GraphType *, int, idxtype *, idxtype *); +GraphType *SetUpCoarseGraph(GraphType *, int, int); +void ReAdjustMemory(GraphType *, GraphType *, int); + +/* coarsen.c */ +GraphType *Coarsen2Way(CtrlType *, GraphType *); + +/* compress.c */ +void CompressGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, idxtype *); +void PruneGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, float); + +/* debug.c */ +int ComputeCut(GraphType *, idxtype *); +int CheckBnd(GraphType *); +int CheckBnd2(GraphType *); +int CheckNodeBnd(GraphType *, int); +int CheckRInfo(RInfoType *); +int CheckNodePartitionParams(GraphType *); +int IsSeparable(GraphType *); + +/* estmem.c */ +void METIS_EstimateMemory(int *, idxtype *, idxtype *, int *, int *, int *); +void EstimateCFraction(int, idxtype *, idxtype *, float *, float *); +int ComputeCoarseGraphSize(int, idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *); + +/* fm.c */ +void FM_2WayEdgeRefine(CtrlType *, GraphType *, int *, int); + +/* fortran.c */ +void Change2CNumbering(int, idxtype *, idxtype *); +void Change2FNumbering(int, idxtype *, idxtype *, idxtype *); +void Change2FNumbering2(int, idxtype *, idxtype *); +void Change2FNumberingOrder(int, idxtype *, idxtype *, idxtype *, idxtype *); +void ChangeMesh2CNumbering(int, idxtype *); +void ChangeMesh2FNumbering(int, idxtype *, int, idxtype *, idxtype *); +void ChangeMesh2FNumbering2(int, idxtype *, int, int, idxtype *, idxtype *); + +/* frename.c */ +void METIS_PARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_PARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_EDGEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NODEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NODEWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd_(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd__(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_PARTMESHNODAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_PARTMESHDUAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_MESHTONODAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_MESHTODUAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_ESTIMATEMEMORY(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory_(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory__(int *, idxtype *, idxtype *, int *, int *, int *); +void METIS_MCPARTGRAPHRECURSIVE(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_MCPARTGRAPHKWAY(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_PARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); + +/* graph.c */ +void SetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); +void SetUpGraphKway(GraphType *, int, idxtype *, idxtype *); +void SetUpGraph2(GraphType *, int, int, idxtype *, idxtype *, float *, idxtype *); +void VolSetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); +void RandomizeGraph(GraphType *); +int IsConnectedSubdomain(CtrlType *, GraphType *, int, int); +int IsConnected(CtrlType *, GraphType *, int); +int IsConnected2(GraphType *, int); +int FindComponents(CtrlType *, GraphType *, idxtype *, idxtype *); + +/* initpart.c */ +void Init2WayPartition(CtrlType *, GraphType *, int *, float); +void InitSeparator(CtrlType *, GraphType *, float); +void GrowBisection(CtrlType *, GraphType *, int *, float); +void GrowBisectionNode(CtrlType *, GraphType *, float); +void RandomBisection(CtrlType *, GraphType *, int *, float); + +/* kmetis.c */ +void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); + +/* kvmetis.c */ +void METIS_PartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelVolKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); + +/* kwayfm.c */ +void Random_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int); +void Greedy_KWayEdgeBalance(CtrlType *, GraphType *, int, float *, float, int); + +/* kwayrefine.c */ +void RefineKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); +void AllocateKWayPartitionMemory(CtrlType *, GraphType *, int); +void ComputeKWayPartitionParams(CtrlType *, GraphType *, int); +void ProjectKWayPartition(CtrlType *, GraphType *, int); +int IsBalanced(idxtype *, int, float *, float); +void ComputeKWayBoundary(CtrlType *, GraphType *, int); +void ComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* kwayvolfm.c */ +void Random_KWayVolRefine(CtrlType *, GraphType *, int, float *, float, int, int); +void Random_KWayVolRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayVolBalance(CtrlType *, GraphType *, int, float *, float, int); +void Greedy_KWayVolBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); +void KWayVolUpdate(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *, idxtype *); +void ComputeKWayVolume(GraphType *, int, idxtype *, idxtype *, idxtype *); +int ComputeVolume(GraphType *, idxtype *); +void CheckVolKWayPartitionParams(CtrlType *, GraphType *, int); +void ComputeVolSubDomainGraph(GraphType *, int, idxtype *, idxtype *); +void EliminateVolSubDomainEdges(CtrlType *, GraphType *, int, float *); +void EliminateVolComponents(CtrlType *, GraphType *, int, float *, float); + +/* kwayvolrefine.c */ +void RefineVolKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); +void AllocateVolKWayPartitionMemory(CtrlType *, GraphType *, int); +void ComputeVolKWayPartitionParams(CtrlType *, GraphType *, int); +void ComputeKWayVolGains(CtrlType *, GraphType *, int); +void ProjectVolKWayPartition(CtrlType *, GraphType *, int); +void ComputeVolKWayBoundary(CtrlType *, GraphType *, int); +void ComputeVolKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* match.c */ +void Match_RM(CtrlType *, GraphType *); +void Match_RM_NVW(CtrlType *, GraphType *); +void Match_HEM(CtrlType *, GraphType *); +void Match_SHEM(CtrlType *, GraphType *); + +/* mbalance.c */ +void MocBalance2Way(CtrlType *, GraphType *, float *, float); +void MocGeneral2WayBalance(CtrlType *, GraphType *, float *, float); + +/* mbalance2.c */ +void MocBalance2Way2(CtrlType *, GraphType *, float *, float *); +void MocGeneral2WayBalance2(CtrlType *, GraphType *, float *, float *); +void SelectQueue3(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); + +/* mcoarsen.c */ +GraphType *MCCoarsen2Way(CtrlType *, GraphType *); + +/* memory.c */ +void AllocateWorkSpace(CtrlType *, GraphType *, int); +void FreeWorkSpace(CtrlType *, GraphType *); +int WspaceAvail(CtrlType *); +idxtype *idxwspacemalloc(CtrlType *, int); +void idxwspacefree(CtrlType *, int); +float *fwspacemalloc(CtrlType *, int); +void fwspacefree(CtrlType *, int); +GraphType *CreateGraph(void); +void InitGraph(GraphType *); +void FreeGraph(GraphType *); + +/* mesh.c */ +void METIS_MeshToDual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_MeshToNodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void GENDUALMETIS(int, int, int, idxtype *, idxtype *, idxtype *adjncy); +void TRINODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void TETNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void HEXNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void QUADNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); + +/* meshpart.c */ +void METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); + +/* mfm.c */ +void MocFM_2WayEdgeRefine(CtrlType *, GraphType *, float *, int); +void SelectQueue(int, float *, float *, int *, int *, PQueueType [MAXNCON][2]); +int BetterBalance(int, float *, float *, float *); +float Compute2WayHLoadImbalance(int, float *, float *); +void Compute2WayHLoadImbalanceVec(int, float *, float *, float *); + +/* mfm2.c */ +void MocFM_2WayEdgeRefine2(CtrlType *, GraphType *, float *, float *, int); +void SelectQueue2(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); +int IsBetter2wayBalance(int, float *, float *, float *); + +/* mincover.o */ +void MinCover(idxtype *, idxtype *, int, int, idxtype *, int *); +int MinCover_Augment(idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *, int); +void MinCover_Decompose(idxtype *, idxtype *, int, int, idxtype *, idxtype *, int *); +void MinCover_ColDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); +void MinCover_RowDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); + +/* minitpart.c */ +void MocInit2WayPartition(CtrlType *, GraphType *, float *, float); +void MocGrowBisection(CtrlType *, GraphType *, float *, float); +void MocRandomBisection(CtrlType *, GraphType *, float *, float); +void MocInit2WayBalance(CtrlType *, GraphType *, float *); +int SelectQueueoneWay(int, float *, float *, int, PQueueType [MAXNCON][2]); + +/* minitpart2.c */ +void MocInit2WayPartition2(CtrlType *, GraphType *, float *, float *); +void MocGrowBisection2(CtrlType *, GraphType *, float *, float *); +void MocGrowBisectionNew2(CtrlType *, GraphType *, float *, float *); +void MocInit2WayBalance2(CtrlType *, GraphType *, float *, float *); +int SelectQueueOneWay2(int, float *, PQueueType [MAXNCON][2], float *); + +/* mkmetis.c */ +void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MCMlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *); + +/* mkwayfmh.c */ +void MCRandom_KWayEdgeRefineHorizontal(CtrlType *, GraphType *, int, float *, int); +void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *, GraphType *, int, float *, int); +int AreAllHVwgtsBelow(int, float, float *, float, float *, float *); +int AreAllHVwgtsAbove(int, float, float *, float, float *, float *); +void ComputeHKWayLoadImbalance(int, int, float *, float *); +int MocIsHBalanced(int, int, float *, float *); +int IsHBalanceBetterFT(int, int, float *, float *, float *, float *); +int IsHBalanceBetterTT(int, int, float *, float *, float *, float *); + +/* mkwayrefine.c */ +void MocRefineKWayHorizontal(CtrlType *, GraphType *, GraphType *, int, float *); +void MocAllocateKWayPartitionMemory(CtrlType *, GraphType *, int); +void MocComputeKWayPartitionParams(CtrlType *, GraphType *, int); +void MocProjectKWayPartition(CtrlType *, GraphType *, int); +void MocComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* mmatch.c */ +void MCMatch_RM(CtrlType *, GraphType *); +void MCMatch_HEM(CtrlType *, GraphType *); +void MCMatch_SHEM(CtrlType *, GraphType *); +void MCMatch_SHEBM(CtrlType *, GraphType *, int); +void MCMatch_SBHEM(CtrlType *, GraphType *, int); +float BetterVBalance(int, int, float *, float *, float *); +int AreAllVwgtsBelowFast(int, float *, float *, float); + +/* mmd.c */ +void genmmd(int, idxtype *, idxtype *, idxtype *, idxtype *, int , idxtype *, idxtype *, idxtype *, idxtype *, int, int *); +void mmdelm(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int); +int mmdint(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *); +void mmdnum(int, idxtype *, idxtype *, idxtype *); +void mmdupd(int, int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int *tag); + +/* mpmetis.c */ +void METIS_mCPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_mCHPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_mCPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, int *, int *, idxtype *); +void METIS_mCHPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, float *, int *, int *, idxtype *); +int MCMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float, int); +int MCHMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, int); +void MCMlevelEdgeBisection(CtrlType *, GraphType *, float *, float); +void MCHMlevelEdgeBisection(CtrlType *, GraphType *, float *, float *); + +/* mrefine.c */ +void MocRefine2Way(CtrlType *, GraphType *, GraphType *, float *, float); +void MocAllocate2WayPartitionMemory(CtrlType *, GraphType *); +void MocCompute2WayPartitionParams(CtrlType *, GraphType *); +void MocProject2WayPartition(CtrlType *, GraphType *); + +/* mrefine2.c */ +void MocRefine2Way2(CtrlType *, GraphType *, GraphType *, float *, float *); + +/* mutil.c */ +int AreAllVwgtsBelow(int, float, float *, float, float *, float); +int AreAnyVwgtsBelow(int, float, float *, float, float *, float); +int AreAllVwgtsAbove(int, float, float *, float, float *, float); +float ComputeLoadImbalance(int, int, float *, float *); +int AreAllBelow(int, float *, float *); + +/* myqsort.c */ +void iidxsort(int, idxtype *); +void iintsort(int, int *); +void ikeysort(int, KeyValueType *); +void ikeyvalsort(int, KeyValueType *); + +/* ometis.c */ +void METIS_EdgeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void MlevelNestedDissection(CtrlType *, GraphType *, idxtype *, float, int); +void MlevelNestedDissectionCC(CtrlType *, GraphType *, idxtype *, float, int); +void MlevelNodeBisectionMultiple(CtrlType *, GraphType *, int *, float); +void MlevelNodeBisection(CtrlType *, GraphType *, int *, float); +void SplitGraphOrder(CtrlType *, GraphType *, GraphType *, GraphType *); +void MMDOrder(CtrlType *, GraphType *, idxtype *, int); +int SplitGraphOrderCC(CtrlType *, GraphType *, GraphType *, int, idxtype *, idxtype *); + +/* parmetis.c */ +void METIS_PartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *); +void MlevelNestedDissectionP(CtrlType *, GraphType *, idxtype *, int, int, int, idxtype *); +void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); + +/* pmetis.c */ +void METIS_PartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, float, int); +void MlevelEdgeBisection(CtrlType *, GraphType *, int *, float); +void SplitGraphPart(CtrlType *, GraphType *, GraphType *, GraphType *); +void SetUpSplitGraph(GraphType *, GraphType *, int, int); + +/* pqueue.c */ +void PQueueInit(CtrlType *ctrl, PQueueType *, int, int); +void PQueueReset(PQueueType *); +void PQueueFree(CtrlType *ctrl, PQueueType *); +int PQueueGetSize(PQueueType *); +int PQueueInsert(PQueueType *, int, int); +int PQueueDelete(PQueueType *, int, int); +int PQueueUpdate(PQueueType *, int, int, int); +void PQueueUpdateUp(PQueueType *, int, int, int); +int PQueueGetMax(PQueueType *); +int PQueueSeeMax(PQueueType *); +int PQueueGetKey(PQueueType *); +int CheckHeap(PQueueType *); + +/* refine.c */ +void Refine2Way(CtrlType *, GraphType *, GraphType *, int *, float ubfactor); +void Allocate2WayPartitionMemory(CtrlType *, GraphType *); +void Compute2WayPartitionParams(CtrlType *, GraphType *); +void Project2WayPartition(CtrlType *, GraphType *); + +/* separator.c */ +void ConstructSeparator(CtrlType *, GraphType *, float); +void ConstructMinCoverSeparator0(CtrlType *, GraphType *, float); +void ConstructMinCoverSeparator(CtrlType *, GraphType *, float); + +/* sfm.c */ +void FM_2WayNodeRefine(CtrlType *, GraphType *, float, int); +void FM_2WayNodeRefineEqWgt(CtrlType *, GraphType *, int); +void FM_2WayNodeRefine_OneSided(CtrlType *, GraphType *, float, int); +void FM_2WayNodeBalance(CtrlType *, GraphType *, float); +int ComputeMaxNodeGain(int, idxtype *, idxtype *, idxtype *); + +/* srefine.c */ +void Refine2WayNode(CtrlType *, GraphType *, GraphType *, float); +void Allocate2WayNodePartitionMemory(CtrlType *, GraphType *); +void Compute2WayNodePartitionParams(CtrlType *, GraphType *); +void Project2WayNodePartition(CtrlType *, GraphType *); + +/* stat.c */ +void ComputePartitionInfo(GraphType *, int, idxtype *); +void ComputePartitionInfoBipartite(GraphType *, int, idxtype *); +void ComputePartitionBalance(GraphType *, int, idxtype *, float *); +float ComputeElementBalance(int, int, idxtype *); + +/* subdomains.c */ +void Random_KWayEdgeRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayEdgeBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); +void PrintSubDomainGraph(GraphType *, int, idxtype *); +void ComputeSubDomainGraph(GraphType *, int, idxtype *, idxtype *); +void EliminateSubDomainEdges(CtrlType *, GraphType *, int, float *); +void MoveGroupMConn(CtrlType *, GraphType *, idxtype *, idxtype *, int, int, int, idxtype *); +void EliminateComponents(CtrlType *, GraphType *, int, float *, float); +void MoveGroup(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *); + +/* timing.c */ +void InitTimers(CtrlType *); +void PrintTimers(CtrlType *); +double seconds(void); + +/* util.c */ +void errexit(char *,...); +#ifndef DMALLOC +int *imalloc(int, char *); +idxtype *idxmalloc(int, char *); +float *fmalloc(int, char *); +int *ismalloc(int, int, char *); +idxtype *idxsmalloc(int, idxtype, char *); +void *GKmalloc(int, char *); +#endif +/*void GKfree(void **,...); */ +int *iset(int n, int val, int *x); +idxtype *idxset(int n, idxtype val, idxtype *x); +float *sset(int n, float val, float *x); +int iamax(int, int *); +int idxamax(int, idxtype *); +int idxamax_strd(int, idxtype *, int); +int samax(int, float *); +int samax2(int, float *); +int idxamin(int, idxtype *); +int samin(int, float *); +int idxsum(int, idxtype *); +int idxsum_strd(int, idxtype *, int); +void idxadd(int, idxtype *, idxtype *); +int charsum(int, char *); +int isum(int, int *); +float ssum(int, float *); +float ssum_strd(int n, float *x, int); +void sscale(int n, float, float *x); +float snorm2(int, float *); +float sdot(int n, float *, float *); +void saxpy(int, float, float *, int, float *, int); +void RandomPermute(int, idxtype *, int); +double drand48(); +void srand48(long); +int ispow2(int); +void InitRandom(int); +int ilog2(int); + + + + + + + + + + +/*************************************************************** +* Programs Directory +****************************************************************/ + +/* io.c */ +void ReadGraph(GraphType *, char *, int *); +void WritePartition(char *, idxtype *, int, int); +void WriteMeshPartition(char *, int, int, idxtype *, int, idxtype *); +void WritePermutation(char *, idxtype *, int); +int CheckGraph(GraphType *); +idxtype *ReadMesh(char *, int *, int *, int *); +void WriteGraph(char *, int, idxtype *, idxtype *); + +/* smbfactor.c */ +void ComputeFillIn(GraphType *, idxtype *); +idxtype ComputeFillIn2(GraphType *, idxtype *); +int smbfct(int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *, idxtype *, idxtype *, int *); + + +/*************************************************************** +* Test Directory +****************************************************************/ +void Test_PartGraph(int, idxtype *, idxtype *); +int VerifyPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); +int VerifyWPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_PartGraphV(int, idxtype *, idxtype *); +int VerifyPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); +int VerifyWPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_PartGraphmC(int, idxtype *, idxtype *); +int VerifyPartmC(int, int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_ND(int, idxtype *, idxtype *); +int VerifyND(int, idxtype *, idxtype *); + diff --git a/thirdparty/linux/include/coin1/ThirdParty/rename.h b/thirdparty/linux/include/coin1/ThirdParty/rename.h new file mode 100644 index 0000000..d096b46 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/rename.h @@ -0,0 +1,418 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * rename.h + * + * This file contains header files + * + * Started 10/2/97 + * George + * + * $Id: rename.h,v 1.1 1998/11/27 17:59:29 karypis Exp $ + * + */ + +/* balance.c */ +#define Balance2Way __Balance2Way +#define Bnd2WayBalance __Bnd2WayBalance +#define General2WayBalance __General2WayBalance + + +/* bucketsort.c */ +#define BucketSortKeysInc __BucketSortKeysInc + + +/* ccgraph.c */ +#define CreateCoarseGraph __CreateCoarseGraph +#define CreateCoarseGraphNoMask __CreateCoarseGraphNoMask +#define CreateCoarseGraph_NVW __CreateCoarseGraph_NVW +#define SetUpCoarseGraph __SetUpCoarseGraph +#define ReAdjustMemory __ReAdjustMemory + + +/* coarsen.c */ +#define Coarsen2Way __Coarsen2Way + + +/* compress.c */ +#define CompressGraph __CompressGraph +#define PruneGraph __PruneGraph + + +/* debug.c */ +#define ComputeCut __ComputeCut +#define CheckBnd __CheckBnd +#define CheckBnd2 __CheckBnd2 +#define CheckNodeBnd __CheckNodeBnd +#define CheckRInfo __CheckRInfo +#define CheckNodePartitionParams __CheckNodePartitionParams +#define IsSeparable __IsSeparable + + +/* estmem.c */ +#define EstimateCFraction __EstimateCFraction +#define ComputeCoarseGraphSize __ComputeCoarseGraphSize + + +/* fm.c */ +#define FM_2WayEdgeRefine __FM_2WayEdgeRefine + + +/* fortran.c */ +#define Change2CNumbering __Change2CNumbering +#define Change2FNumbering __Change2FNumbering +#define Change2FNumbering2 __Change2FNumbering2 +#define Change2FNumberingOrder __Change2FNumberingOrder +#define ChangeMesh2CNumbering __ChangeMesh2CNumbering +#define ChangeMesh2FNumbering __ChangeMesh2FNumbering +#define ChangeMesh2FNumbering2 __ChangeMesh2FNumbering2 + + +/* graph.c */ +#define SetUpGraph __SetUpGraph +#define SetUpGraphKway __SetUpGraphKway +#define SetUpGraph2 __SetUpGraph2 +#define VolSetUpGraph __VolSetUpGraph +#define RandomizeGraph __RandomizeGraph +#define IsConnectedSubdomain __IsConnectedSubdomain +#define IsConnected __IsConnected +#define IsConnected2 __IsConnected2 +#define FindComponents __FindComponents + + +/* initpart.c */ +#define Init2WayPartition __Init2WayPartition +#define InitSeparator __InitSeparator +#define GrowBisection __GrowBisection +#define GrowBisectionNode __GrowBisectionNode +#define RandomBisection __RandomBisection + + +/* kmetis.c */ +#define MlevelKWayPartitioning __MlevelKWayPartitioning + + +/* kvmetis.c */ +#define MlevelVolKWayPartitioning __MlevelVolKWayPartitioning + + +/* kwayfm.c */ +#define Random_KWayEdgeRefine __Random_KWayEdgeRefine +#define Greedy_KWayEdgeRefine __Greedy_KWayEdgeRefine +#define Greedy_KWayEdgeBalance __Greedy_KWayEdgeBalance + + +/* kwayrefine.c */ +#define RefineKWay __RefineKWay +#define AllocateKWayPartitionMemory __AllocateKWayPartitionMemory +#define ComputeKWayPartitionParams __ComputeKWayPartitionParams +#define ProjectKWayPartition __ProjectKWayPartition +#define IsBalanced __IsBalanced +#define ComputeKWayBoundary __ComputeKWayBoundary +#define ComputeKWayBalanceBoundary __ComputeKWayBalanceBoundary + + +/* kwayvolfm.c */ +#define Random_KWayVolRefine __Random_KWayVolRefine +#define Random_KWayVolRefineMConn __Random_KWayVolRefineMConn +#define Greedy_KWayVolBalance __Greedy_KWayVolBalance +#define Greedy_KWayVolBalanceMConn __Greedy_KWayVolBalanceMConn +#define KWayVolUpdate __KWayVolUpdate +#define ComputeKWayVolume __ComputeKWayVolume +#define ComputeVolume __ComputeVolume +#define CheckVolKWayPartitionParams __CheckVolKWayPartitionParams +#define ComputeVolSubDomainGraph __ComputeVolSubDomainGraph +#define EliminateVolSubDomainEdges __EliminateVolSubDomainEdges + + +/* kwayvolrefine.c */ +#define RefineVolKWay __RefineVolKWay +#define AllocateVolKWayPartitionMemory __AllocateVolKWayPartitionMemory +#define ComputeVolKWayPartitionParams __ComputeVolKWayPartitionParams +#define ComputeKWayVolGains __ComputeKWayVolGains +#define ProjectVolKWayPartition __ProjectVolKWayPartition +#define ComputeVolKWayBoundary __ComputeVolKWayBoundary +#define ComputeVolKWayBalanceBoundary __ComputeVolKWayBalanceBoundary + + +/* match.c */ +#define Match_RM __Match_RM +#define Match_RM_NVW __Match_RM_NVW +#define Match_HEM __Match_HEM +#define Match_SHEM __Match_SHEM + + +/* mbalance.c */ +#define MocBalance2Way __MocBalance2Way +#define MocGeneral2WayBalance __MocGeneral2WayBalance + + +/* mbalance2.c */ +#define MocBalance2Way2 __MocBalance2Way2 +#define MocGeneral2WayBalance2 __MocGeneral2WayBalance2 +#define SelectQueue3 __SelectQueue3 + + +/* mcoarsen.c */ +#define MCCoarsen2Way __MCCoarsen2Way + + +/* memory.c */ +#define AllocateWorkSpace __AllocateWorkSpace +#define FreeWorkSpace __FreeWorkSpace +#define WspaceAvail __WspaceAvail +#define idxwspacemalloc __idxwspacemalloc +#define idxwspacefree __idxwspacefree +#define fwspacemalloc __fwspacemalloc +#define CreateGraph __CreateGraph +#define InitGraph __InitGraph +#define FreeGraph __FreeGraph + + +/* mesh.c */ +#define TRIDUALMETIS __TRIDUALMETIS +#define TETDUALMETIS __TETDUALMETIS +#define HEXDUALMETIS __HEXDUALMETIS +#define TRINODALMETIS __TRINODALMETIS +#define TETNODALMETIS __TETNODALMETIS +#define HEXNODALMETIS __HEXNODALMETIS + + +/* mfm.c */ +#define MocFM_2WayEdgeRefine __MocFM_2WayEdgeRefine +#define SelectQueue __SelectQueue +#define BetterBalance __BetterBalance +#define Compute2WayHLoadImbalance __Compute2WayHLoadImbalance +#define Compute2WayHLoadImbalanceVec __Compute2WayHLoadImbalanceVec + + +/* mfm2.c */ +#define MocFM_2WayEdgeRefine2 __MocFM_2WayEdgeRefine2 +#define SelectQueue2 __SelectQueue2 +#define IsBetter2wayBalance __IsBetter2wayBalance + + +/* mincover.c */ +#define MinCover __MinCover +#define MinCover_Augment __MinCover_Augment +#define MinCover_Decompose __MinCover_Decompose +#define MinCover_ColDFS __MinCover_ColDFS +#define MinCover_RowDFS __MinCover_RowDFS + + +/* minitpart.c */ +#define MocInit2WayPartition __MocInit2WayPartition +#define MocGrowBisection __MocGrowBisection +#define MocRandomBisection __MocRandomBisection +#define MocInit2WayBalance __MocInit2WayBalance +#define SelectQueueoneWay __SelectQueueoneWay + + +/* minitpart2.c */ +#define MocInit2WayPartition2 __MocInit2WayPartition2 +#define MocGrowBisection2 __MocGrowBisection2 +#define MocGrowBisectionNew2 __MocGrowBisectionNew2 +#define MocInit2WayBalance2 __MocInit2WayBalance2 +#define SelectQueueOneWay2 __SelectQueueOneWay2 + + +/* mkmetis.c */ +#define MCMlevelKWayPartitioning __MCMlevelKWayPartitioning + + +/* mkwayfmh.c */ +#define MCRandom_KWayEdgeRefineHorizontal __MCRandom_KWayEdgeRefineHorizontal +#define MCGreedy_KWayEdgeBalanceHorizontal __MCGreedy_KWayEdgeBalanceHorizontal +#define AreAllHVwgtsBelow __AreAllHVwgtsBelow +#define AreAllHVwgtsAbove __AreAllHVwgtsAbove +#define ComputeHKWayLoadImbalance __ComputeHKWayLoadImbalance +#define MocIsHBalanced __MocIsHBalanced +#define IsHBalanceBetterFT __IsHBalanceBetterFT +#define IsHBalanceBetterTT __IsHBalanceBetterTT + + +/* mkwayrefine.c */ +#define MocRefineKWayHorizontal __MocRefineKWayHorizontal +#define MocAllocateKWayPartitionMemory __MocAllocateKWayPartitionMemory +#define MocComputeKWayPartitionParams __MocComputeKWayPartitionParams +#define MocProjectKWayPartition __MocProjectKWayPartition +#define MocComputeKWayBalanceBoundary __MocComputeKWayBalanceBoundary + + +/* mmatch.c */ +#define MCMatch_RM __MCMatch_RM +#define MCMatch_HEM __MCMatch_HEM +#define MCMatch_SHEM __MCMatch_SHEM +#define MCMatch_SHEBM __MCMatch_SHEBM +#define MCMatch_SBHEM __MCMatch_SBHEM +#define BetterVBalance __BetterVBalance +#define AreAllVwgtsBelowFast __AreAllVwgtsBelowFast + + +/* mmd.c */ +#define genmmd __genmmd +#define mmdelm __mmdelm +#define mmdint __mmdint +#define mmdnum __mmdnum +#define mmdupd __mmdupd + + +/* mpmetis.c */ +#define MCMlevelRecursiveBisection __MCMlevelRecursiveBisection +#define MCHMlevelRecursiveBisection __MCHMlevelRecursiveBisection +#define MCMlevelEdgeBisection __MCMlevelEdgeBisection +#define MCHMlevelEdgeBisection __MCHMlevelEdgeBisection + + +/* mrefine.c */ +#define MocRefine2Way __MocRefine2Way +#define MocAllocate2WayPartitionMemory __MocAllocate2WayPartitionMemory +#define MocCompute2WayPartitionParams __MocCompute2WayPartitionParams +#define MocProject2WayPartition __MocProject2WayPartition + + +/* mrefine2.c */ +#define MocRefine2Way2 __MocRefine2Way2 + + +/* mutil.c */ +#define AreAllVwgtsBelow __AreAllVwgtsBelow +#define AreAnyVwgtsBelow __AreAnyVwgtsBelow +#define AreAllVwgtsAbove __AreAllVwgtsAbove +#define ComputeLoadImbalance __ComputeLoadImbalance +#define AreAllBelow __AreAllBelow + + +/* myqsort.c */ +#define iidxsort __iidxsort +#define iintsort __iintsort +#define ikeysort __ikeysort +#define ikeyvalsort __ikeyvalsort + + +/* ometis.c */ +#define MlevelNestedDissection __MlevelNestedDissection +#define MlevelNestedDissectionCC __MlevelNestedDissectionCC +#define MlevelNodeBisectionMultiple __MlevelNodeBisectionMultiple +#define MlevelNodeBisection __MlevelNodeBisection +#define SplitGraphOrder __SplitGraphOrder +#define MMDOrder __MMDOrder +#define SplitGraphOrderCC __SplitGraphOrderCC + + +/* parmetis.c */ +#define MlevelNestedDissectionP __MlevelNestedDissectionP + + +/* pmetis.c */ +#define MlevelRecursiveBisection __MlevelRecursiveBisection +#define MlevelEdgeBisection __MlevelEdgeBisection +#define SplitGraphPart __SplitGraphPart +#define SetUpSplitGraph __SetUpSplitGraph + + +/* pqueue.c */ +#define PQueueInit __PQueueInit +#define PQueueReset __PQueueReset +#define PQueueFree __PQueueFree +#define PQueueInsert __PQueueInsert +#define PQueueDelete __PQueueDelete +#define PQueueUpdate __PQueueUpdate +#define PQueueUpdateUp __PQueueUpdateUp +#define PQueueGetMax __PQueueGetMax +#define PQueueSeeMax __PQueueSeeMax +#define CheckHeap __CheckHeap + + +/* refine.c */ +#define Refine2Way __Refine2Way +#define Allocate2WayPartitionMemory __Allocate2WayPartitionMemory +#define Compute2WayPartitionParams __Compute2WayPartitionParams +#define Project2WayPartition __Project2WayPartition + + +/* separator.c */ +#define ConstructSeparator __ConstructSeparator +#define ConstructMinCoverSeparator0 __ConstructMinCoverSeparator0 +#define ConstructMinCoverSeparator __ConstructMinCoverSeparator + + +/* sfm.c */ +#define FM_2WayNodeRefine __FM_2WayNodeRefine +#define FM_2WayNodeRefineEqWgt __FM_2WayNodeRefineEqWgt +#define FM_2WayNodeRefine_OneSided __FM_2WayNodeRefine_OneSided +#define FM_2WayNodeBalance __FM_2WayNodeBalance +#define ComputeMaxNodeGain __ComputeMaxNodeGain + + +/* srefine.c */ +#define Refine2WayNode __Refine2WayNode +#define Allocate2WayNodePartitionMemory __Allocate2WayNodePartitionMemory +#define Compute2WayNodePartitionParams __Compute2WayNodePartitionParams +#define Project2WayNodePartition __Project2WayNodePartition + + +/* stat.c */ +#define ComputePartitionInfo __ComputePartitionInfo +#define ComputePartitionBalance __ComputePartitionBalance +#define ComputeElementBalance __ComputeElementBalance + + +/* subdomains.c */ +#define Random_KWayEdgeRefineMConn __Random_KWayEdgeRefineMConn +#define Greedy_KWayEdgeBalanceMConn __Greedy_KWayEdgeBalanceMConn +#define PrintSubDomainGraph __PrintSubDomainGraph +#define ComputeSubDomainGraph __ComputeSubDomainGraph +#define EliminateSubDomainEdges __EliminateSubDomainEdges +#define MoveGroupMConn __MoveGroupMConn +#define EliminateComponents __EliminateComponents +#define MoveGroup __MoveGroup + + +/* timing.c */ +#define InitTimers __InitTimers +#define PrintTimers __PrintTimers +#define seconds __seconds + + +/* util.c */ +#define errexit __errexit +#define GKfree __GKfree +#ifndef DMALLOC +#define imalloc __imalloc +#define idxmalloc __idxmalloc +#define fmalloc __fmalloc +#define ismalloc __ismalloc +#define idxsmalloc __idxsmalloc +#define GKmalloc __GKmalloc +#endif +#define iset __iset +#define idxset __idxset +#define sset __sset +#define iamax __iamax +#define idxamax __idxamax +#define idxamax_strd __idxamax_strd +#define samax __samax +#define samax2 __samax2 +#define idxamin __idxamin +#define samin __samin +#define idxsum __idxsum +#define idxsum_strd __idxsum_strd +#define idxadd __idxadd +#define charsum __charsum +#define isum __isum +#define ssum __ssum +#define ssum_strd __ssum_strd +#define sscale __sscale +#define snorm2 __snorm2 +#define sdot __sdot +#define saxpy __saxpy +#define RandomPermute __RandomPermute +#define ispow2 __ispow2 +#define InitRandom __InitRandom +#define ilog2 __ilog2 + + + + + diff --git a/thirdparty/linux/include/coin1/ThirdParty/struct.h b/thirdparty/linux/include/coin1/ThirdParty/struct.h new file mode 100644 index 0000000..63c7c65 --- /dev/null +++ b/thirdparty/linux/include/coin1/ThirdParty/struct.h @@ -0,0 +1,251 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * struct.h + * + * This file contains data structures for ILU routines. + * + * Started 9/26/95 + * George + * + * $Id: struct.h,v 1.1 1998/11/27 17:59:31 karypis Exp $ + */ + +/* Undefine the following #define in order to use short int as the idxtype */ +#define IDXTYPE_INT + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +typedef int idxtype; +#else +typedef short idxtype; +#endif + +#define MAXIDX (1<<8*sizeof(idxtype)-2) + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KeyValueType { + idxtype key; + idxtype val; +}; + +typedef struct KeyValueType KeyValueType; + + +/************************************************************************* +* The following data structure will hold a node of a doubly-linked list. +**************************************************************************/ +struct ListNodeType { + int id; /* The id value of the node */ + struct ListNodeType *prev, *next; /* It's a doubly-linked list */ +}; + +typedef struct ListNodeType ListNodeType; + + + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct PQueueType { + int type; /* The type of the representation used */ + int nnodes; + int maxnodes; + int mustfree; + + /* Linear array version of the data structures */ + int pgainspan, ngainspan; /* plus and negative gain span */ + int maxgain; + ListNodeType *nodes; + ListNodeType **buckets; + + /* Heap version of the data structure */ + KeyValueType *heap; + idxtype *locator; +}; + +typedef struct PQueueType PQueueType; + + +/************************************************************************* +* The following data structure stores an edge +**************************************************************************/ +struct edegreedef { + idxtype pid; + idxtype ed; +}; +typedef struct edegreedef EDegreeType; + + +/************************************************************************* +* The following data structure stores an edge for vol +**************************************************************************/ +struct vedegreedef { + idxtype pid; + idxtype ed, ned; + idxtype gv; +}; +typedef struct vedegreedef VEDegreeType; + + +/************************************************************************* +* This data structure holds various working space data +**************************************************************************/ +struct workspacedef { + idxtype *core; /* Where pairs, indices, and degrees are coming from */ + int maxcore, ccore; + + EDegreeType *edegrees; + VEDegreeType *vedegrees; + int cdegree; + + idxtype *auxcore; /* This points to the memory of the edegrees */ + + idxtype *pmat; /* An array of k^2 used for eliminating domain + connectivity in k-way refinement */ +}; + +typedef struct workspacedef WorkSpaceType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct rinfodef { + int id, ed; /* ID/ED of nodes */ + int ndegrees; /* The number of different ext-degrees */ + EDegreeType *edegrees; /* List of edges */ +}; + +typedef struct rinfodef RInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* vol-based partition +**************************************************************************/ +struct vrinfodef { + int id, ed, nid; /* ID/ED of nodes */ + int gv; /* IV/EV of nodes */ + int ndegrees; /* The number of different ext-degrees */ + VEDegreeType *edegrees; /* List of edges */ +}; + +typedef struct vrinfodef VRInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct nrinfodef { + idxtype edegrees[2]; +}; + +typedef struct nrinfodef NRInfoType; + + +/************************************************************************* +* This data structure holds the input graph +**************************************************************************/ +struct graphdef { + idxtype *gdata, *rdata; /* Memory pools for graph and refinement data. + This is where memory is allocated and used + the rest of the fields in this structure */ + + int nvtxs, nedges; /* The # of vertices and edges in the graph */ + idxtype *xadj; /* Pointers to the locally stored vertices */ + idxtype *vwgt; /* Vertex weights */ + idxtype *vsize; /* Vertex sizes for min-volume formulation */ + idxtype *adjncy; /* Array that stores the adjacency lists of nvtxs */ + idxtype *adjwgt; /* Array that stores the weights of the adjacency lists */ + + idxtype *adjwgtsum; /* The sum of the adjacency weight of each vertex */ + + idxtype *label; + + idxtype *cmap; + + /* Partition parameters */ + int mincut, minvol; + idxtype *where, *pwgts; + int nbnd; + idxtype *bndptr, *bndind; + + /* Bisection refinement parameters */ + idxtype *id, *ed; + + /* K-way refinement parameters */ + RInfoType *rinfo; + + /* K-way volume refinement parameters */ + VRInfoType *vrinfo; + + /* Node refinement information */ + NRInfoType *nrinfo; + + + /* Additional info needed by the MOC routines */ + int ncon; /* The # of constrains */ + float *nvwgt; /* Normalized vertex weights */ + float *npwgts; /* The normalized partition weights */ + + struct graphdef *coarser, *finer; +}; + +typedef struct graphdef GraphType; + + + +/************************************************************************* +* The following data type implements a timer +**************************************************************************/ +typedef double timer; + + +/************************************************************************* +* The following structure stores information used by Metis +**************************************************************************/ +struct controldef { + int CoarsenTo; /* The # of vertices in the coarsest graph */ + int dbglvl; /* Controls the debuging output of the program */ + int CType; /* The type of coarsening */ + int IType; /* The type of initial partitioning */ + int RType; /* The type of refinement */ + int maxvwgt; /* The maximum allowed weight for a vertex */ + float nmaxvwgt; /* The maximum allowed weight for a vertex for each constrain */ + int optype; /* Type of operation */ + int pfactor; /* .1*prunning factor */ + int nseps; /* The number of separators to be found during multiple bisections */ + int oflags; + + WorkSpaceType wspace; /* Work Space Informations */ + + /* Various Timers */ + timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, UncoarsenTmr, + SepTmr, RefTmr, ProjectTmr, SplitTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6; + +}; + +typedef struct controldef CtrlType; + + +/************************************************************************* +* The following data structure stores max-partition weight info for +* Vertical MOC k-way refinement +**************************************************************************/ +struct vpwgtdef { + float max[2][MAXNCON]; + int imax[2][MAXNCON]; +}; + +typedef struct vpwgtdef VPInfoType; + + + + diff --git a/thirdparty/linux/include/coin1/symphony.h b/thirdparty/linux/include/coin1/symphony.h new file mode 100644 index 0000000..d9ddace --- /dev/null +++ b/thirdparty/linux/include/coin1/symphony.h @@ -0,0 +1,327 @@ +/*===========================================================================*/ +/* */ +/* This file is part of the SYMPHONY MILP Solver Framework. */ +/* */ +/* SYMPHONY was jointly developed by Ted Ralphs (ted@lehigh.edu) and */ +/* Laci Ladanyi (ladanyi@us.ibm.com). */ +/* */ +/* (c) Copyright 2005-2015 Ted Ralphs. All Rights Reserved. */ +/* */ +/* This software is licensed under the Eclipse Public License. Please see */ +/* accompanying file for terms. */ +/* */ +/*===========================================================================*/ + +#ifndef _SYM_API_H +#define _SYM_API_H + +#define COMPILING_FOR_MASTER + +#ifdef PROTO +#undef PROTO +#endif +#define PROTO(x) x + +/***************************************************************************** + ***************************************************************************** + ************* ********** + ************* Return Values ********** + ************* ********** + ***************************************************************************** + *****************************************************************************/ + +/*----------------------- Global return codes -------------------------------*/ +#define FUNCTION_TERMINATED_NORMALLY 0 +#define FUNCTION_TERMINATED_ABNORMALLY -1 +#define ERROR__USER -100 + +/*-------------- Return codes for sym_parse_comand_line() -------------------*/ +#define ERROR__OPENING_PARAM_FILE -110 +#define ERROR__PARSING_PARAM_FILE -111 + +/*----------------- Return codes for sym_load_problem() ---------------------*/ +#define ERROR__READING_GMPL_FILE -120 +#define ERROR__READING_WARM_START_FILE -121 +#define ERROR__READING_MPS_FILE -122 +#define ERROR__READING_LP_FILE -123 + +/*-------------------- Return codes for sym_solve() -------------------------*/ +#define TM_NO_PROBLEM 225 +#define TM_NO_SOLUTION 226 +#define TM_OPTIMAL_SOLUTION_FOUND 227 +#define TM_TIME_LIMIT_EXCEEDED 228 +#define TM_NODE_LIMIT_EXCEEDED 229 +#define TM_ITERATION_LIMIT_EXCEEDED 230 +#define TM_TARGET_GAP_ACHIEVED 231 +#define TM_FOUND_FIRST_FEASIBLE 232 +#define TM_FINISHED 233 +#define TM_UNFINISHED 234 +#define TM_FEASIBLE_SOLUTION_FOUND 235 +#define TM_SIGNAL_CAUGHT 236 +#define TM_UNBOUNDED 237 +#define PREP_OPTIMAL_SOLUTION_FOUND 238 +#define PREP_NO_SOLUTION 239 +#define TM_ERROR__NO_BRANCHING_CANDIDATE -250 +#define TM_ERROR__ILLEGAL_RETURN_CODE -251 +#define TM_ERROR__NUMERICAL_INSTABILITY -252 +#define TM_ERROR__COMM_ERROR -253 +#define TM_ERROR__USER -275 +#define PREP_ERROR -276 + +/***************************************************************************** + ***************************************************************************** + ************* ********** + ************* General Constants ********** + ************* ********** + ***************************************************************************** + *****************************************************************************/ + +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef ANYONE +#define ANYONE -1 +#endif +#ifndef ANYTHING +#define ANYTHING -1 +#endif + +#define DSIZE sizeof(double) +#define ISIZE sizeof(int) +#define CSIZE sizeof(char) + +#ifndef BITSPERBYTE +#define BITSPERBYTE 8 +#endif +#ifndef BITS +#define BITS(type) (BITSPERBYTE * (int)sizeof (type)) +#endif + +#ifdef HIBITI +#undef HIBITI +#endif +#define HIBITI (1U << (BITS(int) - 1)) +#ifdef MAXINT +#undef MAXINT +#endif +#define MAXINT ((int)(~(HIBITI))) +#ifdef MAXDOUBLE +#undef MAXDOUBLE +#endif +#define MAXDOUBLE 1.79769313486231570e+308 + +#define SYM_INFINITY 1e20 + +#define BIG_DBL 1e40 + +#define SYM_MINIMIZE 0 +#define SYM_MAXIMIZE 1 + +#define MAX_NAME_SIZE 255 + +/*--------------------- return values for user-written functions ------------*/ +#define USER_ERROR -5 +#define USER_SUCCESS -4 +#define USER_NO_PP -3 +#define USER_AND_PP -2 +#define USER_DEFAULT -1 + +/*------------ search order options for multi-criteria problems -------------*/ +#define MC_FIFO 0 +#define MC_LIFO 1 + +/*------------ warm_starting options for multi-criteria problems -------------*/ +#define MC_WS_UTOPIA_FIRST 0 +#define MC_WS_UTOPIA_BOTH_FIXED 1 +#define MC_WS_UTOPIA_BOTH 2 +#define MC_WS_BEST_CLOSE 3 + +/*------------------------ compare_candidates -------------------------------*/ +#define BIGGEST_DIFFERENCE_OBJ 0 +#define LOWEST_LOW_OBJ 1 +#define HIGHEST_LOW_OBJ 2 +#define LOWEST_HIGH_OBJ 3 +#define HIGHEST_HIGH_OBJ 4 +#define HIGH_LOW_COMBINATION 9 + +/*--------------------------- select_child ----------------------------------*/ +#define PREFER_LOWER_OBJ_VALUE 0 +#define PREFER_HIGHER_OBJ_VALUE 1 + +/*-------------------- generate_cuts_in_lp defaults -------------------------*/ +#define GENERATE_CGL_CUTS 20 +#define DO_NOT_GENERATE_CGL_CUTS 21 + +/*-------------------- xxx_cuts_generation_levels ---------------------------*/ +#define DO_NOT_GENERATE -1 +#define GENERATE_DEFAULT 0 +#define GENERATE_IF_IN_ROOT 1 +#define GENERATE_ONLY_IN_ROOT 2 +#define GENERATE_ALWAYS 3 +#define GENERATE_PERIODICALLY 4 + +/*------------------------- node selection rules ----------------------------*/ +#define LOWEST_LP_FIRST 0 +#define HIGHEST_LP_FIRST 1 +#define BREADTH_FIRST_SEARCH 2 +#define DEPTH_FIRST_SEARCH 3 +#define BEST_FIRST_SEARCH 4 +#define DEPTH_FIRST_THEN_BEST_FIRST 5 + +/*-------------------------- diving_strategy --------------------------------*/ +#define BEST_ESTIMATE 0 +#define COMP_BEST_K 1 +#define COMP_BEST_K_GAP 2 + +/*--------------- parameter values for feasibility pump heuristic -----------*/ +#define SYM_FEAS_PUMP_DEFAULT 1 /* use fp using the default rules */ +#define SYM_FEAS_PUMP_REPEATED 2 /* use fp till the end of solve */ +#define SYM_FEAS_PUMP_TILL_SOL 3 /* use fp till a solution is found */ +#define SYM_FEAS_PUMP_DISABLE -1 /* dont use fp */ + +typedef struct MIPDESC MIPdesc; +typedef struct WARM_START_DESC warm_start_desc; +typedef struct SYM_ENVIRONMENT sym_environment; + +/*===========================================================================*/ +/*===================== Interface functions (master.c) ======================*/ +/*===========================================================================*/ + +void sym_version PROTO((void)); +sym_environment *sym_open_environment PROTO((void)); +int sym_set_defaults PROTO((sym_environment *env)); +int sym_parse_command_line PROTO((sym_environment *env, int argc, + char **argv)); +int sym_set_user_data PROTO((sym_environment *env, void *user)); +int sym_get_user_data PROTO((sym_environment *env, void **user)); +int sym_read_mps PROTO((sym_environment *env, char *infile)); +int sym_read_lp PROTO((sym_environment *env, char *infile)); +int sym_read_gmpl PROTO((sym_environment *env, char *modelfile, + char *datafile)); +int sym_write_mps PROTO((sym_environment *env, char *infile)); +int sym_write_lp PROTO((sym_environment *env, char *infile)); + +int sym_load_problem PROTO((sym_environment *env)); +int sym_find_initial_bounds PROTO((sym_environment *env)); + +int sym_solve PROTO((sym_environment *env)); +int sym_warm_solve PROTO((sym_environment *env)); +int sym_mc_solve PROTO((sym_environment *env)); + +int sym_create_permanent_cut_pools PROTO((sym_environment *env, int *cp_num)); +int sym_close_environment PROTO((sym_environment *env)); +int sym_explicit_load_problem PROTO((sym_environment *env, int numcols, + int numrows, int *start, int *index, + double *value, double *collb, + double *colub, char *is_int, double *obj, + double *obj2, char *rowsen, + double *rowrhs, double *rowrng, + char make_copy)); + +int sym_is_abandoned PROTO((sym_environment *env)); +int sym_is_proven_optimal PROTO((sym_environment *env)); +int sym_is_proven_primal_infeasible PROTO((sym_environment *env)); +int sym_is_iteration_limit_reached PROTO((sym_environment *env)); +int sym_is_time_limit_reached PROTO((sym_environment *env)); +int sym_is_target_gap_achieved PROTO((sym_environment *env)); + +int sym_get_status PROTO((sym_environment *env)); +int sym_get_num_cols PROTO((sym_environment *env, int *numcols)); +int sym_get_num_rows PROTO((sym_environment *env, int *numrows)); +int sym_get_num_elements PROTO((sym_environment *env, int *numelems)); +int sym_get_col_lower PROTO((sym_environment *env, double *collb)); +int sym_get_col_upper PROTO((sym_environment *env, double *colub)); +int sym_get_row_sense PROTO((sym_environment *env, char *rowsen)); +int sym_get_rhs PROTO((sym_environment *env, double *rowrhs)); +int sym_get_matrix PROTO((sym_environment *env, int *nz, int *matbeg, + int *matind, double *matval)); +int sym_get_row_range PROTO((sym_environment *env, double *rowrng)); +int sym_get_row_lower PROTO((sym_environment *env, double *rowlb)); +int sym_get_row_upper PROTO((sym_environment *env, double *rowub)); +int sym_get_obj_coeff PROTO((sym_environment *env, double *obj)); +int sym_get_obj2_coeff PROTO((sym_environment *env, double *obj2)); +int sym_get_obj_sense PROTO((sym_environment *env, int *sense)); + +int sym_is_continuous PROTO((sym_environment *env, int index, int *value)); +int sym_is_binary PROTO((sym_environment *env, int index, int *value)); +int sym_is_integer PROTO((sym_environment *env, int index, char *value)); + +double sym_get_infinity PROTO(()); + +int sym_get_col_solution PROTO((sym_environment *env, double *colsol)); +int sym_get_sp_size PROTO((sym_environment *env, int *size)); +int sym_get_sp_solution PROTO((sym_environment *env, int index, + double *colsol, double *objval)); +int sym_get_row_activity PROTO((sym_environment *env, double *rowact)); +int sym_get_obj_val PROTO((sym_environment *env, double *objval)); +int sym_get_primal_bound PROTO((sym_environment *env, double *ub)); +int sym_get_iteration_count PROTO((sym_environment *env, int *numnodes)); + +int sym_set_obj_coeff PROTO((sym_environment *env, int index, double value)); +int sym_set_obj2_coeff PROTO((sym_environment *env, int index, double value)); +int sym_set_col_lower PROTO((sym_environment *env, int index, double value)); +int sym_set_col_upper PROTO((sym_environment *env, int index, double value)); +int sym_set_row_lower PROTO((sym_environment *env, int index, double value)); +int sym_set_row_upper PROTO((sym_environment *env, int index, double value)); +int sym_set_row_type PROTO((sym_environment *env, int index, char rowsense, + double rowrhs, double rowrng)); +int sym_set_obj_sense PROTO((sym_environment *env, int sense)); +int sym_set_col_solution PROTO((sym_environment *env, double * colsol)); +int sym_set_primal_bound PROTO((sym_environment *env, double bound)); +int sym_set_continuous PROTO((sym_environment *env, int index)); +int sym_set_integer PROTO((sym_environment *env, int index)); +int sym_set_col_names PROTO((sym_environment *env, char **colname)); +int sym_add_col PROTO((sym_environment *env, int numelems, int *indices, + double *elements, double collb, double colub, + double obj, char is_int, char *name)); +int sym_add_row PROTO((sym_environment *env, int numelems, int *indices, + double *elements, char rowsen, double rowrhs, + double rowrng)); +int sym_delete_cols PROTO((sym_environment *env, int num, int * indices)); +int sym_delete_rows PROTO((sym_environment *env, int num, int * indices)); + +int sym_write_warm_start_desc PROTO((warm_start_desc *ws, char *file)); +warm_start_desc *sym_read_warm_start PROTO((char *file)); + +void sym_delete_warm_start PROTO((warm_start_desc *ws)); +warm_start_desc *sym_get_warm_start PROTO((sym_environment *env, + int copy_warm_start)); + +int sym_set_warm_start PROTO((sym_environment *env, warm_start_desc *ws)); + +int sym_set_int_param PROTO((sym_environment *env, const char *key, int value)); +int sym_set_dbl_param PROTO((sym_environment *env, const char *key, double value)); +int sym_set_str_param PROTO((sym_environment *env, const char *key, const char *value)); + +int sym_get_int_param PROTO((sym_environment *env, const char *key, int *value)); +int sym_get_dbl_param PROTO((sym_environment *env, const char *key, double *value)); +int sym_get_str_param PROTO((sym_environment *env, const char *key, char **value)); + +int sym_get_lb_for_new_rhs PROTO((sym_environment *env, int cnt, + int *new_rhs_ind, double *new_rhs_val, + double *lb_for_new_rhs)); +int sym_get_ub_for_new_rhs PROTO((sym_environment *env, int cnt, + int *new_rhs_ind, double *new_rhs_val, + double *ub_for_new_rhs)); +#if 0 +int sym_get_lb_for_new_obj PROTO((sym_environment *env, int cnt, + int *new_obj_ind, double *new_obj_val, + double *lb_for_new_obj)); +#endif +int sym_get_ub_for_new_obj PROTO((sym_environment *env, int cnt, + int *new_obj_ind, double *new_obj_val, + double *ub_for_new_obj)); + +warm_start_desc *sym_create_copy_warm_start PROTO((warm_start_desc * ws)); +MIPdesc *sym_create_copy_mip_desc PROTO((sym_environment *env)); +MIPdesc *sym_get_presolved_mip_desc PROTO((sym_environment *env)); +sym_environment * sym_create_copy_environment PROTO((sym_environment *env)); + +int sym_test PROTO((sym_environment *env, int argc, char **argv, + int *test_status)); + +#endif diff --git a/thirdparty/linux/lib/x64/libCbc.so b/thirdparty/linux/lib/x64/libCbc.so new file mode 120000 index 0000000..9a7f60f --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbc.so @@ -0,0 +1 @@ +libCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCbc.so.3 b/thirdparty/linux/lib/x64/libCbc.so.3 new file mode 120000 index 0000000..9a7f60f --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbc.so.3 @@ -0,0 +1 @@ +libCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCbc.so.3.9.6 b/thirdparty/linux/lib/x64/libCbc.so.3.9.6 Binary files differnew file mode 100755 index 0000000..73f9ed7 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbc.so.3.9.6 diff --git a/thirdparty/linux/lib/x64/libCbc.so.3.9.7 b/thirdparty/linux/lib/x64/libCbc.so.3.9.7 Binary files differnew file mode 100755 index 0000000..36fadc6 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbc.so.3.9.7 diff --git a/thirdparty/linux/lib/x64/libCbcSolver.so b/thirdparty/linux/lib/x64/libCbcSolver.so new file mode 120000 index 0000000..4cdc644 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbcSolver.so @@ -0,0 +1 @@ +libCbcSolver.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCbcSolver.so.3 b/thirdparty/linux/lib/x64/libCbcSolver.so.3 new file mode 120000 index 0000000..4cdc644 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbcSolver.so.3 @@ -0,0 +1 @@ +libCbcSolver.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.6 b/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.6 Binary files differnew file mode 100755 index 0000000..d2d4e14 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.6 diff --git a/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.7 b/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.7 Binary files differnew file mode 100755 index 0000000..fd22e8f --- /dev/null +++ b/thirdparty/linux/lib/x64/libCbcSolver.so.3.9.7 diff --git a/thirdparty/linux/lib/x64/libCgl.so b/thirdparty/linux/lib/x64/libCgl.so index d21b1e2..22b7ba2 120000 --- a/thirdparty/linux/lib/x64/libCgl.so +++ b/thirdparty/linux/lib/x64/libCgl.so @@ -1 +1 @@ -libCgl.so.1.9.4
\ No newline at end of file +libCgl.so.1.9.9
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCgl.so.1 b/thirdparty/linux/lib/x64/libCgl.so.1 index d21b1e2..22b7ba2 120000 --- a/thirdparty/linux/lib/x64/libCgl.so.1 +++ b/thirdparty/linux/lib/x64/libCgl.so.1 @@ -1 +1 @@ -libCgl.so.1.9.4
\ No newline at end of file +libCgl.so.1.9.9
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCgl.so.1.9.4 b/thirdparty/linux/lib/x64/libCgl.so.1.9.4 Binary files differdeleted file mode 100755 index 4297d32..0000000 --- a/thirdparty/linux/lib/x64/libCgl.so.1.9.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libCgl.so.1.9.7 b/thirdparty/linux/lib/x64/libCgl.so.1.9.7 new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCgl.so.1.9.7 diff --git a/thirdparty/linux/lib/x64/libCgl.so.1.9.9 b/thirdparty/linux/lib/x64/libCgl.so.1.9.9 Binary files differnew file mode 100755 index 0000000..00a9236 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCgl.so.1.9.9 diff --git a/thirdparty/linux/lib/x64/libClp.so b/thirdparty/linux/lib/x64/libClp.so index f5fb53c..cbe7f38 120000 --- a/thirdparty/linux/lib/x64/libClp.so +++ b/thirdparty/linux/lib/x64/libClp.so @@ -1 +1 @@ -libClp.so.1.13.6
\ No newline at end of file +libClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClp.so.1 b/thirdparty/linux/lib/x64/libClp.so.1 index f5fb53c..cbe7f38 120000 --- a/thirdparty/linux/lib/x64/libClp.so.1 +++ b/thirdparty/linux/lib/x64/libClp.so.1 @@ -1 +1 @@ -libClp.so.1.13.6
\ No newline at end of file +libClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClp.so.1.13.10 b/thirdparty/linux/lib/x64/libClp.so.1.13.10 Binary files differnew file mode 100755 index 0000000..58e02c0 --- /dev/null +++ b/thirdparty/linux/lib/x64/libClp.so.1.13.10 diff --git a/thirdparty/linux/lib/x64/libClp.so.1.13.6 b/thirdparty/linux/lib/x64/libClp.so.1.13.6 Binary files differdeleted file mode 100755 index d6a8148..0000000 --- a/thirdparty/linux/lib/x64/libClp.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libClpSolver.so b/thirdparty/linux/lib/x64/libClpSolver.so index 81f032c..5f6f18c 120000 --- a/thirdparty/linux/lib/x64/libClpSolver.so +++ b/thirdparty/linux/lib/x64/libClpSolver.so @@ -1 +1 @@ -libClpSolver.so.1.13.6
\ No newline at end of file +libClpSolver.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClpSolver.so.1 b/thirdparty/linux/lib/x64/libClpSolver.so.1 index 81f032c..5f6f18c 120000 --- a/thirdparty/linux/lib/x64/libClpSolver.so.1 +++ b/thirdparty/linux/lib/x64/libClpSolver.so.1 @@ -1 +1 @@ -libClpSolver.so.1.13.6
\ No newline at end of file +libClpSolver.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libClpSolver.so.1.13.10 b/thirdparty/linux/lib/x64/libClpSolver.so.1.13.10 Binary files differnew file mode 100755 index 0000000..f4d9942 --- /dev/null +++ b/thirdparty/linux/lib/x64/libClpSolver.so.1.13.10 diff --git a/thirdparty/linux/lib/x64/libClpSolver.so.1.13.6 b/thirdparty/linux/lib/x64/libClpSolver.so.1.13.6 Binary files differdeleted file mode 100755 index 149c1d9..0000000 --- a/thirdparty/linux/lib/x64/libClpSolver.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libCoinUtils.so b/thirdparty/linux/lib/x64/libCoinUtils.so index 963c869..bebfcc3 120000 --- a/thirdparty/linux/lib/x64/libCoinUtils.so +++ b/thirdparty/linux/lib/x64/libCoinUtils.so @@ -1 +1 @@ -libCoinUtils.so.3.10.6
\ No newline at end of file +libCoinUtils.so.3.10.13
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCoinUtils.so.3 b/thirdparty/linux/lib/x64/libCoinUtils.so.3 index 963c869..bebfcc3 120000 --- a/thirdparty/linux/lib/x64/libCoinUtils.so.3 +++ b/thirdparty/linux/lib/x64/libCoinUtils.so.3 @@ -1 +1 @@ -libCoinUtils.so.3.10.6
\ No newline at end of file +libCoinUtils.so.3.10.13
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.13 b/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.13 Binary files differnew file mode 100755 index 0000000..04722d9 --- /dev/null +++ b/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.13 diff --git a/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.6 b/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.6 Binary files differdeleted file mode 100755 index e4cb5a6..0000000 --- a/thirdparty/linux/lib/x64/libCoinUtils.so.3.10.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libOsi.so b/thirdparty/linux/lib/x64/libOsi.so index 550dde9..14d3e4c 120000 --- a/thirdparty/linux/lib/x64/libOsi.so +++ b/thirdparty/linux/lib/x64/libOsi.so @@ -1 +1 @@ -libOsi.so.1.12.4
\ No newline at end of file +libOsi.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsi.so.1 b/thirdparty/linux/lib/x64/libOsi.so.1 index 550dde9..14d3e4c 120000 --- a/thirdparty/linux/lib/x64/libOsi.so.1 +++ b/thirdparty/linux/lib/x64/libOsi.so.1 @@ -1 +1 @@ -libOsi.so.1.12.4
\ No newline at end of file +libOsi.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsi.so.1.12.4 b/thirdparty/linux/lib/x64/libOsi.so.1.12.4 Binary files differdeleted file mode 100755 index 8f1d85e..0000000 --- a/thirdparty/linux/lib/x64/libOsi.so.1.12.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libOsi.so.1.12.8 b/thirdparty/linux/lib/x64/libOsi.so.1.12.8 Binary files differnew file mode 100755 index 0000000..4e99d91 --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsi.so.1.12.8 diff --git a/thirdparty/linux/lib/x64/libOsiCbc.so b/thirdparty/linux/lib/x64/libOsiCbc.so new file mode 120000 index 0000000..2133c10 --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiCbc.so @@ -0,0 +1 @@ +libOsiCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiCbc.so.3 b/thirdparty/linux/lib/x64/libOsiCbc.so.3 new file mode 120000 index 0000000..2133c10 --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiCbc.so.3 @@ -0,0 +1 @@ +libOsiCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.6 b/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.6 Binary files differnew file mode 100755 index 0000000..563b25f --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.6 diff --git a/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.7 b/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.7 Binary files differnew file mode 100755 index 0000000..3b0a7da --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiCbc.so.3.9.7 diff --git a/thirdparty/linux/lib/x64/libOsiClp.so b/thirdparty/linux/lib/x64/libOsiClp.so index 9a8ab31..8d74df2 120000 --- a/thirdparty/linux/lib/x64/libOsiClp.so +++ b/thirdparty/linux/lib/x64/libOsiClp.so @@ -1 +1 @@ -libOsiClp.so.1.13.6
\ No newline at end of file +libOsiClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiClp.so.1 b/thirdparty/linux/lib/x64/libOsiClp.so.1 index 9a8ab31..8d74df2 120000 --- a/thirdparty/linux/lib/x64/libOsiClp.so.1 +++ b/thirdparty/linux/lib/x64/libOsiClp.so.1 @@ -1 +1 @@ -libOsiClp.so.1.13.6
\ No newline at end of file +libOsiClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiClp.so.1.13.10 b/thirdparty/linux/lib/x64/libOsiClp.so.1.13.10 Binary files differnew file mode 100755 index 0000000..c26c5bf --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiClp.so.1.13.10 diff --git a/thirdparty/linux/lib/x64/libOsiClp.so.1.13.6 b/thirdparty/linux/lib/x64/libOsiClp.so.1.13.6 Binary files differdeleted file mode 100755 index e009b1f..0000000 --- a/thirdparty/linux/lib/x64/libOsiClp.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libOsiCommonTests.so b/thirdparty/linux/lib/x64/libOsiCommonTests.so index c78e00d..1362055 120000 --- a/thirdparty/linux/lib/x64/libOsiCommonTests.so +++ b/thirdparty/linux/lib/x64/libOsiCommonTests.so @@ -1 +1 @@ -libOsiCommonTests.so.1.12.4
\ No newline at end of file +libOsiCommonTests.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiCommonTests.so.1 b/thirdparty/linux/lib/x64/libOsiCommonTests.so.1 index c78e00d..1362055 120000 --- a/thirdparty/linux/lib/x64/libOsiCommonTests.so.1 +++ b/thirdparty/linux/lib/x64/libOsiCommonTests.so.1 @@ -1 +1 @@ -libOsiCommonTests.so.1.12.4
\ No newline at end of file +libOsiCommonTests.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.4 b/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.4 Binary files differdeleted file mode 100755 index 30254e2..0000000 --- a/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.8 b/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.8 Binary files differnew file mode 100755 index 0000000..b778f64 --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiCommonTests.so.1.12.8 diff --git a/thirdparty/linux/lib/x64/libOsiSym.so b/thirdparty/linux/lib/x64/libOsiSym.so index 582a52b..5e45b01 120000 --- a/thirdparty/linux/lib/x64/libOsiSym.so +++ b/thirdparty/linux/lib/x64/libOsiSym.so @@ -1 +1 @@ -libOsiSym.so.3.6.10
\ No newline at end of file +libOsiSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiSym.so.3 b/thirdparty/linux/lib/x64/libOsiSym.so.3 index 582a52b..5e45b01 120000 --- a/thirdparty/linux/lib/x64/libOsiSym.so.3 +++ b/thirdparty/linux/lib/x64/libOsiSym.so.3 @@ -1 +1 @@ -libOsiSym.so.3.6.10
\ No newline at end of file +libOsiSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libOsiSym.so.3.6.10 b/thirdparty/linux/lib/x64/libOsiSym.so.3.6.10 Binary files differdeleted file mode 100755 index ca3dc9e..0000000 --- a/thirdparty/linux/lib/x64/libOsiSym.so.3.6.10 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libOsiSym.so.3.6.16 b/thirdparty/linux/lib/x64/libOsiSym.so.3.6.16 Binary files differnew file mode 100755 index 0000000..ab91c76 --- /dev/null +++ b/thirdparty/linux/lib/x64/libOsiSym.so.3.6.16 diff --git a/thirdparty/linux/lib/x64/libSym.so b/thirdparty/linux/lib/x64/libSym.so index 962910f..4f4c630 120000 --- a/thirdparty/linux/lib/x64/libSym.so +++ b/thirdparty/linux/lib/x64/libSym.so @@ -1 +1 @@ -libSym.so.3.6.10
\ No newline at end of file +libSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libSym.so.3 b/thirdparty/linux/lib/x64/libSym.so.3 index 962910f..4f4c630 120000 --- a/thirdparty/linux/lib/x64/libSym.so.3 +++ b/thirdparty/linux/lib/x64/libSym.so.3 @@ -1 +1 @@ -libSym.so.3.6.10
\ No newline at end of file +libSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libSym.so.3.6.10 b/thirdparty/linux/lib/x64/libSym.so.3.6.10 Binary files differdeleted file mode 100755 index 76c62d0..0000000 --- a/thirdparty/linux/lib/x64/libSym.so.3.6.10 +++ /dev/null diff --git a/thirdparty/linux/lib/x64/libSym.so.3.6.16 b/thirdparty/linux/lib/x64/libSym.so.3.6.16 Binary files differnew file mode 100755 index 0000000..e961055 --- /dev/null +++ b/thirdparty/linux/lib/x64/libSym.so.3.6.16 diff --git a/thirdparty/linux/lib/x64/libbonmin.so b/thirdparty/linux/lib/x64/libbonmin.so new file mode 120000 index 0000000..09093f0 --- /dev/null +++ b/thirdparty/linux/lib/x64/libbonmin.so @@ -0,0 +1 @@ +libbonmin.so.4.8.4
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libbonmin.so.4 b/thirdparty/linux/lib/x64/libbonmin.so.4 new file mode 120000 index 0000000..09093f0 --- /dev/null +++ b/thirdparty/linux/lib/x64/libbonmin.so.4 @@ -0,0 +1 @@ +libbonmin.so.4.8.4
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libbonmin.so.4.8.4 b/thirdparty/linux/lib/x64/libbonmin.so.4.8.4 Binary files differnew file mode 100755 index 0000000..2cf0d2e --- /dev/null +++ b/thirdparty/linux/lib/x64/libbonmin.so.4.8.4 diff --git a/thirdparty/linux/lib/x64/libcoinblas.so b/thirdparty/linux/lib/x64/libcoinblas.so index ddd18ab..fed1b05 120000 --- a/thirdparty/linux/lib/x64/libcoinblas.so +++ b/thirdparty/linux/lib/x64/libcoinblas.so @@ -1 +1 @@ -libcoinblas.so.1.4.4
\ No newline at end of file +libcoinblas.so.1.4.6
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinblas.so.1 b/thirdparty/linux/lib/x64/libcoinblas.so.1 index ddd18ab..fed1b05 120000 --- a/thirdparty/linux/lib/x64/libcoinblas.so.1 +++ b/thirdparty/linux/lib/x64/libcoinblas.so.1 @@ -1 +1 @@ -libcoinblas.so.1.4.4
\ No newline at end of file +libcoinblas.so.1.4.6
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinblas.so.1.4.4 b/thirdparty/linux/lib/x64/libcoinblas.so.1.4.4 Binary files differindex 9829460..7926a51 100755 --- a/thirdparty/linux/lib/x64/libcoinblas.so.1.4.4 +++ b/thirdparty/linux/lib/x64/libcoinblas.so.1.4.4 diff --git a/thirdparty/linux/lib/x64/libcoinblas.so.1.4.6 b/thirdparty/linux/lib/x64/libcoinblas.so.1.4.6 Binary files differnew file mode 100755 index 0000000..7926a51 --- /dev/null +++ b/thirdparty/linux/lib/x64/libcoinblas.so.1.4.6 diff --git a/thirdparty/linux/lib/x64/libcoinlapack.so b/thirdparty/linux/lib/x64/libcoinlapack.so index 68af160..5304557 120000 --- a/thirdparty/linux/lib/x64/libcoinlapack.so +++ b/thirdparty/linux/lib/x64/libcoinlapack.so @@ -1 +1 @@ -libcoinlapack.so.1.5.4
\ No newline at end of file +libcoinlapack.so.1.5.6
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinlapack.so.1 b/thirdparty/linux/lib/x64/libcoinlapack.so.1 index 68af160..5304557 120000 --- a/thirdparty/linux/lib/x64/libcoinlapack.so.1 +++ b/thirdparty/linux/lib/x64/libcoinlapack.so.1 @@ -1 +1 @@ -libcoinlapack.so.1.5.4
\ No newline at end of file +libcoinlapack.so.1.5.6
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.4 b/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.4 Binary files differindex 535483d..ca70491 100755 --- a/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.4 +++ b/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.4 diff --git a/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.6 b/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.6 Binary files differnew file mode 100755 index 0000000..ca70491 --- /dev/null +++ b/thirdparty/linux/lib/x64/libcoinlapack.so.1.5.6 diff --git a/thirdparty/linux/lib/x64/libcoinmumps.so b/thirdparty/linux/lib/x64/libcoinmumps.so index c2d14a9..76e48e0 120000 --- a/thirdparty/linux/lib/x64/libcoinmumps.so +++ b/thirdparty/linux/lib/x64/libcoinmumps.so @@ -1 +1 @@ -libcoinmumps.so.1.5.4
\ No newline at end of file +libcoinmumps.so.1.6.0
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinmumps.so.1 b/thirdparty/linux/lib/x64/libcoinmumps.so.1 index c2d14a9..76e48e0 120000 --- a/thirdparty/linux/lib/x64/libcoinmumps.so.1 +++ b/thirdparty/linux/lib/x64/libcoinmumps.so.1 @@ -1 +1 @@ -libcoinmumps.so.1.5.4
\ No newline at end of file +libcoinmumps.so.1.6.0
\ No newline at end of file diff --git a/thirdparty/linux/lib/x64/libcoinmumps.so.1.5.4 b/thirdparty/linux/lib/x64/libcoinmumps.so.1.5.4 Binary files differindex 03e6e54..a15648d 100755 --- a/thirdparty/linux/lib/x64/libcoinmumps.so.1.5.4 +++ b/thirdparty/linux/lib/x64/libcoinmumps.so.1.5.4 diff --git a/thirdparty/linux/lib/x64/libcoinmumps.so.1.6.0 b/thirdparty/linux/lib/x64/libcoinmumps.so.1.6.0 Binary files differindex 03e6e54..a15648d 100755 --- a/thirdparty/linux/lib/x64/libcoinmumps.so.1.6.0 +++ b/thirdparty/linux/lib/x64/libcoinmumps.so.1.6.0 diff --git a/thirdparty/linux/lib/x64/libecos.so b/thirdparty/linux/lib/x64/libecos.so Binary files differnew file mode 100755 index 0000000..7c939e9 --- /dev/null +++ b/thirdparty/linux/lib/x64/libecos.so diff --git a/thirdparty/linux/lib/x64/libipopt.so b/thirdparty/linux/lib/x64/libipopt.so Binary files differindex e4c262e..1754e00 100755..120000 --- a/thirdparty/linux/lib/x64/libipopt.so +++ b/thirdparty/linux/lib/x64/libipopt.so diff --git a/thirdparty/linux/lib/x64/libipopt.so.0 b/thirdparty/linux/lib/x64/libipopt.so.0 Binary files differnew file mode 100755 index 0000000..98ad1d4 --- /dev/null +++ b/thirdparty/linux/lib/x64/libipopt.so.0 diff --git a/thirdparty/linux/lib/x64/libipopt.so.0.0.0 b/thirdparty/linux/lib/x64/libipopt.so.0.0.0 Binary files differnew file mode 100755 index 0000000..98ad1d4 --- /dev/null +++ b/thirdparty/linux/lib/x64/libipopt.so.0.0.0 diff --git a/thirdparty/linux/lib/x64/libipopt.so.1 b/thirdparty/linux/lib/x64/libipopt.so.1 Binary files differindex e4c262e..1754e00 100755..120000 --- a/thirdparty/linux/lib/x64/libipopt.so.1 +++ b/thirdparty/linux/lib/x64/libipopt.so.1 diff --git a/thirdparty/linux/lib/x64/libipopt.so.1.10.7 b/thirdparty/linux/lib/x64/libipopt.so.1.10.7 Binary files differindex e4c262e..15b7c4e 100755 --- a/thirdparty/linux/lib/x64/libipopt.so.1.10.7 +++ b/thirdparty/linux/lib/x64/libipopt.so.1.10.7 diff --git a/thirdparty/linux/lib/x86/libCbc.so b/thirdparty/linux/lib/x86/libCbc.so new file mode 120000 index 0000000..9a7f60f --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbc.so @@ -0,0 +1 @@ +libCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCbc.so.3 b/thirdparty/linux/lib/x86/libCbc.so.3 new file mode 120000 index 0000000..9a7f60f --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbc.so.3 @@ -0,0 +1 @@ +libCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCbc.so.3.9.7 b/thirdparty/linux/lib/x86/libCbc.so.3.9.7 Binary files differnew file mode 100755 index 0000000..67c97bc --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbc.so.3.9.7 diff --git a/thirdparty/linux/lib/x86/libCbcSolver.so b/thirdparty/linux/lib/x86/libCbcSolver.so new file mode 120000 index 0000000..4cdc644 --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbcSolver.so @@ -0,0 +1 @@ +libCbcSolver.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCbcSolver.so.3 b/thirdparty/linux/lib/x86/libCbcSolver.so.3 new file mode 120000 index 0000000..4cdc644 --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbcSolver.so.3 @@ -0,0 +1 @@ +libCbcSolver.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCbcSolver.so.3.9.7 b/thirdparty/linux/lib/x86/libCbcSolver.so.3.9.7 Binary files differnew file mode 100755 index 0000000..b02972a --- /dev/null +++ b/thirdparty/linux/lib/x86/libCbcSolver.so.3.9.7 diff --git a/thirdparty/linux/lib/x86/libCgl.so b/thirdparty/linux/lib/x86/libCgl.so index d21b1e2..22b7ba2 120000 --- a/thirdparty/linux/lib/x86/libCgl.so +++ b/thirdparty/linux/lib/x86/libCgl.so @@ -1 +1 @@ -libCgl.so.1.9.4
\ No newline at end of file +libCgl.so.1.9.9
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCgl.so.1 b/thirdparty/linux/lib/x86/libCgl.so.1 index d21b1e2..22b7ba2 120000 --- a/thirdparty/linux/lib/x86/libCgl.so.1 +++ b/thirdparty/linux/lib/x86/libCgl.so.1 @@ -1 +1 @@ -libCgl.so.1.9.4
\ No newline at end of file +libCgl.so.1.9.9
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCgl.so.1.9.4 b/thirdparty/linux/lib/x86/libCgl.so.1.9.4 Binary files differdeleted file mode 100755 index 7334f5c..0000000 --- a/thirdparty/linux/lib/x86/libCgl.so.1.9.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libCgl.so.1.9.9 b/thirdparty/linux/lib/x86/libCgl.so.1.9.9 Binary files differnew file mode 100755 index 0000000..0726df5 --- /dev/null +++ b/thirdparty/linux/lib/x86/libCgl.so.1.9.9 diff --git a/thirdparty/linux/lib/x86/libClp.so b/thirdparty/linux/lib/x86/libClp.so index f5fb53c..cbe7f38 120000 --- a/thirdparty/linux/lib/x86/libClp.so +++ b/thirdparty/linux/lib/x86/libClp.so @@ -1 +1 @@ -libClp.so.1.13.6
\ No newline at end of file +libClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libClp.so.1 b/thirdparty/linux/lib/x86/libClp.so.1 index f5fb53c..cbe7f38 120000 --- a/thirdparty/linux/lib/x86/libClp.so.1 +++ b/thirdparty/linux/lib/x86/libClp.so.1 @@ -1 +1 @@ -libClp.so.1.13.6
\ No newline at end of file +libClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libClp.so.1.13.10 b/thirdparty/linux/lib/x86/libClp.so.1.13.10 Binary files differnew file mode 100755 index 0000000..d8d05e3 --- /dev/null +++ b/thirdparty/linux/lib/x86/libClp.so.1.13.10 diff --git a/thirdparty/linux/lib/x86/libClp.so.1.13.6 b/thirdparty/linux/lib/x86/libClp.so.1.13.6 Binary files differdeleted file mode 100755 index 2e97e66..0000000 --- a/thirdparty/linux/lib/x86/libClp.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libClpSolver.so b/thirdparty/linux/lib/x86/libClpSolver.so index 81f032c..5f6f18c 120000 --- a/thirdparty/linux/lib/x86/libClpSolver.so +++ b/thirdparty/linux/lib/x86/libClpSolver.so @@ -1 +1 @@ -libClpSolver.so.1.13.6
\ No newline at end of file +libClpSolver.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libClpSolver.so.1 b/thirdparty/linux/lib/x86/libClpSolver.so.1 index 81f032c..5f6f18c 120000 --- a/thirdparty/linux/lib/x86/libClpSolver.so.1 +++ b/thirdparty/linux/lib/x86/libClpSolver.so.1 @@ -1 +1 @@ -libClpSolver.so.1.13.6
\ No newline at end of file +libClpSolver.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libClpSolver.so.1.13.10 b/thirdparty/linux/lib/x86/libClpSolver.so.1.13.10 Binary files differnew file mode 100755 index 0000000..1798eb1 --- /dev/null +++ b/thirdparty/linux/lib/x86/libClpSolver.so.1.13.10 diff --git a/thirdparty/linux/lib/x86/libClpSolver.so.1.13.6 b/thirdparty/linux/lib/x86/libClpSolver.so.1.13.6 Binary files differdeleted file mode 100755 index 136dd90..0000000 --- a/thirdparty/linux/lib/x86/libClpSolver.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libCoinUtils.so b/thirdparty/linux/lib/x86/libCoinUtils.so index 963c869..bebfcc3 120000 --- a/thirdparty/linux/lib/x86/libCoinUtils.so +++ b/thirdparty/linux/lib/x86/libCoinUtils.so @@ -1 +1 @@ -libCoinUtils.so.3.10.6
\ No newline at end of file +libCoinUtils.so.3.10.13
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCoinUtils.so.3 b/thirdparty/linux/lib/x86/libCoinUtils.so.3 index 963c869..bebfcc3 120000 --- a/thirdparty/linux/lib/x86/libCoinUtils.so.3 +++ b/thirdparty/linux/lib/x86/libCoinUtils.so.3 @@ -1 +1 @@ -libCoinUtils.so.3.10.6
\ No newline at end of file +libCoinUtils.so.3.10.13
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.13 b/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.13 Binary files differnew file mode 100755 index 0000000..eba898c --- /dev/null +++ b/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.13 diff --git a/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.6 b/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.6 Binary files differdeleted file mode 100755 index ee2c99c..0000000 --- a/thirdparty/linux/lib/x86/libCoinUtils.so.3.10.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libOsi.so b/thirdparty/linux/lib/x86/libOsi.so index 550dde9..14d3e4c 120000 --- a/thirdparty/linux/lib/x86/libOsi.so +++ b/thirdparty/linux/lib/x86/libOsi.so @@ -1 +1 @@ -libOsi.so.1.12.4
\ No newline at end of file +libOsi.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsi.so.1 b/thirdparty/linux/lib/x86/libOsi.so.1 index 550dde9..14d3e4c 120000 --- a/thirdparty/linux/lib/x86/libOsi.so.1 +++ b/thirdparty/linux/lib/x86/libOsi.so.1 @@ -1 +1 @@ -libOsi.so.1.12.4
\ No newline at end of file +libOsi.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsi.so.1.12.4 b/thirdparty/linux/lib/x86/libOsi.so.1.12.4 Binary files differdeleted file mode 100755 index 76e8fc6..0000000 --- a/thirdparty/linux/lib/x86/libOsi.so.1.12.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libOsi.so.1.12.8 b/thirdparty/linux/lib/x86/libOsi.so.1.12.8 Binary files differnew file mode 100755 index 0000000..d6c382a --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsi.so.1.12.8 diff --git a/thirdparty/linux/lib/x86/libOsiCbc.so b/thirdparty/linux/lib/x86/libOsiCbc.so new file mode 120000 index 0000000..2133c10 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiCbc.so @@ -0,0 +1 @@ +libOsiCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiCbc.so.3 b/thirdparty/linux/lib/x86/libOsiCbc.so.3 new file mode 120000 index 0000000..2133c10 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiCbc.so.3 @@ -0,0 +1 @@ +libOsiCbc.so.3.9.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiCbc.so.3.9.7 b/thirdparty/linux/lib/x86/libOsiCbc.so.3.9.7 Binary files differnew file mode 100755 index 0000000..54f2d25 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiCbc.so.3.9.7 diff --git a/thirdparty/linux/lib/x86/libOsiClp.so b/thirdparty/linux/lib/x86/libOsiClp.so index 9a8ab31..8d74df2 120000 --- a/thirdparty/linux/lib/x86/libOsiClp.so +++ b/thirdparty/linux/lib/x86/libOsiClp.so @@ -1 +1 @@ -libOsiClp.so.1.13.6
\ No newline at end of file +libOsiClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiClp.so.1 b/thirdparty/linux/lib/x86/libOsiClp.so.1 index 9a8ab31..8d74df2 120000 --- a/thirdparty/linux/lib/x86/libOsiClp.so.1 +++ b/thirdparty/linux/lib/x86/libOsiClp.so.1 @@ -1 +1 @@ -libOsiClp.so.1.13.6
\ No newline at end of file +libOsiClp.so.1.13.10
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiClp.so.1.13.10 b/thirdparty/linux/lib/x86/libOsiClp.so.1.13.10 Binary files differnew file mode 100755 index 0000000..b8562e7 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiClp.so.1.13.10 diff --git a/thirdparty/linux/lib/x86/libOsiClp.so.1.13.6 b/thirdparty/linux/lib/x86/libOsiClp.so.1.13.6 Binary files differdeleted file mode 100755 index fc76378..0000000 --- a/thirdparty/linux/lib/x86/libOsiClp.so.1.13.6 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libOsiCommonTests.so b/thirdparty/linux/lib/x86/libOsiCommonTests.so index c78e00d..1362055 120000 --- a/thirdparty/linux/lib/x86/libOsiCommonTests.so +++ b/thirdparty/linux/lib/x86/libOsiCommonTests.so @@ -1 +1 @@ -libOsiCommonTests.so.1.12.4
\ No newline at end of file +libOsiCommonTests.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiCommonTests.so.1 b/thirdparty/linux/lib/x86/libOsiCommonTests.so.1 index c78e00d..1362055 120000 --- a/thirdparty/linux/lib/x86/libOsiCommonTests.so.1 +++ b/thirdparty/linux/lib/x86/libOsiCommonTests.so.1 @@ -1 +1 @@ -libOsiCommonTests.so.1.12.4
\ No newline at end of file +libOsiCommonTests.so.1.12.8
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.4 b/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.4 Binary files differdeleted file mode 100755 index 0faa2c7..0000000 --- a/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.8 b/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.8 Binary files differnew file mode 100755 index 0000000..b27c0a7 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiCommonTests.so.1.12.8 diff --git a/thirdparty/linux/lib/x86/libOsiSym.so b/thirdparty/linux/lib/x86/libOsiSym.so index 582a52b..5e45b01 120000 --- a/thirdparty/linux/lib/x86/libOsiSym.so +++ b/thirdparty/linux/lib/x86/libOsiSym.so @@ -1 +1 @@ -libOsiSym.so.3.6.10
\ No newline at end of file +libOsiSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiSym.so.3 b/thirdparty/linux/lib/x86/libOsiSym.so.3 index 582a52b..5e45b01 120000 --- a/thirdparty/linux/lib/x86/libOsiSym.so.3 +++ b/thirdparty/linux/lib/x86/libOsiSym.so.3 @@ -1 +1 @@ -libOsiSym.so.3.6.10
\ No newline at end of file +libOsiSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libOsiSym.so.3.6.10 b/thirdparty/linux/lib/x86/libOsiSym.so.3.6.10 Binary files differdeleted file mode 100755 index 2127cf9..0000000 --- a/thirdparty/linux/lib/x86/libOsiSym.so.3.6.10 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libOsiSym.so.3.6.16 b/thirdparty/linux/lib/x86/libOsiSym.so.3.6.16 Binary files differnew file mode 100755 index 0000000..ad82801 --- /dev/null +++ b/thirdparty/linux/lib/x86/libOsiSym.so.3.6.16 diff --git a/thirdparty/linux/lib/x86/libSym.so b/thirdparty/linux/lib/x86/libSym.so index 962910f..4f4c630 120000 --- a/thirdparty/linux/lib/x86/libSym.so +++ b/thirdparty/linux/lib/x86/libSym.so @@ -1 +1 @@ -libSym.so.3.6.10
\ No newline at end of file +libSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libSym.so.3 b/thirdparty/linux/lib/x86/libSym.so.3 index 962910f..4f4c630 120000 --- a/thirdparty/linux/lib/x86/libSym.so.3 +++ b/thirdparty/linux/lib/x86/libSym.so.3 @@ -1 +1 @@ -libSym.so.3.6.10
\ No newline at end of file +libSym.so.3.6.16
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libSym.so.3.6.10 b/thirdparty/linux/lib/x86/libSym.so.3.6.10 Binary files differdeleted file mode 100755 index 93600a6..0000000 --- a/thirdparty/linux/lib/x86/libSym.so.3.6.10 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libSym.so.3.6.16 b/thirdparty/linux/lib/x86/libSym.so.3.6.16 Binary files differnew file mode 100755 index 0000000..0b62692 --- /dev/null +++ b/thirdparty/linux/lib/x86/libSym.so.3.6.16 diff --git a/thirdparty/linux/lib/x86/libbonmin.so b/thirdparty/linux/lib/x86/libbonmin.so new file mode 120000 index 0000000..09093f0 --- /dev/null +++ b/thirdparty/linux/lib/x86/libbonmin.so @@ -0,0 +1 @@ +libbonmin.so.4.8.4
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libbonmin.so.4 b/thirdparty/linux/lib/x86/libbonmin.so.4 new file mode 120000 index 0000000..09093f0 --- /dev/null +++ b/thirdparty/linux/lib/x86/libbonmin.so.4 @@ -0,0 +1 @@ +libbonmin.so.4.8.4
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libbonmin.so.4.8.4 b/thirdparty/linux/lib/x86/libbonmin.so.4.8.4 Binary files differnew file mode 100755 index 0000000..46bc6f9 --- /dev/null +++ b/thirdparty/linux/lib/x86/libbonmin.so.4.8.4 diff --git a/thirdparty/linux/lib/x86/libcoinblas.so.1.4.4 b/thirdparty/linux/lib/x86/libcoinblas.so.1.4.4 Binary files differindex 631f62a..44bae7f 100755 --- a/thirdparty/linux/lib/x86/libcoinblas.so.1.4.4 +++ b/thirdparty/linux/lib/x86/libcoinblas.so.1.4.4 diff --git a/thirdparty/linux/lib/x86/libcoinblas.so.1.4.6 b/thirdparty/linux/lib/x86/libcoinblas.so.1.4.6 Binary files differnew file mode 100755 index 0000000..44bae7f --- /dev/null +++ b/thirdparty/linux/lib/x86/libcoinblas.so.1.4.6 diff --git a/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.4 b/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.4 Binary files differindex 088e1bf..dbf9640 100755 --- a/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.4 +++ b/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.4 diff --git a/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.6 b/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.6 Binary files differnew file mode 100755 index 0000000..1fb8007 --- /dev/null +++ b/thirdparty/linux/lib/x86/libcoinlapack.so.1.5.6 diff --git a/thirdparty/linux/lib/x86/libcoinmumps.so.1.4.7 b/thirdparty/linux/lib/x86/libcoinmumps.so.1.4.7 Binary files differdeleted file mode 100755 index c6bba5a..0000000 --- a/thirdparty/linux/lib/x86/libcoinmumps.so.1.4.7 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libcoinmumps.so.1.5.4 b/thirdparty/linux/lib/x86/libcoinmumps.so.1.5.4 Binary files differindex 65845a4..99bb911 100755 --- a/thirdparty/linux/lib/x86/libcoinmumps.so.1.5.4 +++ b/thirdparty/linux/lib/x86/libcoinmumps.so.1.5.4 diff --git a/thirdparty/linux/lib/x86/libcoinmumps.so.1.6.0 b/thirdparty/linux/lib/x86/libcoinmumps.so.1.6.0 Binary files differnew file mode 100755 index 0000000..faa3fef --- /dev/null +++ b/thirdparty/linux/lib/x86/libcoinmumps.so.1.6.0 diff --git a/thirdparty/linux/lib/x86/libipopt.so b/thirdparty/linux/lib/x86/libipopt.so index 5cfe046..1754e00 120000 --- a/thirdparty/linux/lib/x86/libipopt.so +++ b/thirdparty/linux/lib/x86/libipopt.so @@ -1 +1 @@ -libipopt.so.1.10.4
\ No newline at end of file +libipopt.so.1.10.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libipopt.so.1 b/thirdparty/linux/lib/x86/libipopt.so.1 index a170a4e..1754e00 120000 --- a/thirdparty/linux/lib/x86/libipopt.so.1 +++ b/thirdparty/linux/lib/x86/libipopt.so.1 @@ -1 +1 @@ -libipopt.so.1.10.5
\ No newline at end of file +libipopt.so.1.10.7
\ No newline at end of file diff --git a/thirdparty/linux/lib/x86/libipopt.so.1.10.4 b/thirdparty/linux/lib/x86/libipopt.so.1.10.4 Binary files differdeleted file mode 100755 index 29c6300..0000000 --- a/thirdparty/linux/lib/x86/libipopt.so.1.10.4 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libipopt.so.1.10.5 b/thirdparty/linux/lib/x86/libipopt.so.1.10.5 Binary files differdeleted file mode 100755 index d0a4641..0000000 --- a/thirdparty/linux/lib/x86/libipopt.so.1.10.5 +++ /dev/null diff --git a/thirdparty/linux/lib/x86/libipopt.so.1.10.7 b/thirdparty/linux/lib/x86/libipopt.so.1.10.7 Binary files differnew file mode 100755 index 0000000..e92b3dd --- /dev/null +++ b/thirdparty/linux/lib/x86/libipopt.so.1.10.7 diff --git a/thirdparty/linux/lib/x86/libipopt.so.1.9.0 b/thirdparty/linux/lib/x86/libipopt.so.1.9.0 Binary files differdeleted file mode 100755 index 53846ef..0000000 --- a/thirdparty/linux/lib/x86/libipopt.so.1.9.0 +++ /dev/null |