Astro-PAL

 view release on metacpan or  search on metacpan

palsrc/palFitxy.c  view on Meta::CPAN

*            coeffs[4] = E
*            coeffs[5] = F
*         ---
*         the model is:
*         ---
*            xe = A + B * xm + C * ym
*            ye = D + E * xm + F * ym
*         ---
*         For the "solid body rotation" option (itype=4), the
*         magnitudes of B and F, and of C and E, are equal.  The
*         signs of these coefficients depend on whether there is a
*         sign reversal between xe,ye and xm,ym;  fits are performed
*         with and without a sign reversal and the best one chosen.
*
*     4)  Error status values j=-1 and -2 leave coeffs unchanged;
*         if j=-3 coeffs may have been changed.

*  See also:
*      palPxy, palInvf, palXy2xy and palDcmpf

*  Authors:
*     PTW: Pat Wallace (STFC)
*     GSB: Graham Bell (EAO)

*  History:
*     2001-11-30 (PTW):
*        SLALIB implementation.
*     2005-09-08 (PTW):
*        Fix compiler uninitialised warnings.
*     2018-10-23 (GSB):
*        Initial version in C.

*  Copyright:
*     Copyright (C) 2005 P.T.Wallace. All rights reserved.
*     Copyright (C) 2018 East Asian Observatory.
*
*  Licence:
*     This program is free software; you can redistribute it and/or modify
*     it under the terms of the GNU General Public License as published by
*     the Free Software Foundation; either version 2 of the License, or
*     (at your option) any later version.
*
*     This program is distributed in the hope that it will be useful,
*     but WITHOUT ANY WARRANTY; without even the implied warranty of
*     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*     GNU General Public License for more details.
*
*     You should have received a copy of the GNU General Public License
*     along with this program (see SLA_CONDITIONS); if not, write to the
*     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
*     Boston, MA  02110-1301  USA
*-
*/

#include "pal.h"

void palFitxy ( int itype, int np, double xye[][2], double xym[][2],
                double coeffs[6], int *j) {

  int i, jstat, iw[4], nsol;
  double a, b, c, d, aold, bold, cold, dold, sold,
    p, sxe, sxexm, sxeym, sye, syeym, syexm, sxm,
    sym, sxmxm, sxmym, symym, xe, ye,
    xm, ym, v[4], dm3[3][3], dm4[4][4], det,
    sgn, sxxyy, sxyyx, sx2y2, sdr2, xr, yr;

  /* Preset the status */
  *j = 0;

  /* Variable initializations to avoid compiler warnings */
  a = 0.0;
  b = 0.0;
  c = 0.0;
  d = 0.0;
  aold = 0.0;
  bold = 0.0;
  cold = 0.0;
  dold = 0.0;
  sold = 0.0;

  /* Float the number of samples */
  p = (double) np;

  /* Check ITYPE */
  if (itype == 6) {
    /* Six-coefficient linear model */

    /* Check enough samples */
    if (np >= 3) {

      /* Form summations */
      sxe = 0.0;
      sxexm = 0.0;
      sxeym = 0.0;
      sye = 0.0;
      syeym = 0.0;
      syexm = 0.0;
      sxm = 0.0;
      sym = 0.0;
      sxmxm = 0.0;
      sxmym = 0.0;
      symym = 0.0;

      for (i = 0; i < np; i++) {
        xe = xye[i][0];
        ye = xye[i][1];
        xm = xym[i][0];
        ym = xym[i][1];
        sxe = sxe + xe;
        sxexm = sxexm + xe * xm;
        sxeym = sxeym + xe * ym;
        sye = sye + ye;
        syeym = syeym + ye * ym;
        syexm = syexm + ye * xm;
        sxm = sxm + xm;
        sym = sym + ym;
        sxmxm = sxmxm + xm * xm;
        sxmym = sxmym + xm * ym;
        symym = symym + ym * ym;
      }

      /* Solve for A, B, C in  xe = A + B * xm + C * ym */
      v[0] = sxe;
      v[1] = sxexm;
      v[2] = sxeym;
      dm3[0][0] = p;
      dm3[0][1] = sxm;
      dm3[0][2] = sym;
      dm3[1][0] = sxm;
      dm3[1][1] = sxmxm;
      dm3[1][2] = sxmym;
      dm3[2][0] = sym;
      dm3[2][1] = sxmym;
      dm3[2][2] = symym;

      palDmat(3, *dm3, v, &det, &jstat, iw);

palsrc/palFitxy.c  view on Meta::CPAN

          xm = xym[i][0];
          ym = xym[i][1];
          sxe = sxe + xe;
          sxxyy = sxxyy + xe * xm + ye * ym;
          sxyyx = sxyyx + xe * ym - ye * xm;
          sye = sye + ye;
          sxm = sxm + xm;
          sym = sym + ym;
          sx2y2 = sx2y2 + xm * xm + ym * ym;
        }

        /* Solve for A, B, C, D in:  +/- xe = A + B * xm - C * ym
                                       + ye = D + C * xm + B * ym */
        v[0] = sxe;
        v[1] = sxxyy;
        v[2] = sxyyx;
        v[3] = sye;
        dm4[0][0] = p;
        dm4[0][1] = sxm;
        dm4[0][2] = -sym;
        dm4[0][3] = 0.0;
        dm4[1][0] = sxm;
        dm4[1][1] = sx2y2;
        dm4[1][2] = 0.0;
        dm4[1][3] = sym;
        dm4[2][0] = sym;
        dm4[2][1] = 0.0;
        dm4[2][2] = -sx2y2;
        dm4[2][3] = -sxm;
        dm4[3][0] = 0.0;
        dm4[3][1] = sym;
        dm4[3][2] = sxm;
        dm4[3][3] = p;

        palDmat(4, *dm4, v, &det, &jstat, iw);

        if (jstat == 0) {
          a = v[0];
          b = v[1];
          c = v[2];
          d = v[3];

          /* Determine sum of radial errors squared */
          sdr2 = 0.0;
          for (i = 0; i < np; i ++) {
            xm = xym[i][0];
            ym = xym[i][1];
            xr = a + b * xm - c * ym - xye[i][0] * sgn;
            yr = d + c * xm + b * ym - xye[i][1];
            sdr2 = sdr2 + xr * xr + yr * yr;
          }

        } else {
          /* Singular: set flag */
          sdr2 = -1.0;
        }

        /* If first pass and non-singular, save variables */
        if (nsol == 0 && jstat == 0) {
          aold = a;
          bold = b;
          cold = c;
          dold = d;
          sold = sdr2;
        }
      }

      /* Pick the best of the two solutions */
      if (sold >= 0.0 && (sold <= sdr2 || np == 2)) {
        coeffs[0] = aold;
        coeffs[1] = bold;
        coeffs[2] = -cold;
        coeffs[3] = dold;
        coeffs[4] = cold;
        coeffs[5] = bold;
      } else if (jstat == 0) {
        coeffs[0] = -a;
        coeffs[1] = -b;
        coeffs[2] = c;
        coeffs[3] = d;
        coeffs[4] = c;
        coeffs[5] = b;
      } else {
        /* No 4-coefficient fit possible */
        *j = -3;
      }
    } else {
      /* Insufficient data for 4-coefficient fit */
      *j = -2;
    }
  } else {
    /* Illegal itype - not 4 or 6 */
    *j = -1;
  }
}



( run in 0.832 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )