1 /*! \file lib/resol_basisfn.h
2     Header file for resolution basis function
3 */
4 //C Copyright (C) 2000-2006 Kevin Cowtan and University of York
5 //L
6 //L  This library is free software and is distributed under the terms
7 //L  and conditions of version 2.1 of the GNU Lesser General Public
8 //L  Licence (LGPL) with the following additional clause:
9 //L
10 //L     `You may also combine or link a "work that uses the Library" to
11 //L     produce a work containing portions of the Library, and distribute
12 //L     that work under terms of your choice, provided that you give
13 //L     prominent notice with each copy of the work that the specified
14 //L     version of the Library is used in it, and that you include or
15 //L     provide public access to the complete corresponding
16 //L     machine-readable source code for the Library including whatever
17 //L     changes were used in the work. (i.e. If you make changes to the
18 //L     Library you must distribute those, but you do not need to
19 //L     distribute source or object code to those portions of the work
20 //L     not covered by this licence.)'
21 //L
22 //L  Note that this clause grants an additional right and does not impose
23 //L  any additional restriction, and so does not affect compatibility
24 //L  with the GNU General Public Licence (GPL). If you wish to negotiate
25 //L  other terms, please contact the maintainer.
26 //L
27 //L  You can redistribute it and/or modify the library under the terms of
28 //L  the GNU Lesser General Public License as published by the Free Software
29 //L  Foundation; either version 2.1 of the License, or (at your option) any
30 //L  later version.
31 //L
32 //L  This library is distributed in the hope that it will be useful, but
33 //L  WITHOUT ANY WARRANTY; without even the implied warranty of
34 //L  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
35 //L  Lesser General Public License for more details.
36 //L
37 //L  You should have received a copy of the CCP4 licence and/or GNU
38 //L  Lesser General Public License along with this library; if not, write
39 //L  to the CCP4 Secretary, Daresbury Laboratory, Warrington WA4 4AD, UK.
40 //L  The GNU Lesser General Public can also be obtained by writing to the
41 //L  Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
42 //L  MA 02111-1307 USA
43 
44 
45 #ifndef CLIPPER_RESOL_BASISFN
46 #define CLIPPER_RESOL_BASISFN
47 
48 #include "resol_fn.h"
49 
50 namespace clipper {
51 
52 
53   //! Resolution ordinal gernerator
54   /*! This class is a helper class for functions which need to divide
55     reflections up by resolution whilst guaranteeing a certain
56     distribution of number of reflections per range. It takes a list
57     of reflections, one at a time, and calculates a function to get
58     the approximate ordinal number of a reflection in a list sorted by
59     resolution.
60   */
61   class Resolution_ordinal : public Generic_ordinal
62   {
63   public:
64     //! initialiser: takes an HKL_info and uses all reflections.
65     void init( const HKL_info& hklinfo, const ftype& power );
66     //! initialiser: takes an HKL_data & uses non-missing reflections.
67     void init( const HKL_data_base& hkldata, const ftype& power );
68     //! initialiser: takes an HKL_data + Cell & uses non-missing reflections.
69     void init( const HKL_data_base& hkldata, const Cell& cell, const ftype& power );
70   };
71 
72 
73   //! simple binning basis function
74   /*! This class bins reflections on the basis of resolution, i.e. it
75     generates a resolution function from spherical shells. */
76   class BasisFn_binner : public BasisFn_base
77   {
78   public:
79     //! constructor: include whole reflection list in histogram
BasisFn_base(nbins_)80     BasisFn_binner( const HKL_info& hklinfo, const int& nbins_, const ftype power = 1.0 ) : BasisFn_base( nbins_ ) { s_ord.init( hklinfo, power ); }
81     //! constructor: include only non-missing reflections in histogram
BasisFn_base(nbins_)82     BasisFn_binner( const HKL_data_base& hkldata, const int& nbins_, const ftype power = 1.0  ) : BasisFn_base( nbins_ ) { s_ord.init( hkldata, hkldata.base_cell(), power ); }
83     //! the value of the resolution function (override for speed)
84     ftype f_s( const ftype& s, const std::vector<ftype>& params ) const;
85     //! the derivative of the resolution function w.r.t. the parameters
86     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
87     //! the type of the function: optionally used to improve convergence
type()88     FNtype type() const { return LINEAR; }
89     //! number of non-zero diagonals in the upper triangle of the curvatures
num_diagonals()90     int num_diagonals() const { return 1; }
91     //! the value of the resolution function (override for speed)
f(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)92     ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
93     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)94     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
95   private:
96     Resolution_ordinal s_ord; //<! resolution ordinal
97   };
98 
99 
100   //! simple linear basis function
101   /*! This class fits a piecewise linear function through reflections
102     on the basis of resolution. */
103   class BasisFn_linear : public BasisFn_base
104   {
105   public:
106     //! constructor: include whole reflection list in histogram
BasisFn_base(nbins_)107     BasisFn_linear( const HKL_info& hklinfo, const int& nbins_, const ftype power = 1.0 ) : BasisFn_base( nbins_ ) { s_ord.init( hklinfo, power ); }
108     //! constructor: include only non-missing reflections in histogram
BasisFn_base(nbins_)109     BasisFn_linear( const HKL_data_base& hkldata, const int& nbins_, const ftype power = 1.0  ) : BasisFn_base( nbins_ ) { s_ord.init( hkldata, hkldata.base_cell(), power ); }
110     //! the value of the resolution function (override for speed)
111     ftype f_s( const ftype& s, const std::vector<ftype>& params ) const;
112     //! the derivative of the resolution function w.r.t. the parameters
113     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
114     //! the type of the function: optionally used to improve convergence
type()115     FNtype type() const { return LINEAR; }
116     //! number of non-zero diagonals in the upper triangle of the curvatures
num_diagonals()117     int num_diagonals() const { return 2; }
118     //! the value of the resolution function (override for speed)
f(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)119     ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
120     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)121     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
122   private:
123     Resolution_ordinal s_ord; //<! resolution ordinal
124   };
125 
126 
127   //! simple smooth basis function
128   /*! This class fits a Bspline through reflections on the basis of
129     resolution. */
130   class BasisFn_spline : public BasisFn_base
131   {
132   public:
133     //! constructor: include whole reflection list in histogram
BasisFn_base(nbins_)134     BasisFn_spline( const HKL_info& hklinfo, const int& nbins_, const ftype power = 1.0 ) : BasisFn_base( nbins_ ) { s_ord.init( hklinfo, power ); }
135     //! constructor: include only non-missing reflections in histogram
BasisFn_base(nbins_)136     BasisFn_spline( const HKL_data_base& hkldata, const int& nbins_, const ftype power = 1.0  ) : BasisFn_base( nbins_ ) { s_ord.init( hkldata, hkldata.base_cell(), power ); }
137     //! the value of the resolution function (override for speed)
138     ftype f_s( const ftype& s, const std::vector<ftype>& params ) const;
139     //! the derivative of the resolution function w.r.t. the parameters
140     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
141     //! the type of the function: optionally used to improve convergence
type()142     FNtype type() const { return LINEAR; }
143     //! number of non-zero diagonals in the upper triangle of the curvatures
num_diagonals()144     int num_diagonals() const { return 3; }
145     //! the value of the resolution function (override for speed)
f(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)146     ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
147     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)148     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
149   private:
150     Resolution_ordinal s_ord; //<! resolution ordinal
151   };
152 
153 
154   //! simple Gaussian basis function
155   /*! This class provides a Gaussian basis function. */
156   class BasisFn_gaussian : public BasisFn_base
157   {
158   public:
159     //! constructor:
BasisFn_gaussian()160     BasisFn_gaussian() : BasisFn_base( 2 ) {}
161     //! the value of the resolution function
162     //ftype f_s( const ftype& s, const std::vector<ftype>& params ) const;
163     //! the derivatives of the resolution function w.r.t. the parameters
164     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
165     //! the value of the resolution function (override for speed)
166     //ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
167     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)168     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
169     //! return the scale factor corresponding to the Gaussian parameters
170     ftype scale( const std::vector<ftype>& params ) const;
171     //! return the isotropic U corresponding to the Gaussian parameters
172     ftype u_iso( const std::vector<ftype>& params ) const;
173   };
174 
175 
176   //! simple anisotropic Gaussian basis function
177   /*! This class provides a anisotropic Gaussian basis function. */
178   class BasisFn_aniso_gaussian : public BasisFn_base
179   {
180   public:
181     //! constructor:
BasisFn_aniso_gaussian()182     BasisFn_aniso_gaussian() : BasisFn_base( 7 ) {}
183     //! the derivatives of the resolution function w.r.t. the parameters
184     const BasisFn_base::Fderiv& fderiv_coord( const Coord_reci_orth& xs, const std::vector<ftype>& params ) const;
185     //! the value of the resolution function (override for speed)
186     //ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_coord( hkl.coord_reci_orth( cell ), params ); }
187     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)188     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_coord( hkl.coord_reci_orth( cell ), params ); }
189     //! return the scale factor corresponding to the Gaussian parameters
190     ftype scale( const std::vector<ftype>& params ) const;
191     //! return the anisotropic U corresponding to the Gaussian parameters
192     U_aniso_orth u_aniso_orth( const std::vector<ftype>& params ) const;
193   };
194 
195 
196   //! simple log Gaussian basis function
197   /*! This class provides a Log Gaussian basis function.  i.e. a
198    quadratic function of resolution.
199    Use this in conjunction with a Log-target function to get a fast
200    estimate to a Gaussian fit. */
201   class BasisFn_log_gaussian : public BasisFn_base
202   {
203   public:
204     //! constructor:
BasisFn_log_gaussian()205     BasisFn_log_gaussian() : BasisFn_base( 2 ) {}
206     //! the value of the resolution function
207     //ftype f_s( const ftype& s, const std::vector<ftype>& params ) const;
208     //! the derivatives of the resolution function w.r.t. the parameters
209     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
210     //! the value of the resolution function (override for speed)
211     //ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
212     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)213     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const
214 std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
215     //! the type of the function: optionally used to improve convergence
type()216     FNtype type() const { return LINEAR; }
217     //! return the scale factor corresponding to the Gaussian parameters
218     ftype scale( const std::vector<ftype>& params ) const;
219     //! return the isotropic U corresponding to the Gaussian parameters
220     ftype u_iso( const std::vector<ftype>& params ) const;
221   };
222 
223 
224   //! simple anisotropic Gaussian basis function
225   /*! This class provides a anisotropic Gaussian basis function.
226    i.e. a general quadratic function of resolution.
227    Use this in conjunction with a Log-target function to get a fast
228    estimate to a Gaussian fit. */
229   class BasisFn_log_aniso_gaussian : public BasisFn_base
230   {
231   public:
232     //! constructor:
BasisFn_log_aniso_gaussian()233     BasisFn_log_aniso_gaussian() : BasisFn_base( 7 ) {}
234     //! the derivatives of the resolution function w.r.t. the parameters
235     const BasisFn_base::Fderiv& fderiv_coord( const Coord_reci_orth& xs, const std::vector<ftype>& params ) const;
236     //! the value of the resolution function (override for speed)
237     //ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_coord( hkl.coord_reci_orth( cell ), params ); }
238     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)239     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const
240 std::vector<ftype>& params ) const { return fderiv_coord( hkl.coord_reci_orth( cell ), params ); }
241     //! the type of the function: optionally used to improve convergence
type()242     FNtype type() const { return LINEAR; }
243     //! return the scale factor corresponding to the Gaussian parameters
244     ftype scale( const std::vector<ftype>& params ) const;
245     //! return the anisotropic U corresponding to the Gaussian parameters
246     U_aniso_orth u_aniso_orth( const std::vector<ftype>& params ) const;
247   };
248 
249 
250   //! simple Expcubic basis function
251   /*! This class provides a Expcubic basis function. */
252   class BasisFn_expcubic : public BasisFn_base
253   {
254   public:
255     //! constructor
BasisFn_expcubic()256     BasisFn_expcubic() : BasisFn_base( 4 ) {}
257     //! the derivatives of the resolution function w.r.t. the parameters
258     const BasisFn_base::Fderiv& fderiv_s( const ftype& s, const std::vector<ftype>& params ) const;
259     //! the value of the resolution function (override for speed)
260     //ftype f( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return f_s( hkl.invresolsq( cell ), params ); }
261     //! the derivatives of the resolution function w.r.t. the parameters
fderiv(const HKL & hkl,const Cell & cell,const std::vector<ftype> & params)262     const BasisFn_base::Fderiv& fderiv( const HKL& hkl, const Cell& cell, const std::vector<ftype>& params ) const { return fderiv_s( hkl.invresolsq( cell ), params ); }
263   };
264 
265 
266 } // namespace clipper
267 
268 #endif
269