37 #include <cxmessages.h>
41 #include "gimath_lm.h"
42 #include "gimessages.h"
58 #define SWAP(a,b) {swap=(a);(a)=(b);(b)=swap;}
69 {LMRQ_GAUSSUM, mrqgaussum, 4, 1,
"gaussum", LINE_MODEL},
70 {LMRQ_XOPTMOD, mrqxoptmod, 7, 3,
"xoptmod", XOPT_MODEL},
71 {LMRQ_XOPTMODGS, mrqxoptmodGS, 7, 3,
"xoptmodGS", XOPT_MODEL},
72 {LMRQ_XOPTMOD2, mrqxoptmod2, 10, 3,
"xoptmod2", XOPT_MODEL},
73 {LMRQ_PSFCOS, mrqpsfcos, 5, 1,
"psfcos", LINE_MODEL},
74 {LMRQ_PSFEXP, mrqpsfexp, 5, 1,
"psfexp", LINE_MODEL},
75 {LMRQ_YOPTMOD, mrqyoptmod, 7, 3,
"yoptmod", YOPT_MODEL},
76 {LMRQ_YOPTMOD2, mrqyoptmod2, 10, 3,
"yoptmod2", YOPT_MODEL},
77 {LMRQ_LOCYWARP, mrqlocywarp, 5, 4,
"locywarp", LOCY_MODEL},
78 {LMRQ_PSFEXP2, mrqpsfexp2, 5, 1,
"psfexp2", LINE_MODEL},
79 {LMRQ_TEST, mrqtest, 2, 1,
"test", LINE_MODEL}
82 cxint nr_lmrq_models = CX_N_ELEMENTS(lmrq_models);
102 covariance_sort(cpl_matrix *covar, cxint ma, cxint ia[], cxint mfit)
105 register cxint i, j, k;
106 register cxdouble swap;
108 cxdouble *pd_covar = NULL;
111 pd_covar = cpl_matrix_get_data(covar);
112 nr_covar = cpl_matrix_get_nrow(covar);
114 for (i = mfit; i < ma; i++)
115 for (j = 0; j <= i; j++)
116 pd_covar[i * nr_covar + j] = pd_covar[j * nr_covar + i] = 0.0;
119 for (j = (ma-1); j >= 0; j--) {
121 for (i = 0; i < ma; i++)
122 SWAP(pd_covar[i * nr_covar + k],pd_covar[i * nr_covar + j])
124 for (i = 0;i < ma; i++)
125 SWAP(pd_covar[k * nr_covar + i],pd_covar[j * nr_covar + i])
162 mrqdydaweight(cxdouble x, cxdouble x0, cxdouble dx)
166 w = exp(-pow(fabs(x-x0),DW_DEGREE)/pow(dx,DW_DEGREE/DW_LOG001));
212 lmrq_params fit_params,
223 cpl_matrix *beta = NULL;
229 beta = cpl_matrix_new(ma,ma);
233 res = mymrqmin(x, y, sig, ndata, a, r, ia, ma, alpha, beta, chisq,
237 cpl_matrix_delete(beta); beta = NULL;
243 for (n = 1; n <= fit_params.imax; n++) {
247 res = mymrqmin(x, y, sig, ndata, a, r, ia, ma, alpha, beta, chisq,
251 cpl_matrix_delete(beta); beta = NULL;
257 else if (fabs(ochisq-*chisq) < fit_params.dchsq)
260 if (itst > fit_params.tmax)
267 res = mymrqmin(x, y, sig, ndata, a, r, ia, ma, alpha, beta, chisq,
271 cpl_matrix_delete(beta); beta = NULL;
275 cpl_matrix_delete(beta); beta = NULL;
354 register cxint gj, j, k, l, m;
356 static cxdouble *pd_a, *pd_covar, *pd_alpha;
357 static cxint nr_covar, nr_alpha, nr_moneda, mfit;
359 static cpl_matrix *matry, *mbeta, *mda, *moneda;
360 static cxdouble *atry, *beta, *da, *oneda, ochisq;
366 pd_a = cpl_matrix_get_data(a);
367 pd_covar = cpl_matrix_get_data(covar);
368 pd_alpha = cpl_matrix_get_data(alpha);
369 nr_covar = cpl_matrix_get_nrow(covar);
370 nr_alpha = cpl_matrix_get_nrow(alpha);
374 matry = cpl_matrix_new(ma,1);
375 atry = cpl_matrix_get_data(matry);
377 mbeta = cpl_matrix_new(ma,1);
378 beta = cpl_matrix_get_data(mbeta);
380 mda = cpl_matrix_new(ma,1);
381 da = cpl_matrix_get_data(mda);
383 for (mfit = 0, j = 0; j < ma; j++)
387 moneda = cpl_matrix_new(1,mfit);
388 oneda = cpl_matrix_get_data(moneda);
392 gj = mymrqcof(x, y, sig, ndata, a, r, ia, ma, alpha, mbeta,
396 cpl_matrix_delete(moneda); moneda = NULL; oneda = NULL;
397 cpl_matrix_delete(mda); mda = NULL; da = NULL;
398 cpl_matrix_delete(mbeta); mbeta = NULL; beta = NULL;
399 cpl_matrix_delete(matry); matry = NULL; atry = NULL;
405 for (j = 0; j < ma; j++)
410 nr_moneda = cpl_matrix_get_nrow(moneda);
412 for (j = -1, l = 0; l < ma; l++) {
414 for (j++, k = -1, m = 0; m < ma; m++) {
417 pd_covar[j * nr_covar + k] = pd_alpha[j * nr_alpha + k];
421 pd_covar[j * nr_covar + j] =
422 pd_alpha[j * nr_alpha + j] * (1.0 + (*alamda));
424 oneda[j * nr_moneda + 0] = beta[j];
428 gj = giraffe_gauss_jordan(covar, mfit, moneda, 1);
431 cpl_matrix_delete(moneda); moneda = NULL; oneda = NULL;
432 cpl_matrix_delete(mda); mda = NULL; da = NULL;
433 cpl_matrix_delete(mbeta); mbeta = NULL; beta = NULL;
434 cpl_matrix_delete(matry); matry = NULL; atry = NULL;
438 for (j = 0; j < mfit; j++)
439 da[j] = oneda[j * nr_moneda + 0];
441 if (*alamda == 0.0) {
442 covariance_sort(covar, ma, ia, mfit);
443 cpl_matrix_delete(moneda); moneda = NULL; oneda = NULL;
444 cpl_matrix_delete(mda); mda = NULL; da = NULL;
445 cpl_matrix_delete(mbeta); mbeta = NULL; beta = NULL;
446 cpl_matrix_delete(matry); matry = NULL; atry = NULL;
450 for (j = -1, l = 0; l < ma; l++)
452 atry[l] = pd_a[l] + da[++j];
454 gj = mymrqcof(x, y, sig, ndata, matry, r, ia, ma, covar, mda,
458 cpl_matrix_delete(moneda); moneda = NULL; oneda = NULL;
459 cpl_matrix_delete(mda); mda = NULL; da = NULL;
460 cpl_matrix_delete(mbeta); mbeta = NULL; beta = NULL;
461 cpl_matrix_delete(matry); matry = NULL; atry = NULL;
465 if (*chisq < ochisq) {
470 for (j = -1, l = 0; l < ma; l++) {
472 for (j++, k = -1, m = 0; m < ma; m++) {
475 pd_alpha[j * nr_alpha + k] =
476 pd_covar[j * nr_covar + k];
537 register cxint i, j, k, l, m, mfit = 0;
539 cxdouble ymod, wt, sig2i, dy, *dyda;
541 cxdouble *pd_x = NULL,
548 cxint nr_alpha, nc_x;
554 pd_x = cpl_matrix_get_data(x);
555 nc_x = cpl_matrix_get_ncol(x);
556 pd_y = cpl_matrix_get_data(y);
557 pd_sig = cpl_matrix_get_data(sig);
558 pd_a = cpl_matrix_get_data(a);
559 pd_alpha = cpl_matrix_get_data(alpha);
560 nr_alpha = cpl_matrix_get_nrow(alpha);
561 pd_beta = cpl_matrix_get_data(beta);
563 for (j = 0; j < ma; j++) {
568 for (j = 0; j < mfit; j++) {
569 for (k = 0; k <= j; k++)
570 pd_alpha[j * nr_alpha + k] = 0.0;
577 dyda = (cxdouble *) cx_calloc(ma,
sizeof(cxdouble));
579 for (i = 0; i < ndata; i++) {
581 (*funcs)(&(pd_x[i*nc_x]), pd_a, r, &ymod, dyda, ma);
583 if (pd_sig[i]==0.0) {
587 sig2i = 1.0 / (pd_sig[i] * pd_sig[i]);
591 for (j = -1, l = 0; l < ma; l++) {
594 wt = dyda[l] * sig2i;
595 for (j++, k = -1, m = 0; m <= l; m++) {
598 pd_alpha[j * nr_alpha + k] += (wt * dyda[m]);
602 pd_beta[j] += (dy * wt);
607 *chisq += (dy * dy * sig2i);
611 for (j = 1; j < mfit; j++)
612 for (k = 0; k < j; k++)
613 pd_alpha[k * nr_alpha + j] = pd_alpha[j * nr_alpha + k];
639 r_squared(cxdouble resSS, cpl_matrix *y, cxint n)
642 register cxdouble Sy, Syy, SS;
643 cxdouble res, *pd_y = NULL;
645 pd_y = cpl_matrix_get_data(y);
650 for (i=0, Sy=0.0, Syy=0.0; i<n; i++) {
652 Syy += pd_y[i]*pd_y[i];
700 mrqgaussum(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
701 cxdouble dyda[], cxint na)
705 register cxdouble fac,ex,amplitude,center,backg,width,xred;
710 for (j = 0, i = 0; i < na; i += 4, j += 4) {
715 xred = (x[0] - center) / width;
716 ex = exp(-xred * xred / 2.);
717 fac = amplitude * xred * ex;
718 *y += (amplitude * ex + backg);
721 if (dyda == NULL)
continue;
725 dyda[j + 1] = fac / width;
727 dyda[j + 3] = (fac * xred) / width;
784 mrqxoptmod(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
785 cxdouble dyda[], cxint na)
788 const cxchar *fctid =
"mrqxoptmod";
790 register cxdouble xccd, d, X;
791 register cxdouble lambda,xfibre,yfibre,pixsize,nx;
793 register cxdouble fcoll,cfact;
795 register cxdouble gtheta,gorder,gspace;
796 register cxdouble yfibre2,tmp,tmp2,d2,X2,gspace2,sqtmp,costheta,sintheta;
800 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
806 dyda[0] = dyda[1] = dyda[2] = dyda[3] =
807 dyda[4] = dyda[5] = dyda[6] = 0.0;
810 lambda = x[LMI_WLEN];
811 xfibre = x[LMI_XFIB];
812 yfibre = x[LMI_YFIB];
815 pixsize = a[LMP_PXSIZ];
816 fcoll = a[LMP_FCOLL];
817 cfact = a[LMP_CFACT];
818 gtheta = a[LMP_THETA];
819 gorder = a[LMP_ORDER];
820 gspace = a[LMP_SPACE];
822 yfibre2 = yfibre * yfibre;
823 gspace2 = gspace * gspace;
824 costheta = cos(gtheta);
825 sintheta = sin(gtheta);
826 d2 = xfibre * xfibre + yfibre2 + (fcoll * fcoll);
828 X = (-lambda*gorder/gspace) + (xfibre*costheta/d) + (fcoll*sintheta/d);
830 sqtmp = sqrt(1.0 - yfibre2/d2 - X2);
831 tmp = -sintheta*X + costheta*sqtmp;
833 xccd = (cfact * fcoll * (X*costheta + sintheta*sqtmp))/tmp;
837 *y = (xccd / pixsize - 0.5*nx);
839 *y = (-xccd / pixsize + 0.5*nx);
847 dyda[LMP_PXSIZ] = 0.0;
849 dyda[LMP_FCOLL] = cfact*(costheta*X+sintheta*sqtmp)/tmp +
850 cfact*fcoll*(costheta*(-X*fcoll/d2+sintheta/d -
851 gorder*lambda*fcoll/(d2*gspace)) +
852 0.5*sintheta*(-2.0*X*(-X*fcoll/d2+sintheta/d -
853 gorder*lambda*fcoll/(d2*gspace))+2.0*yfibre2*fcoll/(d2*d2))/sqtmp)/tmp -
854 cfact*fcoll*(costheta*X+sintheta*sqtmp)*(-sintheta*(-X*fcoll/d2 +
855 sintheta/d-gorder*lambda*fcoll/(d2*gspace)) +
856 0.5*costheta*(-2.0*X*(-X*fcoll/d2+sintheta/d -
857 gorder*lambda*fcoll/(d2*gspace))+2.0*yfibre2*fcoll/(d2*d2))/sqtmp)/tmp2;
858 dyda[LMP_FCOLL] /= pixsize;
860 dyda[LMP_CFACT] = (xccd/cfact)/pixsize;
862 dyda[LMP_THETA] = cfact*fcoll*((-xfibre*sintheta/d+fcoll*costheta/d)*costheta -
863 sintheta*X-sintheta*X*(-xfibre*sintheta/d+fcoll*costheta/d)/sqtmp +
864 costheta*sqtmp)/tmp -
865 cfact*fcoll*(costheta*X+sintheta*sqtmp)*(-(-xfibre*sintheta/d +
866 fcoll*costheta/d)*sintheta-costheta*X -
867 costheta*X*(-xfibre*sintheta/d+fcoll*costheta/d)/sqtmp -
868 sintheta*sqtmp)/tmp2;
869 dyda[LMP_THETA] /= pixsize;
871 dyda[LMP_ORDER] = 0.0;
872 dyda[LMP_SPACE] = cfact*fcoll*(lambda*gorder*costheta/gspace2-sintheta*X*lambda*gorder/(sqtmp*gspace2))/tmp -
873 cfact*fcoll*(X*costheta+sintheta*sqtmp) *
874 (-lambda*gorder*sintheta/gspace2-costheta*X*lambda*gorder/(sqtmp*gspace2))/tmp2;
875 dyda[LMP_SPACE] /= pixsize;
878 dyda[LMP_NX] = -dyda[LMP_NX];
879 dyda[LMP_PXSIZ] = -dyda[LMP_PXSIZ];
880 dyda[LMP_FCOLL] = -dyda[LMP_FCOLL];
881 dyda[LMP_CFACT] = -dyda[LMP_CFACT];
882 dyda[LMP_THETA] = -dyda[LMP_THETA];
883 dyda[LMP_ORDER] = -dyda[LMP_ORDER];
884 dyda[LMP_SPACE] = -dyda[LMP_SPACE];
892 dyda[LMP_FCOLL] *= mrqdydaweight(a[LMP_FCOLL],r[k],r[k+1]);
896 dyda[LMP_CFACT] *= mrqdydaweight(a[LMP_CFACT],r[k],r[k+1]);
900 dyda[LMP_THETA] *= mrqdydaweight(a[LMP_THETA],r[k],r[k+1]);
904 dyda[LMP_SPACE] *= mrqdydaweight(a[LMP_SPACE],r[k],r[k+1]);
972 mrqxoptmod2(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
973 cxdouble dyda[], cxint na)
976 const cxchar *fctid =
"mrqxoptmod2";
978 register cxdouble lambda,xfibre,yfibre,pixsize,nx;
980 register cxdouble fcoll,cfact;
982 register cxdouble gtheta,gorder,gspace;
984 cxdouble slitdx,slitdy,slitphi;
986 register cxdouble t1,t10,t104,t107,t11,t113,t119,t12,t120,t121,t124,t136,
987 t137,t138,t14,t143,t148,t16,t161,t162,t166,t168,t17,t173,
988 t18,t19,t191,t195,t196,t2,t20,t201,t21,t210,t23,t24,t26,
989 t27,t28,t3,t30,t32,t33,t34,t35,t36,t37,t38,t39,t4,t40,t44,
990 t49,t52,t58,t60,t61,t62,t64,t68,t75,t76,t78,t80,t9,t91,t93;
994 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1000 dyda[0] = dyda[1] = dyda[2] = dyda[3] =
1001 dyda[4] = dyda[5] = dyda[6] =
1002 dyda[7] = dyda[8] = dyda[9] = 0.0;
1005 lambda = x[LMI_WLEN];
1006 xfibre = x[LMI_XFIB];
1007 yfibre = x[LMI_YFIB];
1010 pixsize = a[LMP_PXSIZ];
1011 fcoll = a[LMP_FCOLL];
1012 cfact = a[LMP_CFACT];
1013 gtheta = a[LMP_THETA];
1014 gorder = a[LMP_ORDER];
1015 gspace = a[LMP_SPACE];
1016 slitdx = a[LMP_SOFFX];
1017 slitdy = a[LMP_SOFFY];
1018 slitphi = a[LMP_SPHI];
1024 t9 = xfibre*(1.0+slitphi*yfibre)+slitdx;
1027 t12 = slitphi*slitphi;
1028 t14 = sqrt(1.0-t12);
1029 t16 = yfibre*t14+slitdy;
1037 t26 = -t3*t4+t10*t21+t24*t21;
1041 t32 = sqrt(1.0-t17*t28-t30);
1050 t44 = pixsize*pixsize;
1053 t58 = -t10*t52*fcoll+t23*t21-t18*t23*t52;
1058 t68 = 2.0*t64*fcoll-2.0*t26*t58;
1063 t91 = -t9*t23*t21+fcoll*t2*t21;
1066 t107 = t26*lambda*t4;
1068 t119 = gspace*gspace;
1075 t143 = t136-t10*t138/2.0-t24*t138/2.0;
1076 t148 = t64*t137-2.0*t26*t143;
1079 t166 = -t10*t162/2.0-t24*t162/2.0;
1081 t173 = -2.0*t168+t64*t161-2.0*t26*t166;
1083 t195 = 2.0*t9*xfibre*yfibre-2.0*t16*yfibre*t191*slitphi;
1085 t201 = xfibre*yfibre*t136-t10*t196/2.0-t24*t196/2.0;
1086 t210 = 2.0*t168*yfibre*t191*slitphi+t64*t195-2.0*t26*t201;
1090 *y = t1*t39*t40-0.5*nx;
1092 *y = -t1*t39*t40+0.5*nx;
1100 dyda[LMP_PXSIZ] = -t1*t39/t44;
1102 cfact*t34*t49+t1*(t2*t58+t61*t68/2.0)*t38*t40 -
1103 t75*t78*(-t23*t58+t80*t68/2.0);
1107 t1*(-t35+t2*t91+t36-t61*t93)*t38*t40 -
1108 t75*t78*(-t27-t23*t91-t33-t80*t93);
1110 t1*(-t104*t4+t61*t107)*t38*t40-t75*t78*(t113*t4+t80*t107);
1112 t1*(t104*t121-t61*t26*t124)*t38*t40 -
1113 t75*t78*(-t113*t121-t80*t26*t124);
1115 t1*(t2*t143+t61*t148/2.0)*t38*t40 -
1116 t75*t78*(-t23*t143+t80*t148/2.0);
1118 t1*(t2*t166+t61*t173/2.0)*t38*t40 -
1119 t75*t78*(-t23*t166+t80*t173/2.0);
1121 t1*(t2*t201+t61*t210/2.0)*t38*t40 -
1122 t75*t78*(-t23*t201+t80*t210/2.0);
1125 dyda[LMP_NX] = -dyda[LMP_NX];
1126 dyda[LMP_PXSIZ] = -dyda[LMP_PXSIZ];
1127 dyda[LMP_FCOLL] = -dyda[LMP_FCOLL];
1128 dyda[LMP_CFACT] = -dyda[LMP_CFACT];
1129 dyda[LMP_THETA] = -dyda[LMP_THETA];
1130 dyda[LMP_ORDER] = -dyda[LMP_ORDER];
1131 dyda[LMP_SPACE] = -dyda[LMP_SPACE];
1132 dyda[LMP_SOFFX] = -dyda[LMP_SOFFX];
1133 dyda[LMP_SOFFY] = -dyda[LMP_SOFFY];
1134 dyda[LMP_SPHI] = -dyda[LMP_SPHI];
1142 dyda[LMP_PXSIZ] *= mrqdydaweight(a[LMP_PXSIZ],r[k],r[k+1]);
1146 dyda[LMP_FCOLL] *= mrqdydaweight(a[LMP_FCOLL],r[k],r[k+1]);
1150 dyda[LMP_CFACT] *= mrqdydaweight(a[LMP_CFACT],r[k],r[k+1]);
1154 dyda[LMP_THETA] *= mrqdydaweight(a[LMP_THETA],r[k],r[k+1]);
1158 dyda[LMP_ORDER] *= mrqdydaweight(a[LMP_ORDER],r[k],r[k+1]);
1162 dyda[LMP_SPACE] *= mrqdydaweight(a[LMP_SPACE],r[k],r[k+1]);
1166 dyda[LMP_SOFFX] *= mrqdydaweight(a[LMP_SOFFX],r[k],r[k+1]);
1170 dyda[LMP_SOFFY] *= mrqdydaweight(a[LMP_SOFFY],r[k],r[k+1]);
1174 dyda[LMP_SPHI] *= mrqdydaweight(a[LMP_SPHI],r[k],r[k+1]);
1245 mrqyoptmod(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1246 cxdouble dyda[], cxint na)
1249 const cxchar *fctid =
"mrqyoptmod";
1251 register cxdouble lambda,xfibre,yfibre,pixsize,ny;
1253 register cxdouble fcoll,cfact;
1255 register cxdouble gtheta,gorder,gspace;
1257 cxdouble t10,t12,t13,t15,t18,t2,t22,t24,t26,t27,t28,t29,t3,t30,t33,
1258 t4,t41,t45,t47,t5,t53,t56,t57,t6,t7,t76,t8,t9,t93,t94;
1264 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1270 dyda[LMP_NX] = dyda[LMP_PXSIZ] = dyda[LMP_FCOLL] = dyda[LMP_CFACT] =
1271 dyda[LMP_THETA] = dyda[LMP_ORDER] = dyda[LMP_SPACE] = 0.0;
1274 lambda = x[LMI_WLEN];
1275 xfibre = x[LMI_XFIB];
1276 yfibre = x[LMI_YFIB];
1279 pixsize = a[LMP_PXSIZ];
1280 fcoll = a[LMP_FCOLL];
1281 cfact = a[LMP_CFACT];
1282 gtheta = a[LMP_THETA];
1283 gorder = a[LMP_ORDER];
1284 gspace = a[LMP_SPACE];
1286 t2 = cfact*fcoll*yfibre;
1298 t18 = -t9*t10+t13*t8+fcoll*t15*t8;
1300 t24 = sqrt(1.0-t4/t6-t22);
1301 t26 = -t18*t15+t12*t24;
1306 t33 = pixsize*pixsize;
1310 t53 = -t13*t41*fcoll+t15*t8-t5*t15*t41;
1313 t76 = -xfibre*t15*t8+fcoll*t12*t8;
1314 t93 = gspace*gspace;
1317 *y = -t2*t30+0.5*ny;
1320 if (dyda == NULL)
return;
1325 dyda[LMP_PXSIZ] = t2*t28/t33;
1326 dyda[LMP_FCOLL] = -cfact*yfibre*t30+cfact*t5*yfibre*t41*t27*t29+t2*t47*t29*
1327 (-t53*t15+t56*(2.0*t4/t57*fcoll-2.0*t18*t53)/2.0);
1328 dyda[LMP_CFACT] = -fcoll*yfibre*t30;
1329 dyda[LMP_THETA] = t2*t47*t29*(-t76*t15-t18*t12-t15*t24-t56*t18*t76);
1330 dyda[LMP_ORDER] = t2*t47*t29*(lambda*t10*t15+t56*t18*lambda*t10);
1331 dyda[LMP_SPACE] = t2*t47*t29*(-t9*t94*t15-t56*t18*t9*t94);
1408 mrqyoptmod2(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1409 cxdouble dyda[], cxint na)
1412 const cxchar *fctid =
"mrqyoptmod2";
1414 register cxdouble lambda,xfibre,yfibre,pixsize,ny;
1416 register cxdouble fcoll,cfact;
1418 register cxdouble gtheta,gorder,gspace;
1420 cxdouble slitdx,slitdy,slitphi;
1422 double t1,t102,t103,t11,t112,t117,t118,t12,t123,t13,t136,t14,t141,t145,
1423 t147,t15,t159,t16,t160,t17,t172,t179,t18,t184,t19,t2,t21,t22,t24,
1424 t25,t27,t29,t31,t33,t35,t36,t37,t38,t39,t4,t42,t50,t51,t54,t56,t6,
1425 t62,t65,t66,t68,t7,t85;
1431 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1437 dyda[LMP_NY] = dyda[LMP_PXSIZ] = dyda[LMP_FCOLL] = dyda[LMP_CFACT] =
1438 dyda[LMP_THETA] = dyda[LMP_ORDER] = dyda[LMP_SPACE] =
1439 dyda[LMP_SOFFX] = dyda[LMP_SOFFY] = dyda[LMP_SPHI] = 0.0;
1442 lambda = x[LMI_WLEN];
1443 xfibre = x[LMI_XFIB];
1444 yfibre = x[LMI_YFIB];
1447 pixsize = a[LMP_PXSIZ];
1448 fcoll = a[LMP_FCOLL];
1449 cfact = a[LMP_CFACT];
1450 gtheta = a[LMP_THETA];
1451 gorder = a[LMP_ORDER];
1452 gspace = a[LMP_SPACE];
1453 slitdx = a[LMP_SOFFX];
1454 slitdy = a[LMP_SOFFY];
1455 slitphi = a[LMP_SPHI];
1458 t2 = slitphi*slitphi;
1460 t6 = yfibre*t4+slitdy;
1462 t11 = xfibre*(1.0+slitphi*yfibre)+slitdx;
1469 t18 = lambda*gorder;
1475 t27 = -t18*t19+t22*t17+t25*t17;
1478 t33 = sqrt(1.0-t13*t29-t31);
1479 t35 = -t27*t24+t21*t33;
1484 t42 = pixsize*pixsize;
1489 t62 = -t22*t50*fcoll+t24*t17-t14*t24*t50;
1493 t85 = -t11*t24*t17+fcoll*t21*t17;
1494 t102 = gspace*gspace;
1499 t123 = t117-t22*t118/2.0-t25*t118/2.0;
1502 t145 = -t22*t141/2.0-t25*t141/2.0;
1506 t172 = 2.0*t11*xfibre*yfibre-2.0*t6*yfibre*t159*slitphi;
1508 t184 = xfibre*yfibre*t117-t22*t179/2.0-t25*t179/2.0;
1510 *y = -t7*t39+0.5*ny;
1513 if (dyda == NULL)
return;
1517 dyda[LMP_PXSIZ] = t7*t37/t42;
1519 -cfact*t6*t39+cfact*t14*t6*t51*t38+
1520 t7*t56*t38*(-t62*t24+t65*(2.0*t68*fcoll-2.0*t27*t62)/2.0);
1524 t7*t56*t38*(-t85*t24-t27*t21-t24*t33-t65*t27*t85);
1526 t7*t56*t38*(lambda*t19*t24+t65*t27*lambda*t19);
1528 t7*t56*t38*(-t18*t103*t24-t65*t27*t18*t103);
1530 t7*t51*t38*t112/2.0+t7*t56*t38*(-t123*t24+t65*
1531 (t68*t112-2.0*t27*t123)/2.0);
1533 -t1*t39+t7*t51*t38*t136/2.0+t7*t56*t38*(-t145*t24+t65*
1534 (-2.0*t147+t68*t136-2.0*t27*t145)/2.0);
1536 t1*t160*slitphi*t17*t36*t38+t7*t51*t38*t172/2.0+
1537 t7*t56*t38*(-t184*t24+t65*(2.0*t147*t160*slitphi+t68*t172-
1568 mrqpsfcos(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1569 cxdouble dyda[], cxint na)
1572 const cxchar *fctid =
"mrqpsfcos";
1574 cxdouble t1,t10,t13,t14,t15,t16,t2,t26,t3,t4,t5,t6,t7,t8,t9;
1576 cxdouble amplitude = a[LMP_AMPL];
1577 cxdouble center = a[LMP_CENT];
1578 cxdouble background = a[LMP_BACK];
1579 cxdouble width1 = a[LMP_WID1];
1580 cxdouble width2 = a[LMP_WID2];
1586 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1592 dyda[LMP_AMPL] = dyda[LMP_CENT] = dyda[LMP_BACK] = dyda[LMP_WID1] =
1593 dyda[LMP_WID2] = 0.0;
1600 t5 = pow(t4,width1);
1610 t26 = (t1>0.0)? 1.0:-1.0;
1616 if (dyda == NULL)
return;
1618 dyda[LMP_AMPL] = dyda[LMP_CENT] = dyda[LMP_BACK] = dyda[LMP_WID1] = 0.0;
1619 dyda[LMP_WID2] = 1.0;
1621 *y = amplitude*t10/8.0+background;
1627 dyda[LMP_AMPL] = t10/8.0;
1629 dyda[LMP_CENT] = 3.0/8.0*t13*t14*CX_PI*t5*width1*t26/t2;
1630 dyda[LMP_BACK] = 1.0;
1631 dyda[LMP_WID1] = -3.0/8.0*t15*t6*t16;
1632 dyda[LMP_WID2] = 3.0/8.0*t15*t6*width1*t3;
1665 mrqpsfexp(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1666 cxdouble dyda[], cxint na)
1669 const cxchar *fctid =
"mrqpsfexp";
1671 cxdouble t1,t2,t3,t4,t6,t8,t10,t15,t18;
1673 cxdouble amplitude = a[LMP_AMPL];
1674 cxdouble center = a[LMP_CENT];
1675 cxdouble background = a[LMP_BACK];
1676 cxdouble width1 = a[LMP_WID1];
1677 cxdouble width2 = a[LMP_WID2];
1681 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1687 dyda[LMP_AMPL] = dyda[LMP_CENT] = dyda[LMP_BACK] = dyda[LMP_WID1] =
1688 dyda[LMP_WID2] = 0.0;
1701 t3 = pow(t2,width2);
1705 t15 = width1*width1;
1708 *y = amplitude*t6+background;
1714 dyda[LMP_AMPL] = t6;
1715 dyda[LMP_CENT] = t8*width2*t10/t2*t4*t6;
1717 if (isnan(dyda[LMP_CENT]))
1718 dyda[LMP_CENT] = 0.;
1720 dyda[LMP_BACK] = 1.0;
1721 dyda[LMP_WID1] = t8/t15*t6;
1722 dyda[LMP_WID2] = -t8*t18*t4*t6;
1724 if (isnan(dyda[LMP_WID2]))
1725 dyda[LMP_WID2] = 0.;
1732 dyda[LMP_AMPL] *= mrqdydaweight(a[LMP_AMPL],r[k],r[k+1]);
1736 dyda[LMP_CENT] *= mrqdydaweight(a[LMP_CENT],r[k],r[k+1]);
1740 dyda[LMP_WID1] *= mrqdydaweight(a[LMP_WID1],r[k],r[k+1]);
1744 dyda[LMP_WID2] *= mrqdydaweight(a[LMP_WID2],r[k],r[k+1]);
1778 mrqpsfexp2(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1779 cxdouble dyda[], cxint na)
1782 const cxchar *fctid =
"mrqpsfexp2";
1784 cxdouble t1,t2,t3,t4,t5,t6,t8,t10,t16;
1786 cxdouble amplitude = a[LMP_AMPL];
1787 cxdouble center = a[LMP_CENT];
1788 cxdouble background = a[LMP_BACK];
1789 cxdouble width1 = a[LMP_WID1];
1790 cxdouble width2 = a[LMP_WID2];
1794 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1800 dyda[LMP_AMPL] = dyda[LMP_CENT] = dyda[LMP_BACK] = dyda[LMP_WID1] =
1801 dyda[LMP_WID2] = 0.0;
1816 t5 = pow(t4,width2);
1821 *y = amplitude*t6+background;
1827 dyda[LMP_AMPL] = t6;
1828 dyda[LMP_CENT] = t8*width2*t10/t2*t6;
1830 if (isnan(dyda[LMP_CENT]))
1831 dyda[LMP_CENT] = 0.0;
1833 dyda[LMP_BACK] = 1.0;
1834 dyda[LMP_WID1] = t8*width2*t3*t6;
1835 dyda[LMP_WID2] = -t8*t16*t6;
1837 if (isnan(dyda[LMP_WID2]))
1838 dyda[LMP_WID2] = 0.0;
1845 dyda[LMP_AMPL] *= mrqdydaweight(a[LMP_AMPL],r[k],r[k+1]);
1849 dyda[LMP_CENT] *= mrqdydaweight(a[LMP_CENT],r[k],r[k+1]);
1853 dyda[LMP_WID1] *= mrqdydaweight(a[LMP_WID1],r[k],r[k+1]);
1857 dyda[LMP_WID2] *= mrqdydaweight(a[LMP_WID2],r[k],r[k+1]);
1886 mrqlocywarp(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
1887 cxdouble dyda[], cxint na)
1890 const cxchar *fctid =
"mrqlocywarp";
1892 cxdouble xccd, nx, startx;
1893 register cxint i,ncoef;
1894 cxdouble Tx, Ty, cx, Ky, tt, xx;
1895 cpl_matrix *mBase = NULL, *mX = NULL;
1896 register cxdouble fxx = 0.0, f1xx = 0.0, f2xx = 0.0, z1;
1897 cxdouble *pd_x = NULL, *pd_mbase = NULL;
1901 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1907 dyda[LMP_TX] = dyda[LMP_TY] = dyda[LMP_CX] = dyda[LMP_KY] =
1913 startx = x[LMI_STRX];
1914 ncoef = (cxint) x[LMI_NCOF];
1924 mX = cpl_matrix_new(1,1);
1925 pd_x = cpl_matrix_get_data(mX);
1928 mBase = giraffe_chebyshev_base1d(startx, nx, ncoef, mX);
1930 pd_mbase = cpl_matrix_get_data(mBase);
1932 for (i = 0; i < ncoef; i++)
1933 fxx += pd_mbase[i] * x[i+4];
1936 for (i = 0; i < (ncoef - 1); i++)
1937 f1xx += pd_mbase[i] * (i+1)*x[i+5];
1941 for (i = 0; i < (ncoef - 2); i++)
1942 f2xx += pd_mbase[i] * (i+2)*x[i+6];
1945 if (mX!=NULL) { cpl_matrix_delete(mX); mX = NULL; pd_x = NULL; }
1946 if (mBase!=NULL) { cpl_matrix_delete(mBase); mBase = NULL; pd_mbase = NULL; }
1948 z1 = 1.0 - tt*tt + tt*f1xx;
1949 *y = Ky*(fxx-tt*xx)/z1 + Ty;
1956 (cx*Ky/z1)*((tt-f1xx) + tt*f2xx*(fxx-tt*xx)/z1);
1961 (Ky*(xccd-Tx)/z1)*((f1xx-tt) - tt*f2xx*(fxx-tt*xx)/z1);
1963 dyda[LMP_KY] = (fxx-tt*xx)/z1;
1965 (Ky/(z1*z1))*(-xx*(1.+tt*tt)+2.*tt*fxx-fxx*f1xx);
1972 dyda[LMP_TX] *= mrqdydaweight(a[LMP_TX],r[k],r[k+1]);
1976 dyda[LMP_CX] *= mrqdydaweight(a[LMP_CX],r[k],r[k+1]);
1980 dyda[LMP_KY] *= mrqdydaweight(a[LMP_KY],r[k],r[k+1]);
1984 dyda[LMP_TT] *= mrqdydaweight(a[LMP_TT],r[k],r[k+1]);
2013 mrqxoptmodGS(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
2014 cxdouble dyda[], cxint na)
2017 const cxchar *fctid =
"mrqxoptmodGS";
2019 register cxdouble lambda,xfibre,yfibre,pixsize,nx;
2021 register cxdouble fcoll,cfact;
2023 register cxdouble gtheta,gorder,gspace;
2025 register cxdouble t1,t10,t109,t11,t110,t114,t12,t14,t17,t18,t2,t21,t23,t24;
2026 register cxdouble t25,t26,t27,t28,t29,t3,t30,t31,t35,t40,t43,t49,t5,t51,t52;
2027 register cxdouble t53,t59,t6,t66,t67,t69,t7,t71,t8,t82,t84,t9,t95,t98;
2031 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
2037 dyda[LMP_NX] = dyda[LMP_PXSIZ] = dyda[LMP_FCOLL] = dyda[LMP_CFACT] =
2038 dyda[LMP_THETA] = dyda[LMP_ORDER] = dyda[LMP_SPACE] = 0.0;
2041 lambda = x[LMI_WLEN];
2042 xfibre = x[LMI_XFIB];
2043 yfibre = x[LMI_YFIB];
2046 pixsize = a[LMP_PXSIZ];
2047 fcoll = a[LMP_FCOLL];
2048 cfact = a[LMP_CFACT];
2049 gtheta = a[LMP_THETA];
2050 gorder = a[LMP_ORDER];
2051 gspace = a[LMP_SPACE];
2065 t17 = -t2*t3+t12*t6+fcoll*t14*t12;
2068 t23 = sqrt(1.0-t8/t10-t21);
2077 t35 = pixsize*pixsize;
2080 t49 = -t6*t43*fcoll+t14*t12-t9*t14*t43;
2084 t59 = 2.0*t8/t53*fcoll-2.0*t17*t49;
2089 t82 = -xfibre*t14*t12+fcoll*t5*t12;
2092 t98 = t17*lambda*t3;
2093 t109 = gspace*gspace;
2099 *y = t1*t30*t31-0.5*nx;
2101 *y = -t1*t30*t31+0.5*nx;
2109 dyda[LMP_PXSIZ] = -t1*t30/t35;
2111 cfact*t25*t40+t1*(t49*t5+t52*t59/2.0)*t29*t31-
2112 t66*t69*(-t49*t14+t71*t59/2.0);
2116 t1*(t82*t5-t26+t27-t52*t84)*t29*t31-
2117 t66*t69*(-t82*t14-t18-t24-t71*t84);
2119 t1*(-t95*t5+t52*t98)*t29*t31-t66*t69*(t95*t14+t71*t98);
2121 t1*(t2*t110*t5-t52*t17*t114)*t29*t31-
2122 t66*t69*(-t2*t110*t14-t71*t17*t114);
2125 dyda[LMP_NX] = -dyda[LMP_NX];
2126 dyda[LMP_PXSIZ] = -dyda[LMP_PXSIZ];
2127 dyda[LMP_FCOLL] = -dyda[LMP_FCOLL];
2128 dyda[LMP_CFACT] = -dyda[LMP_CFACT];
2129 dyda[LMP_THETA] = -dyda[LMP_THETA];
2130 dyda[LMP_ORDER] = -dyda[LMP_ORDER];
2131 dyda[LMP_SPACE] = -dyda[LMP_SPACE];
2139 dyda[LMP_PXSIZ] *= mrqdydaweight(a[LMP_PXSIZ],r[k],r[k+1]);
2143 dyda[LMP_FCOLL] *= mrqdydaweight(a[LMP_FCOLL],r[k],r[k+1]);
2147 dyda[LMP_CFACT] *= mrqdydaweight(a[LMP_CFACT],r[k],r[k+1]);
2151 dyda[LMP_THETA] *= mrqdydaweight(a[LMP_THETA],r[k],r[k+1]);
2155 dyda[LMP_ORDER] *= mrqdydaweight(a[LMP_ORDER],r[k],r[k+1]);
2159 dyda[LMP_SPACE] *= mrqdydaweight(a[LMP_SPACE],r[k],r[k+1]);
2189 mrqtest(cxdouble x[], cxdouble a[], cxdouble r[], cxdouble *y,
2190 cxdouble dyda[], cxint na)
2193 const cxchar *fctid =
"mrqtest";
2202 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
2207 *y = a1 * x[0] + b1;
struct definition to handle model functions