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