MADNESS  0.10.1
nonlinsol.h
Go to the documentation of this file.
1 /*
2  This file is part of MADNESS.
3 
4  Copyright (C) 2007,2010 Oak Ridge National Laboratory
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20  For more information please contact:
21 
22  Robert J. Harrison
23  Oak Ridge National Laboratory
24  One Bethel Valley Road
25  P.O. Box 2008, MS-6367
26 
27  email: harrisonrj@ornl.gov
28  tel: 865-241-3937
29  fax: 865-572-0680
30 
31  $Id$
32 */
33 
34 #ifndef MADNESS_EXAMPLES_NONLINSOL_H__INCLUDED
35 #define MADNESS_EXAMPLES_NONLINSOL_H__INCLUDED
36 
37 /*!
38  \file nonlinsol.h
39  \brief Implementation of Krylov-subspace nonlinear equation solver
40  \defgroup nonlinearsolve Simple Krylov-subspace nonlinear equation solver
41  \ingroup mra
42 
43  This class implements the solver described in
44  \verbatim
45  R. J. Harrison, Krylov subspace accelerated inexact newton method for linear
46  and nonlinear equations, J. Comput. Chem. 25 (2004), no. 3, 328-334.
47  \endverbatim
48  */
49 
50 #include <madness/mra/mra.h>
51 #include <madness/tensor/solvers.h>
52 
53 namespace madness {
54 
55 
56  /// check for subspace linear dependency
57 
58  /// @param[in] Q the input matrix for KAIN
59  /// @param[in,out] c the coefficients for constructing the new solution
60  /// @param[in] rcondtol rcond less than this will cause the subspace to be shrunk due to linear dependence
61  /// @param[in] cabsmax maximum element of c greater than this will cause the subspace to be shrunk due to linear dependence
62  template<typename C>
63  void check_linear_dependence(const Tensor<C>& Q, Tensor<C>& c, const double rcondtol, const double cabsmax,
64  bool do_print=true) {
65  double rcond = 1e-12;
66  int m = c.dim(0);
67 
68  while(1){
69  c = KAIN(Q, rcond);
70  //if (world.rank() == 0) print("kain c:", c);
71 // if(std::abs(c[m - 1]) < 3.0){
72  if (c.absmax()<cabsmax) {
73  break;
74  } else if(rcond < rcondtol){
75  if (do_print) print("Increasing subspace singular value threshold ", c[m - 1], rcond);
76  rcond *= 100;
77  } else {
78  if (do_print) print("Forcing full step due to subspace malfunction");
79  c = 0.0;
80  c[m - 1] = 1.0;
81  break;
82  }
83  }
84  }
85 
86  /// A simple Krylov-subspace nonlinear equation solver
87 
88  /// \ingroup nonlinearsolve
89  template<size_t NDIM>
91  unsigned int maxsub; ///< Maximum size of subspace dimension
92 
93  std::vector<Function<double,NDIM> > ulist, rlist;
95 
96  public:
97  void set_maxsub(const unsigned int &new_maxsub){
98  maxsub = new_maxsub;
99  }
100  unsigned int get_maxsub()const{
101  const unsigned int tmp = maxsub;
102  return tmp;
103  }
104  bool do_print;
105 
106  NonlinearSolverND(unsigned int maxsub = 10) : maxsub(maxsub), do_print(false) {}
107 
108  /// Computes next trial solution vector
109 
110  /// You are responsible for performing step restriction or line search
111  /// (not necessary for linear problems).
112  ///
113  /// @param u Current solution vector
114  /// @param r Corresponding residual
115  /// @return Next trial solution vector
116  /// @param[in] rcondtol rcond less than this will cause the subspace to be shrunk due to linear dependence
117  /// @param[in] cabsmax maximum element of c greater than this will cause the subspace to be shrunk due to linear dependence
119  const double rcondtol=1e-8, const double cabsmax=1000.0) {
120  if (maxsub==1) return u-r;
121  int iter = ulist.size();
122  ulist.push_back(u);
123  rlist.push_back(r);
124 
125  // Solve subspace equations
126  real_tensor Qnew(iter+1,iter+1);
127  if (iter>0) Qnew(Slice(0,-2),Slice(0,-2)) = Q;
128  for (int i=0; i<=iter; i++) {
129  Qnew(i,iter) = inner(ulist[i],rlist[iter]);
130  Qnew(iter,i) = inner(ulist[iter],rlist[i]);
131  }
132  Q = Qnew;
133  real_tensor c = KAIN(Q);
134  check_linear_dependence(Q,c,rcondtol,cabsmax);
135  if (do_print) print("subspace solution",c);
136 
137  // Form new solution in u
139  if (ulist[0].is_compressed()) unew.compress();
140  for (int i=0; i<=iter; i++) {
141  unew.gaxpy(1.0,ulist[i], c[i]);
142  unew.gaxpy(1.0,rlist[i],-c[i]);
143  }
144  unew.truncate();
145 
146  if (ulist.size() == maxsub) {
147  ulist.erase(ulist.begin());
148  rlist.erase(rlist.begin());
149  Q = copy(Q(Slice(1,-1),Slice(1,-1)));
150  }
151  return unew;
152  }
153  };
154 
155  // backwards compatibility
157 
158 
159  template <class T>
161  T operator()() {return T();}
162  };
163 
164 
165  // The default constructor for functions does not initialize
166  // them to any value, but the solver needs functions initialized
167  // to zero for which we also need the world object.
168  template<typename T, std::size_t NDIM>
171  const int n=-1;
172 
173  /// @param[in] world the world
174  /// @param[in] nn the number of functions in a given vector
175  vector_function_allocator(World& world, const int nn) : world(world), n(nn) {}
176 
177  /// allocate a vector of n empty functions
178  std::vector<Function<T, NDIM> > operator()() {
179  return zero_functions<T, NDIM>(world, n);
180  }
181  };
182 
183 
184 
185  /// Generalized version of NonlinearSolver not limited to a single madness function
186 
187  /// \ingroup nonlinearsolve
188  ///
189  /// This solves the equation \f$r(u) = 0\f$ where u and r are both
190  /// of type \c T and inner products between two items of type \c T
191  /// produce a number of type \c C (defaulting to double). The type \c T
192  /// must support storage in an STL vector, scaling by a constant
193  /// of type \c C, inplace addition (+=), subtraction, allocation with
194  /// value zero, and inner products computed with the interface \c
195  /// inner(a,b). Have a look in examples/testsolver.cc for a
196  /// simple but complete example, and in examples/h2dynamic.cc for a
197  /// more complex example.
198  ///
199  /// I've not yet tested with anything except \c C=double and I think
200  /// that the KAIN routine will need extending for anything else.
201  template <class T, class C = double, class Alloc = default_allocator<T> >
203  unsigned int maxsub; ///< Maximum size of subspace dimension
204  Alloc alloc;
205  std::vector<T> ulist, rlist; ///< Subspace information
207  Tensor<C> c; ///< coefficients for linear combination
208  public:
209  bool do_print;
210 
211  XNonlinearSolver(const Alloc& alloc = Alloc(),bool print=false)
212  : maxsub(10)
213  , alloc(alloc)
214  , do_print(print)
215  {}
216 
218  : maxsub(other.maxsub)
219  , alloc(other.alloc)
220  , do_print(other.do_print)
221  {}
222 
223 
224  std::vector<T>& get_ulist() {return ulist;}
225  std::vector<T>& get_rlist() {return rlist;}
226 
227  void set_maxsub(int maxsub) {this->maxsub = maxsub;}
228  Tensor<C> get_c() const {return c;}
229 
230  void clear_subspace() {
231  ulist.clear();
232  rlist.clear();
233  Q=Tensor<C>();
234  }
235 
236  /// Computes next trial solution vector
237 
238  /// You are responsible for performing step restriction or line search
239  /// (not necessary for linear problems).
240  ///
241  /// @param u Current solution vector
242  /// @param r Corresponding residual
243  /// @return Next trial solution vector
244  /// @param[in] rcondtol rcond less than this will cause the subspace to be shrunk due to linear dependence
245  /// @param[in] cabsmax maximum element of c greater than this will cause the subspace to be shrunk due to li
246  T update(const T& u, const T& r, const double rcondtol=1e-8, const double cabsmax=1000.0) {
247  if (maxsub==1) return u-r;
248  int iter = ulist.size();
249  ulist.push_back(u);
250  rlist.push_back(r);
251 
252  // Solve subspace equations
253  Tensor<C> Qnew(iter+1,iter+1);
254  if (iter>0) Qnew(Slice(0,-2),Slice(0,-2)) = Q;
255  for (int i=0; i<=iter; i++) {
256  Qnew(i,iter) = inner(ulist[i],rlist[iter]);
257  Qnew(iter,i) = inner(ulist[iter],rlist[i]);
258  }
259  Q = Qnew;
260  c = KAIN(Q);
261 
262  check_linear_dependence(Q,c,rcondtol,cabsmax,do_print);
263  if (do_print) print("subspace solution",c);
264 
265  // Form new solution in u
266  T unew = alloc();
267  for (int i=0; i<=iter; i++) {
268  unew += (ulist[i] - rlist[i])*c[i];
269  }
270 
271  if (ulist.size() == maxsub) {
272  ulist.erase(ulist.begin());
273  rlist.erase(rlist.begin());
274  Q = copy(Q(Slice(1,-1),Slice(1,-1)));
275  }
276  return unew;
277  }
278 
279  };
280 
281 
282  template<typename T, std::size_t NDIM>
283  static inline XNonlinearSolver<std::vector<Function<T,NDIM>>,T,vector_function_allocator<T,NDIM>>
284  nonlinear_vector_solver(World& world, const long nvec) {
285  auto alloc=vector_function_allocator<T,NDIM>(world,nvec);
287  };
288 
289 
292 
293 
294 }
295 #endif
FunctionFactory implements the named-parameter idiom for Function.
Definition: function_factory.h:86
Function< T, NDIM > & truncate(double tol=0.0, bool fence=true)
Truncate the function with optional fence. Compresses with fence if not compressed.
Definition: mra.h:602
const Function< T, NDIM > & compress(bool fence=true) const
Compresses the function, transforming into wavelet basis. Possible non-blocking comm.
Definition: mra.h:721
Function< T, NDIM > & gaxpy(const T &alpha, const Function< Q, NDIM > &other, const R &beta, bool fence=true)
Inplace, general bi-linear operation in wavelet basis. No communication except for optional fence.
Definition: mra.h:981
A simple Krylov-subspace nonlinear equation solver.
Definition: nonlinsol.h:90
void set_maxsub(const unsigned int &new_maxsub)
Definition: nonlinsol.h:97
real_tensor Q
Definition: nonlinsol.h:94
bool do_print
Definition: nonlinsol.h:104
std::vector< Function< double, NDIM > > ulist
Definition: nonlinsol.h:93
unsigned int get_maxsub() const
Definition: nonlinsol.h:100
NonlinearSolverND(unsigned int maxsub=10)
Definition: nonlinsol.h:106
Function< double, NDIM > update(const Function< double, NDIM > &u, const Function< double, NDIM > &r, const double rcondtol=1e-8, const double cabsmax=1000.0)
Computes next trial solution vector.
Definition: nonlinsol.h:118
unsigned int maxsub
Maximum size of subspace dimension.
Definition: nonlinsol.h:91
std::vector< Function< double, NDIM > > rlist
Definition: nonlinsol.h:93
A slice defines a sub-range or patch of a dimension.
Definition: slice.h:103
A tensor is a multidimension array.
Definition: tensor.h:317
A parallel world class.
Definition: world.h:132
Generalized version of NonlinearSolver not limited to a single madness function.
Definition: nonlinsol.h:202
void set_maxsub(int maxsub)
Definition: nonlinsol.h:227
XNonlinearSolver(const Alloc &alloc=Alloc(), bool print=false)
Definition: nonlinsol.h:211
void clear_subspace()
Definition: nonlinsol.h:230
Tensor< C > c
coefficients for linear combination
Definition: nonlinsol.h:207
Tensor< C > Q
Definition: nonlinsol.h:206
std::vector< T > ulist
Definition: nonlinsol.h:205
Tensor< C > get_c() const
Definition: nonlinsol.h:228
std::vector< T > rlist
Subspace information.
Definition: nonlinsol.h:205
Alloc alloc
Definition: nonlinsol.h:204
T update(const T &u, const T &r, const double rcondtol=1e-8, const double cabsmax=1000.0)
Computes next trial solution vector.
Definition: nonlinsol.h:246
bool do_print
Definition: nonlinsol.h:209
std::vector< T > & get_ulist()
Definition: nonlinsol.h:224
std::vector< T > & get_rlist()
Definition: nonlinsol.h:225
XNonlinearSolver(const XNonlinearSolver &other)
Definition: nonlinsol.h:217
unsigned int maxsub
Maximum size of subspace dimension.
Definition: nonlinsol.h:203
const double m
Definition: gfit.cc:199
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
Main include file for MADNESS and defines Function interface.
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
NonlinearSolverND< 3 > NonlinearSolver
Definition: nonlinsol.h:156
Tensor< T > KAIN(const Tensor< T > &Q, double rcond=1e-12)
Solves non-linear equation using KAIN (returns coefficients to compute next vector)
Definition: solvers.h:98
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition: mra.h:2002
void check_linear_dependence(const Tensor< C > &Q, Tensor< C > &c, const double rcondtol, const double cabsmax, bool do_print=true)
check for subspace linear dependency
Definition: nonlinsol.h:63
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition: print.h:225
XNonlinearSolver< std::vector< Function< double, 6 > >, double, vector_function_allocator< double, 6 > > NonlinearVectorSolver_6d
Definition: nonlinsol.h:291
double inner(response_space &a, response_space &b)
Definition: response_functions.h:442
XNonlinearSolver< std::vector< Function< double, 3 > >, double, vector_function_allocator< double, 3 > > NonlinearVectorSolver_3d
Definition: nonlinsol.h:287
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition: nonlinsol.h:284
double Q(double a)
Definition: relops.cc:20
static const double c
Definition: relops.cc:10
Defines interfaces for optimization and non-linear equation solvers.
Definition: nonlinsol.h:160
T operator()()
Definition: nonlinsol.h:161
Definition: nonlinsol.h:169
const int n
Definition: nonlinsol.h:171
World & world
Definition: nonlinsol.h:170
vector_function_allocator(World &world, const int nn)
Definition: nonlinsol.h:175
std::vector< Function< T, NDIM > > operator()()
allocate a vector of n empty functions
Definition: nonlinsol.h:178
void e()
Definition: test_sig.cc:75
double u(const double x, const double expnt)
Definition: testperiodic.cc:56