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>
52
53namespace 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 }
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
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:
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
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>>
288
289
292
293
294}
295#endif
FunctionFactory implements the named-parameter idiom for Function.
Definition function_factory.h:86
A multiresolution adaptive numerical function.
Definition mra.h:122
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
std::size_t size() const
Returns the number of coefficients in the function ... collective global sum.
Definition mra.h:538
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
const Function< T, NDIM > & compress(bool fence=true) const
Compresses the function, transforming into wavelet basis. Possible non-blocking comm.
Definition mra.h:721
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
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 get_maxsub() const
Definition nonlinsol.h:100
NonlinearSolverND(unsigned int maxsub=10)
Definition nonlinsol.h:106
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 > & get_rlist()
Definition nonlinsol.h:225
std::vector< T > ulist
Definition nonlinsol.h:205
Tensor< C > get_c() const
Definition nonlinsol.h:228
std::vector< T > & get_ulist()
Definition nonlinsol.h:224
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
XNonlinearSolver(const XNonlinearSolver &other)
Definition nonlinsol.h:217
unsigned int maxsub
Maximum size of subspace dimension.
Definition nonlinsol.h:203
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
static double u(double r, double c)
Definition he.cc:20
Main include file for MADNESS and defines Function interface.
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
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
NonlinearSolverND< 3 > NonlinearSolver
Definition nonlinsol.h:156
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:290
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
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
double Q(double a)
Definition relops.cc:20
static const double c
Definition relops.cc:10
static const double m
Definition relops.cc:9
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