Least-squares minimisation.
1845 {
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862 const unsigned int n = par.size();
1863 const unsigned int m = x.size();
1864
1865 if (n > m) {
1866 std::cerr << "LeastSquaresFit: Number of parameters to be varied\n"
1867 << " exceeds the number of data points.\n";
1868 return false;
1869 }
1870
1871
1872 if (*std::min_element(ey.cbegin(), ey.cend()) <= 0.) {
1873 std::cerr << "LeastSquaresFit: Not all errors are > 0; no fit done.\n";
1874 return false;
1875 }
1876 chi2 = 0.;
1877
1878 double diffc = -1.;
1879
1880 std::vector<double> r(m, 0.);
1881 for (unsigned int i = 0; i < m; ++i) {
1882
1883 r[i] = (y[i] - f(x[i], par)) / ey[i];
1884
1885 diffc = std::max(std::abs(r[i]), diffc);
1886
1887 chi2 += r[i] * r[i];
1888 }
1889 if (debug) {
1890 std::cout << " Input data points:\n"
1891 << " X Y Y - F(X)\n";
1892 for (unsigned int i = 0; i < m; ++i) {
1893 std::printf(" %9u %15.8e %15.8e %15.8e\n", i, x[i], y[i], r[i]);
1894 }
1895 std::cout << " Initial values of the fit parameters:\n"
1896 << " Parameter Value\n";
1897 for (unsigned int i = 0; i < n; ++i) {
1898 std::printf(" %9u %15.8e\n", i, par[i]);
1899 }
1900 }
1901 if (verbose) {
1902 std::cout << " MINIMISATION SUMMARY\n"
1903 << " Initial situation:\n";
1904 std::printf(" Largest difference between fit and target: %15.8e\n",
1905 diffc);
1906 std::printf(" Sum of squares of these differences: %15.8e\n",
1907 chi2);
1908 }
1909
1910 bool converged = false;
1911 double chi2L = 0.;
1912 for (unsigned int iter = 1; iter <= nMaxIter; ++iter) {
1913
1914 if ((diffc < diff) || (iter > 1 && std::abs(chi2L - chi2) < eps * chi2)) {
1915 if (debug || verbose) {
1916 if (diffc < diff) {
1917 std::cout << " The maximum difference stopping criterion "
1918 << "is satisfied.\n";
1919 } else {
1920 std::cout << " The relative change in chi-squared has dropped "
1921 << "below the threshold.\n";
1922 }
1923 }
1924 converged = true;
1925 break;
1926 }
1927
1928 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
1929 for (unsigned int i = 0; i < n; ++i) {
1930 const double epsdif = eps * (1. + std::abs(par[i]));
1931 par[i] += 0.5 * epsdif;
1932 for (unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
1933 par[i] -= epsdif;
1934 for (unsigned int j = 0; j < m; ++j) {
1935 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
1936 }
1937 par[i] += 0.5 * epsdif;
1938 }
1939
1940 std::vector<double> colsum(n, 0.);
1941 std::vector<int> pivot(n, 0);
1942 for (unsigned int i = 0; i < n; ++i) {
1943 colsum[i] = std::inner_product(d[i].cbegin(), d[i].cend(),
1944 d[i].cbegin(), 0.);
1945 pivot[i] = i;
1946 }
1947
1948 std::vector<double>
alpha(n, 0.);
1949 bool singular = false;
1950 for (unsigned int k = 0; k < n; ++k) {
1951 double sigma = colsum[k];
1952 unsigned int jbar = k;
1953 for (unsigned int j = k + 1; j < n; ++j) {
1954 if (sigma < colsum[j]) {
1955 sigma = colsum[j];
1956 jbar = j;
1957 }
1958 }
1959 if (jbar != k) {
1960
1961 std::swap(pivot[k], pivot[jbar]);
1962 std::swap(colsum[k], colsum[jbar]);
1963 std::swap(d[k], d[jbar]);
1964 }
1965 sigma = 0.;
1966 for (unsigned int i = k; i < m; ++i) sigma += d[k][i] * d[k][i];
1967 if (sigma == 0. ||
sqrt(sigma) < 1.e-8 * std::abs(d[k][k])) {
1968 singular = true;
1969 break;
1970 }
1972 const double beta = 1. / (sigma - d[k][k] *
alpha[k]);
1973 d[k][k] -=
alpha[k];
1974 std::vector<double> b(n, 0.);
1975 for (unsigned int j = k + 1; j < n; ++j) {
1976 for (unsigned int i = k; i < n; ++i) b[j] += d[k][i] * d[j][i];
1977 b[j] *= beta;
1978 }
1979 for (unsigned int j = k + 1; j < n; ++j) {
1980 for (unsigned int i = k; i < m; ++i) {
1981 d[j][i] -= d[k][i] * b[j];
1982 colsum[j] -= d[j][k] * d[j][k];
1983 }
1984 }
1985 }
1986 if (singular) {
1987 std::cerr << "LeastSquaresFit: Householder matrix (nearly) singular;\n"
1988 << " no further optimisation.\n"
1989 << " Ensure the function depends on the parameters\n"
1990 << " and try to supply reasonable starting values.\n";
1991 break;
1992 }
1993
1994 for (unsigned int j = 0; j < n; ++j) {
1995 double gamma = 0.;
1996 for (unsigned int i = j; i < m; ++i) gamma += d[j][i] * r[i];
1997 gamma *= 1. / (
alpha[j] * d[j][j]);
1998 for (unsigned int i = j; i < m; ++i) r[i] += gamma * d[j][i];
1999 }
2000 std::vector<double>
z(n, 0.);
2001 z[n - 1] = r[n - 1] /
alpha[n - 1];
2002 for (int i = n - 1; i >= 1; --i) {
2003 double sum = 0.;
2004 for (unsigned int j = i + 1; j <= n; ++j) {
2005 sum += d[j - 1][i - 1] *
z[j - 1];
2006 }
2007 z[i - 1] = (r[i - 1] - sum) / alpha[i - 1];
2008 }
2009
2010 std::vector<double> s(n, 0.);
2011 for (unsigned int i = 0; i < n; ++i) s[pivot[i]] = z[i];
2012
2013 if (debug) {
2014 std::cout << " Correction vector in iteration " << iter << ":\n";
2015 for (unsigned int i = 0; i < n; ++i) {
2016 std::printf(" %5u %15.8e\n", i, s[i]);
2017 }
2018 }
2019
2020 chi2L = chi2;
2021 chi2 *= 2;
2022 for (unsigned int i = 0; i < n; ++i) par[i] += s[i] * 2;
2023 for (unsigned int i = 0; i <= 10; ++i) {
2024 if (chi2 <= chi2L) break;
2025 if (std::abs(chi2L - chi2) < eps * chi2) {
2026 if (debug) {
2027 std::cout << " Too little improvement; reduction loop halted.\n";
2028 }
2029 break;
2030 }
2031 chi2 = 0.;
2032 const double scale = 1. /
pow(2, i);
2033 for (unsigned int j = 0; j < n; ++j) par[j] -= s[j] * scale;
2034 for (unsigned int j = 0; j < m; ++j) {
2035 r[j] = (
y[j] - f(x[j], par)) / ey[j];
2036 chi2 += r[j] * r[j];
2037 }
2038 if (debug) {
2039 std::printf(" Reduction loop %3i: chi2 = %15.8e\n", i, chi2);
2040 }
2041 }
2042
2043 diffc = std::abs(r[0]);
2044 for (unsigned int i = 1; i < m; ++i) {
2045 diffc = std::max(std::abs(r[i]), diffc);
2046 }
2047
2048 if (debug) {
2049 std::cout << " Values of the fit parameters after iteration "
2050 << iter << "\n Parameter Value\n";
2051 for (unsigned int i = 0; i < n; ++i) {
2052 std::printf(" %9u %15.8e\n", i, par[i]);
2053 }
2054 std::printf(" for which chi2 = %15.8e and diff = %15.8e\n",
2055 chi2, diffc);
2056 } else if (verbose) {
2057 std::printf(" Step %3u: largest deviation = %15.8e, chi2 = %15.8e\n",
2058 iter, diffc, chi2);
2059 }
2060 }
2061
2062 if (!converged) {
2063 std::cerr << "LeastSquaresFit: Maximum number of iterations reached.\n";
2064 }
2065
2066 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
2067 for (unsigned int i = 0; i < n; ++i) {
2068 const double epsdif = eps * (1. + std::abs(par[i]));
2069 par[i] += 0.5 * epsdif;
2070 for (unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
2071 par[i] -= epsdif;
2072 for (unsigned int j = 0; j < m; ++j) {
2073 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
2074 }
2075 par[i] += 0.5 * epsdif;
2076 }
2077
2078 std::vector<std::vector<double> > cov(n, std::vector<double>(n, 0.));
2079 for (unsigned int i = 0; i < n; ++i) {
2080 for (unsigned int j = 0; j < n; ++j) {
2081 cov[i][j] = std::inner_product(d[i].cbegin(), d[i].cend(),
2082 d[j].cbegin(), 0.);
2083 }
2084 }
2085
2086 double scale = m > n ? chi2 / (m - n) : 1.;
2087
2088 epar.assign(n, 0.);
2090 std::cerr << "LeastSquaresFit: Singular covariance matrix; "
2091 << "no error calculation.\n";
2092 } else {
2093 for (unsigned int i = 0; i < n; ++i) {
2094 for (unsigned int j = 0; j < n; ++j) cov[i][j] *= scale;
2095 epar[i] =
sqrt(std::max(0., cov[i][i]));
2096 }
2097 }
2098
2099 if (debug) {
2100 std::cout << " Comparison between input and fit:\n"
2101 << " X Y F(X)\n";
2102 for (unsigned int i = 0; i < m; ++i) {
2103 std::printf(" %5u %15.8e %15.8e %15.8e\n", i, x[i], y[i], f(x[i], par));
2104 }
2105 }
2106 if (verbose) {
2107 std::cout << " Final values of the fit parameters:\n"
2108 << " Parameter Value Error\n";
2109 for (unsigned int i = 0; i < n; ++i) {
2110 std::printf(" %9u %15.8e %15.8e\n", i, par[i], epar[i]);
2111 }
2112 std::cout << " The errors have been scaled by a factor of "
2113 <<
sqrt(scale) <<
".\n";
2114 std::cout << " Covariance matrix:\n";
2115 for (unsigned int i = 0; i < n; ++i) {
2116 for (unsigned int j = 0; j < n; ++j) {
2117 std::printf(" %15.8e", cov[i][j]);
2118 }
2119 std::cout << "\n";
2120 }
2121 std::cout << " Correlation matrix:\n";
2122 for (unsigned int i = 0; i < n; ++i) {
2123 for (unsigned int j = 0; j < n; ++j) {
2124 double cor = 0.;
2125 if (cov[i][i] > 0. && cov[j][j] > 0.) {
2126 cor = cov[i][j] /
sqrt(cov[i][i] * cov[j][j]);
2127 }
2128 std::printf(" %15.8e", cor);
2129 }
2130 std::cout << "\n";
2131 }
2132 std::cout << " Minimisation finished.\n";
2133 }
2134 return converged;
2135}
int dinv(const int n, std::vector< std::vector< double > > &a)
Replace square matrix A by its inverse.
DoubleAc pow(const DoubleAc &f, double p)
DoubleAc sqrt(const DoubleAc &f)