74 gsl_vector* residuals)
79 const double* xInf = dataPtr->
xInf_ptr;
80 const double* yInf = dataPtr->
yInf_ptr;
81 const double* xSup = dataPtr->
xSup_ptr;
82 const double* ySup = dataPtr->
ySup_ptr;
84 const double* zObs = dataPtr->
zObs_ptr;
92 int axe = dataPtr->
axe;
97 const double*
params = gsl_vector_const_ptr(gslParams, 0);
101 const double* mu = &
params[0];
103 double*
w = (
double*)&
params[(dimOfParameters - 1) * K];
106 double lastW = 1.0 - vectorSum(
w, K - 1);
110 printf(
" Function evaluation at:\n");
111 for (
int k = 0; k < K; k++) {
112 if (dimOfParameters == 3) {
113 printf(
" mu_k[%d] = %g %g \n", k, mu[k], mu[K + k]);
115 printf(
" mu_k[%d] = %g \n", k, mu[k]);
118 for (
int k = 0; k < K - 1; k++) {
119 printf(
" w_k[%d] = %g \n", k,
w[k]);
122 printf(
" w_k[%d] = %g \n", K - 1, lastW);
142 for (
int k = 0; k < K; k++) {
146 vectorAddScalar(xInf, -mu[k], N, xyInf0);
147 vectorAddScalar(xSup, -mu[k], N, xySup0);
156 }
else if (axe == 1) {
165 vectorAddScalar(yInf, -mu[K + k], N, xyInf0);
166 vectorAddScalar(xSup, -mu[K + k], N, xySup0);
187 double wTmp = (k != K - 1) ?
w[k] : lastW;
188 vectorAddVector(
z, wTmp, zTmp, N,
z);
196 double sumNormalizedZ[2];
198 for (
int i = 0;
i < N;
i++) {
200 sumNormalizedZ[0] += notSaturated[
i] *
z[
i];
202 sumNormalizedZ[1] += notSaturated[
i] *
z[
i];
223 double chargePerCath[2] = {0., 0.};
224 for (
int i = 0;
i < N;
i++) {
226 chargePerCath[cath[
i]] +=
z[
i];
228 double cathPenal = 0;
230 cathPenal = fabs(zCathTotalCharge[0] - chargePerCath[0]) +
231 fabs(zCathTotalCharge[1] - chargePerCath[1]);
239 for (
int k = 0; k < (K - 1); k++) {
242 }
else if (
w[k] > 1.0) {
243 wPenal += (
w[k] - 1.0);
247 wPenal = wPenal + fabs(1.0 - vectorSum(
w, K - 1) - lastW);
249 printf(
" wPenal: %f\n", wPenal);
252 for (
int i = 0;
i < N;
i++) {
254 double mask = notSaturated[
i];
255 if ((notSaturated[
i] == 0) && (
z[
i] < zObs[
i])) {
262 gsl_vector_set(residuals,
i,
mask * ((
z[
i] - zObs[
i]) + meanCoef * wPenal));
272 printf(
" Observed sumCath0=%15.8f, sumCath1=%15.8f,\n",
273 zCathTotalCharge[0], zCathTotalCharge[1]);
276 printf(
" Penalties cathPenal=%5.4g wPenal=%5.4g \n", 1.0 + cathPenal,
278 printf(
" Residues\n");
279 printf(
" %15s %15s %15s %15s %15s %15s\n",
"zObs",
"z",
"cathWeight",
280 "norm. factor",
"notSaturated",
"residual");
281 for (
int i = 0;
i < N;
i++) {
282 printf(
" %15.8f %15.8f %15.8f %15.8f %d %15.8f\n", zObs[
i],
283 z[
i], cathWeights[
i], sumNormalizedZ[cath[
i]] * cathWeights[
i],
284 notSaturated[
i], gsl_vector_get(residuals,
i));
289 printf(
" |f| = %g \n", gsl_blas_dnrm2(residuals));
872void printState(
int iter, gsl_multifit_fdfsolver* s,
int axe,
int K,
int N)
874 printf(
" Fitting iter=%3d |f(x)|=%g\n", iter, gsl_blas_dnrm2(s->f));
877 }
else if (axe == 1) {
880 printf(
" mu (x,y):");
884 for (; k < 2 * K; k++) {
885 printf(
" % 7.3f", gsl_vector_get(s->x, k));
889 for (; k < 1 * K; k++) {
890 printf(
" % 7.3f", gsl_vector_get(s->x, k));
896 int nDimensions = (axe == -1) ? 3 : 2;
897 for (; k < nDimensions * K - 1; k++) {
898 double w = gsl_vector_get(s->x, k);
900 printf(
" %7.3f", gsl_vector_get(s->x, k));
903 printf(
" %7.3f", 1.0 - sumW);
909 for (; k < (nDimensions - 1) * K; k++) {
910 double dx_k = gsl_vector_get(s->dx, k);
911 printf(
" %7.3f", dx_k);
912 dxMax = (dxMax < dx_k) ? dx_k : dxMax;
915 printf(
" max(dxyw) = %7.3f", dxMax);
916 printf(
" Jacobian\n");
918 for (
int k = 0; k < K; k++) {
919 if (nDimensions == 3) {
920 printf(
" k=%2d mux:", k);
921 for (
int i = 0;
i < N;
i++) {
922#if GSL_MAJOR_VERSION < 2
923 printf(
" % 7.3f", gsl_matrix_get(s->J,
i, k));
928 printf(
" k=%2d mux/y:", k);
929 for (
int i = 0;
i < N;
i++) {
930#if GSL_MAJOR_VERSION < 2
931 printf(
" % 7.3f", gsl_matrix_get(s->J,
i, k + (nDimensions - 2) * K));
936 printf(
" k=%2d w :", k);
937 for (
int i = 0;
i < N;
i++) {
938#if GSL_MAJOR_VERSION < 2
939 printf(
" % 7.3f", gsl_matrix_get(s->J,
i, k + (nDimensions - 1) * K));
949 int dimOfParameters,
int axe,
int mode,
950 double* thetaFinal,
double* khi2,
double* pError)
957 int verbose = p & 0x3;
959 int doJacobian = p & 0x1;
961 int computeKhi2 = p & 0x1;
963 int computeStdDev = p & 0x1;
965 printf(
"\n> [fitMathieson] Fitting \n");
967 " mode: verbose, doJacobian, computeKhi2, computeStdDev %d %d %d %d\n",
968 verbose, doJacobian, computeKhi2, computeStdDev);
979 double* muAndWi =
getMuAndW(thetaInit, kInit);
982 double* muAndWf =
getMuAndW(thetaFinal, kInit);
983 if (dimOfParameters * kInit - 1 > N) {
985 muAndWf[kInit] = NAN;
986 muAndWf[2 * kInit] = NAN;
991 double cathMax[2] = {0.0, 0.0};
1005 mathiesonData.
N = N;
1006 mathiesonData.
K = kInit;
1007 double* xInf =
new double[N];
1008 double* xSup =
new double[N];
1009 double* yInf =
new double[N];
1010 double* ySup =
new double[N];
1011 vectorAddVector(iPads.
getX(), -1.0, iPads.
getDX(), N, xInf);
1012 vectorAddVector(iPads.
getX(), +1.0, iPads.
getDX(), N, xSup);
1013 vectorAddVector(iPads.
getY(), -1.0, iPads.
getDY(), N, yInf);
1014 vectorAddVector(iPads.
getY(), +1.0, iPads.
getDY(), N, ySup);
1022 vectorCopyShort(iPads.
getSaturates(), N, notSaturated);
1023 vectorNotShort(notSaturated, N, notSaturated);
1026 mathiesonData.
axe = axe;
1046 double zCathTotalCharge[2];
1047 double cathCoefNorm[2] = {0.0};
1053 zCathTotalCharge[0] = vectorMaskedSum(mathiesonData.
zObs_ptr,
mask, N);
1059 zCathTotalCharge[1] = vectorMaskedSum(mathiesonData.
zObs_ptr,
mask, N);
1062 cathWeights =
new double[N];
1063 for (
int i = 0;
i < N;
i++) {
1064 cathWeights[
i] = (mathiesonData.
cath_ptr[
i] == 0) ? zCathTotalCharge[0]
1065 : zCathTotalCharge[1];
1066 cathMax[mathiesonData.
cath_ptr[
i]] = std::fmax(
1081 mathiesonData.
verbose = verbose;
1084 gsl_multifit_function_fdf
f;
1090 f.p = dimOfParameters * kInit - 1;
1091 f.params = &mathiesonData;
1097 int maxIndex[kInit];
1098 for (
int k = 0; k < kInit; k++) {
1101 double*
w = &muAndWi[2 * kInit];
1102 std::sort(maxIndex, &maxIndex[kInit],
1103 [=](
int a,
int b) {
return (
w[
a] >
w[
b]); });
1109 double muAndWTest[dimOfParameters * K];
1111 if (dimOfParameters == 3) {
1112 for (
int k = 0; k < K; k++) {
1114 muAndWTest[k] = muAndWi[maxIndex[k]];
1115 muAndWTest[k + K] = muAndWi[maxIndex[k] + kInit];
1116 muAndWTest[k + 2 * K] = muAndWi[maxIndex[k] + 2 * kInit];
1119 for (
int k = 0; k < K; k++) {
1123 muAndWTest[k] = muAndWi[maxIndex[k]];
1126 muAndWTest[k] = muAndWi[maxIndex[k] + kInit];
1130 muAndWTest[k + K] = muAndWi[maxIndex[k] + 2 * kInit];
1136 if (dimOfParameters == 3) {
1137 vectorPrint(
" Selected w", &muAndWTest[2 * K], K);
1141 printf(
" Selected dimOfParameters=2, axe=%d", axe);
1146 mathiesonData.
K = K;
1147 f.p = dimOfParameters * K - 1;
1151 gsl_vector_view params0 = gsl_vector_view_array(muAndWTest, dimOfParameters * K - 1);
1154 gsl_multifit_fdfsolver* s = gsl_multifit_fdfsolver_alloc(
1155 gsl_multifit_fdfsolver_lmsder, N, dimOfParameters * K - 1);
1157 gsl_multifit_fdfsolver_set(s, &
f, ¶ms0.vector);
1163 double initialResidual = 0.0;
1165 status = GSL_CONTINUE;
1166 double residual = DBL_MAX;
1167 double prevResidual = DBL_MAX;
1168 double prevTheta[dimOfParameters * K - 1];
1171 for (; (status == GSL_CONTINUE) && (iter < 50); iter++) {
1173 for (
int k = 0; k < (dimOfParameters * K - 1); k++) {
1174 prevTheta[k] = gsl_vector_get(s->x, k);
1178 status = gsl_multifit_fdfsolver_iterate(s);
1180 printf(
" Solver status = %s\n", gsl_strerror(status));
1192 status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4);
1194 printf(
" Status multifit_test_delta = %d %s\n", status,
1195 gsl_strerror(status));
1198 prevResidual = residual;
1199 residual = gsl_blas_dnrm2(s->f);
1205 double tmp[(dimOfParameters - 1) * K];
1206 vectorAbs(s->dx->data, (dimOfParameters - 1) * K, tmp);
1207 double maxDxy = vectorMax(tmp, (dimOfParameters - 1) * K);
1213 printf(
" Stop iteration iteration=%d (dResidu/residu~0), prevResidual=%f residual=%f\n",
1214 iter, prevResidual, residual);
1215 printf(
" End max dxy=%f\n", vectorMax(s->dx->data, (dimOfParameters - 1) * K));
1217 printf(
" End max dw=%f\n", vectorMax(&s->dx->data[(dimOfParameters - 1) * K], K - 1));
1220 for (
int k = 0; k < (dimOfParameters * K - 1); k++) {
1221 gsl_vector_set(s->x, k, prevTheta[k]);
1223 status = GSL_SUCCESS;
1226 double finalResidual = gsl_blas_dnrm2(s->f);
1227 bool keepInitialTheta =
1228 fabs(finalResidual - initialResidual) / initialResidual < 1.0e-1;
1231 if (computeKhi2 && (khi2 !=
nullptr)) {
1233 double chi = gsl_blas_dnrm2(s->f);
1234 double dof = N - (dimOfParameters * K - 1);
1235 double c = fmax(1.0, chi / sqrt(dof));
1237 printf(
" K=%d, chi=%f, chisq/dof = %g\n", K, chi * chi,
1240 khi2[0] = chi * chi / dof;
1246 copyTheta(thetaInit, kInit, thetaFinal, kInit, kInit);
1256 for (
int k = 0; k < K; k++) {
1259 muAndWf[k] = gsl_vector_get(s->x, k);
1262 muAndWf[k + kInit] = iPads.
getY()[0];
1263 }
else if (axe == 1) {
1266 muAndWf[k] = iPads.
getX()[0];
1268 muAndWf[k + kInit] = gsl_vector_get(s->x, k);
1269 }
else if (axe == -1) {
1271 muAndWf[k] = gsl_vector_get(s->x, k);
1273 muAndWf[k + kInit] = gsl_vector_get(s->x, k + K);
1278 for (
int k = 0; k < K - 1; k++) {
1279 double w = gsl_vector_get(s->x, k + (dimOfParameters - 1) * K);
1281 muAndWf[k + 2 * kInit] =
w;
1284 muAndWf[3 * kInit - 1] = 1.0 - sumW;
1299 printf(
" status parameter error = %s\n", gsl_strerror(status));
1301 gsl_multifit_fdfsolver_free(s);
1307 delete[] cathWeights;