1 /* Siconos is a program dedicated to modeling, simulation and control
2  * of non smooth dynamical systems.
3  *
4  * Copyright 2021 INRIA.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17 */
18 
19 #ifndef LINESEARCH_H
20 #define LINESEARCH_H
21 
22 /*!\file line_search.h
23  * \brief Basic structures for line-search (and arcsearch) methods
24  *
25  */
26 
27 #include "Newton_methods.h"
28 #include "SiconosConfig.h" // for BUILD_AS_CPP // IWYU pragma: keep
29 
30 /** \struct search_data line_search.h
31  * Struct to hold together the data needed by the search
32  */
33 typedef struct {
34   compute_F_ptr compute_F; /**< function to compute F(z) */
35   compute_F_merit_ptr compute_F_merit; /**< function to compute F_merit(z) */
36   double* z; /**< z vector */
37   double* zc; /**< candidate z vector */
38   double* F; /**< value of F(z) */
39   double* F_merit; /**< value of F_merit(z) */
40   double* desc_dir; /**< descent direction */
41   double alpha0; /**< starting value for alpha */
42   double alpha_min; /**< minimum value of alpha*/
43   void* data; /**< opaque pointer for extra data (needed for function call) */
44   void* nm_ref_data; /**< data for the update rule */
45   unsigned searchtype; /**< type of search: LINESEARCH or ARCSEARCH */
46   void* set; /**< set on which the solution has to belong; only used for arcsearch */
47   double sigma; /**< sigma value, used only for ARCSEARCH */
48   void* extra_params; /**< extra parameters for some line search algorithm */
49 } search_data;
50 
51 
52 /** \struct nm_ref_struct line_search.h
53  * Struct used for the non-monotone search
54  */
55 typedef struct {
56   int type; /**< 0 if false, otherwise use a nonmonotone search. The integer value gives the update rule for the merit value ``threshold'' */
57   int M; /**< maximum number of previous values of the merit function stored*/
58   int m; /**< number of previous values of the merit function stored*/
59   double* previous_thetas; /**< set of previous values of the merit function */
60 } nm_ref_struct;
61 
62 enum { NM_LS_DISABLE, NM_LS_MAX, NM_LS_MEAN, NM_LS_ZHANG_HAGER };
63 
64 enum SEARCH_TYPE { LINESEARCH, ARCSEARCH, BACKWARD_PATHSEARCH };
65 
66 enum LSA_ALGO { SICONOS_LSA_ARMIJO, SICONOS_LSA_GOLDSTEIN };
67 
68 typedef double (*sn_ls_fn)(int n, double* theta, double preRHS, search_data* ls_data);
69 
70 #if defined(__cplusplus) && !defined(BUILD_AS_CPP)
71 extern "C"
72 {
73 #endif
74 
75   /** Set the update type for the non-monotone line search
76    * \param nm_ref_data the struct containing the data relative to the
77    * reference value used in the line search
78    * \param type for the update
79    */
set_nonmonotone_type(void * nm_ref_data,int type)80   static inline void set_nonmonotone_type(void* nm_ref_data, int type)
81   {
82     ((nm_ref_struct*) nm_ref_data)->type = type;
83   }
84 
85   /** Get the update type for the non-monotone line search
86    * \param nm_ref_data the struct containing the data relative to the
87    * reference value used in the line search
88    * \return the type for the update
89    */
get_nonmonotone_type(void * nm_ref_data)90   static inline int get_nonmonotone_type(void* nm_ref_data)
91   {
92     return ((nm_ref_struct*) nm_ref_data)->type;
93   }
94 
95   /** Generic call for a linesearch (or arcsearch). Handles the update of the
96    * update of the non-monotone data
97    * \param n size of the variable
98    * \param theta current value of the merit function
99    * \param preRHS value used for the comparison
100    * \param ls_data line search data
101    * \param searchtype type of search: linesearch or arcsearch
102    * \param ls_fn function to call
103    * \return the value of tau, NAN if the search failed
104    */
105   double line_search_generic(int n, double theta, double preRHS, search_data* ls_data, unsigned searchtype, sn_ls_fn ls_fn);
106 
107   /** update the reference value for the non-monotone line search
108    * \param nm_ref_data the struct containing the data for the update
109    * \param cur_merit new value of the merit function for the update
110    */
111   void update_non_monotone_ref(void* nm_ref_data, double cur_merit);
112 
113   /** compute the reference value
114    * \param nm_ref_data the struct containing the data relative to the
115    * reference value used in the line search
116    * \param[in,out] theta_ref on input the current value of the merit function;
117    * on output, the new reference value
118    */
119   void get_non_monotone_ref(void* nm_ref_data, double* theta_ref);
120 
121   /** fill the data struct for non-monotone search
122    * \param nm_ref_data the structure to fill
123    * \param iparam the set of parameter from the SolverOption struct
124    */
125   void fill_nm_data(nm_ref_struct* nm_ref_data, int* iparam);
126 
127   /** Reset the storage for the non-monotone search
128    * \param nm_ref_data the structure
129    */
130   void zero_nm_data(nm_ref_struct* nm_ref_data);
131 
132   /** free the allocated memory for the non-monotone search
133    * \param nm_ref_data the structure holding the allocated memory
134    */
135   void free_nm_data(nm_ref_struct* nm_ref_data);
136 
137   /** free the allocated memory for the linesearch method
138    * \param ls_data the struct
139    */
140   void free_ls_data(search_data* ls_data);
141 
142 #if defined(__cplusplus) && !defined(BUILD_AS_CPP)
143 }
144 #endif
145 
146 #endif
147 
148