| 2130 | } |
| 2131 | |
| 2132 | void XYFitCurvePrivate::runMaximumLikelihood(const AbstractColumn* tmpXDataColumn, const double norm) { |
| 2133 | const size_t n = tmpXDataColumn->rowCount(); |
| 2134 | |
| 2135 | fitResult.available = true; |
| 2136 | fitResult.valid = true; |
| 2137 | fitResult.status = i18n("Success"); // can it fail in any way? |
| 2138 | |
| 2139 | const unsigned int np = fitData.paramNames.size(); // number of fit parameters |
| 2140 | fitResult.dof = n - np; |
| 2141 | fitResult.paramValues.resize(np); |
| 2142 | fitResult.errorValues.resize(np); |
| 2143 | fitResult.tdist_tValues.resize(np); |
| 2144 | fitResult.tdist_pValues.resize(np); |
| 2145 | fitResult.marginValues.resize(np); |
| 2146 | fitResult.correlationMatrix.resize(np * (np + 1) / 2); |
| 2147 | |
| 2148 | DEBUG(Q_FUNC_INFO << ", DISTRIBUTION: " << fitData.modelType) |
| 2149 | fitResult.paramValues[0] = norm; // A - normalization |
| 2150 | // TODO: parameter values (error, etc.) |
| 2151 | // TODO: currently all values are used (data range not changeable) |
| 2152 | const double alpha = 1.0 - fitData.confidenceInterval / 100.; |
| 2153 | const auto& statistics = ((Column*)tmpXDataColumn)->statistics(); |
| 2154 | const double mean = statistics.arithmeticMean; |
| 2155 | const double var = statistics.variance; |
| 2156 | const double median = statistics.median; |
| 2157 | const double madmed = statistics.meanDeviationAroundMedian; |
| 2158 | const double iqr = statistics.iqr; |
| 2159 | switch (fitData.modelType) { // only these are supported |
| 2160 | case nsl_sf_stats_gaussian: { |
| 2161 | const double sigma = std::sqrt(var); |
| 2162 | const double mu = mean; |
| 2163 | fitResult.paramValues[1] = sigma; |
| 2164 | fitResult.paramValues[2] = mu; |
| 2165 | DEBUG(Q_FUNC_INFO << ", mu = " << mu << ", sigma = " << sigma) |
| 2166 | |
| 2167 | fitResult.errorValues[2] = sigma / std::sqrt(n); |
| 2168 | double margin = nsl_stats_tdist_margin(alpha, fitResult.dof, fitResult.errorValues.at(2)); |
| 2169 | // DEBUG("z = " << nsl_stats_tdist_z(alpha, fitResult.dof)) |
| 2170 | fitResult.marginValues[2] = margin; |
| 2171 | |
| 2172 | fitResult.errorValues[1] = sigma * sigma / std::sqrt(2 * n); |
| 2173 | margin = nsl_stats_tdist_margin(alpha, fitResult.dof, fitResult.errorValues.at(1)); |
| 2174 | // WARN("sigma CONFIDENCE INTERVAL: " << fitResult.paramValues[1] - margin << " .. " << fitResult.paramValues[1] + margin) |
| 2175 | fitResult.marginValues[1] = margin; |
| 2176 | |
| 2177 | // normalization for spreadsheet or curve |
| 2178 | if (dataSourceType != XYAnalysisCurve::DataSourceType::Histogram) |
| 2179 | fitResult.paramValues[0] /= |
| 2180 | (gsl_sf_erf((tmpXDataColumn->maximum() - mu) / sigma) - gsl_sf_erf((tmpXDataColumn->minimum() - mu) / sigma)) / (2. * std::sqrt(2.)); |
| 2181 | break; |
| 2182 | } |
| 2183 | case nsl_sf_stats_exponential: { |
| 2184 | const double mu = tmpXDataColumn->minimum(); |
| 2185 | const double lambda = 1. / (mean - mu); // 1/(<x>-\mu) |
| 2186 | fitResult.paramValues[1] = lambda * (1 - 1. / (n - 1)); // unbiased |
| 2187 | fitResult.paramValues[2] = mu; |
| 2188 | |
| 2189 | fitResult.errorValues[1] = lambda / std::sqrt(n); |
nothing calls this directly
no test coverage detected