profit.c 147 KB
Newer Older
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4001

4002
  if (prof->code==MODEL_BACK)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4003
4004
4005
4006
4007
    {
    amp = fabs(*prof->flux);
    pixout = profit->modpix;
    for (i=npix; i--;)
      *(pixout++) += amp;
4008
4009
    prof->lostfluxfrac = 0.0;
    return 0.0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4010
4011
4012
4013
    }

  scaling = profit->pixstep / prof->typscale;

4014
  if (prof->code!=MODEL_DIRAC)
4015
4016
4017
4018
4019
4020
    {
/*-- Compute Profile CD matrix */
    ctheta = cos(*prof->posangle*DEG);
    stheta = sin(*prof->posangle*DEG);
    saspect = fabs(*prof->aspect);
    xscale = (*prof->scale==0.0)?
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4021
		0.0 : fabs(scaling / (*prof->scale*prof->typscale));
4022
    yscale = (*prof->scale*saspect == 0.0)?
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4023
		0.0 : fabs(scaling / (*prof->scale*prof->typscale*saspect));
4024
4025
4026
4027
    cd11 = (float)(xscale*ctheta);
    cd12 = (float)(xscale*stheta);
    cd21 = (float)(-yscale*stheta);
    cd22 = (float)(yscale*ctheta);
4028
4029
4030
4031
4032
    dx1 = 0.0;	/* Shifting operations have been moved to profit_resample() */
    dx2 = 0.0;	/* Shifting operations have been moved to profit_resample() */

    x1cout = (float)(profit->modnaxisn[0]/2);
    x2cout = (float)(profit->modnaxisn[1]/2);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4033
    nx2 = profit->modnaxisn[1]/2 + 1;
4034
4035
4036

/*-- Compute the largest r^2 that fits in the frame */
    num = cd11*cd22-cd12*cd21;
4037
    num *= num;
4038
4039
    x1max = x1cout - 1.0;
    x2max = x2cout - 1.0;
4040
4041
4042
4043
4044
4045
4046
    den = fabs(cd12*cd12+cd22*cd22);
    num2 = x1max*x1max*num;
    r2max1 = num2<PROFIT_MAXR2MAX*den? num2 / den : PROFIT_MAXR2MAX;
    den = fabs(cd11*cd11+cd21*cd21);
    num2 = x2max*x2max*num;
    r2max2 = num2<PROFIT_MAXR2MAX*den? num2 / den : PROFIT_MAXR2MAX;
    r2max = (r2max1 < r2max2? r2max1 : r2max2);
4047
    rmax = sqrtf(r2max);
4048
    }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4049
4050
4051

  switch(prof->code)
    {
4052
    case MODEL_DIRAC:
4053
      memset(prof->pix, 0, profit->nmodpix);
4054
4055
4056
4057
4058
      prof->pix[profit->modnaxisn[0]/2
		+ (profit->modnaxisn[1]/2)*profit->modnaxisn[0]] = 1.0;
      prof->lostfluxfrac = 0.0;
      threshflag = 0;
      break;
4059
4060
4061
    case MODEL_SERSIC:
    case MODEL_DEVAUCOULEURS:
    case MODEL_EXPONENTIAL:
4062
4063
4064
4065
4066
4067
/*---- Compute sharp/smooth transition radius */
      rs = PROFIT_SMOOTHR*(xscale>yscale?xscale:yscale);
      if (rs<=0)
        rs = 1.0;
      rs2 = rs*rs;
/*---- The consequence of sampling on flux is compensated by PSF normalisation*/
4068
      if (prof->code==MODEL_EXPONENTIAL)
4069
        bn = n = 1.0;
4070
      else if (prof->code==MODEL_DEVAUCOULEURS)
4071
4072
4073
4074
4075
4076
4077
4078
        {
        n = 4.0;
        bn = 7.66924944;
        }
      else
        {
        n = fabs(*prof->extra[0]);
        bn = 2.0*n - 1.0/3.0 + 4.0/(405.0*n) + 46.0/(25515.0*n*n)
4079
		+ 131.0/(1148175*n*n*n);	/* Ciotti & Bertin 1999 */
4080
4081
        }
      invn = 1.0/n;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4082
      hinvn = 0.5/n;
4083
4084
      k = -bn;
/*---- Compute central polynomial terms */
4085
      krspinvn = prof->code==MODEL_EXPONENTIAL? -rs : k*expf(logf(rs)*invn);
4086
4087
4088
4089
4090
4091
4092
      ekrspinvn = expf(krspinvn);
      p2 = krspinvn*invn*invn;
      p1 = krspinvn*p2;
      a0 = (1+(1.0/6.0)*(p1+(1.0-5.0*n)*p2))*ekrspinvn;
      a2 = (-1.0/2.0)*(p1+(1.0-3.0*n)*p2)/rs2*ekrspinvn;
      a3 = (1.0/3.0)*(p1+(1.0-2.0*n)*p2)/(rs2*rs)*ekrspinvn;
/*---- Compute the smooth part of the profile */
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4093
4094
      x10 = -x1cout - dx1;
      x2 = -x2cout - dx2;
4095
      pixin = prof->pix;
4096
      if (prof->code==MODEL_EXPONENTIAL)
4097
        for (ix2=nx2; ix2--; x2+=1.0)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4098
          {
4099
4100
          x1 = x10;
          for (ix1=profit->modnaxisn[0]; ix1--; x1+=1.0)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4101
            {
4102
4103
4104
4105
            x1in = cd12*x2 + cd11*x1;
            x2in = cd22*x2 + cd21*x1;
            ra = x1in*x1in+x2in*x2in;
            if (ra>r2max)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4106
              {
4107
4108
              *(pixin++) = 0.0;
              continue;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4109
              }
4110
4111
            val = ra<rs2? a0+ra*(a2+a3*sqrtf(ra)) : expf(-sqrtf(ra));
            *(pixin++) = val;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4112
4113
            }
          }
4114
4115
      else
        for (ix2=nx2; ix2--; x2+=1.0)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4116
          {
4117
4118
          x1 = x10;
          for (ix1=profit->modnaxisn[0]; ix1--; x1+=1.0)
4119
            {
4120
4121
4122
4123
            x1in = cd12*x2 + cd11*x1;
            x2in = cd22*x2 + cd21*x1;
            ra = x1in*x1in+x2in*x2in;
            if (ra>r2max)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4124
              {
4125
4126
              *(pixin++) = 0.0;
              continue;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4127
              }
4128
4129
            val = ra<rs2? a0+ra*(a2+a3*sqrtf(ra)) : expf(k*expf(logf(ra)*hinvn));
            *(pixin++) = val;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4130
4131
            }
          }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4132
4133
4134
/*---- Copy the symmetric part */
      if ((npix2=(profit->modnaxisn[1]-nx2)*profit->modnaxisn[0]) > 0)
        {
4135
4136
4137
4138
4139
4140
        pixin2 = pixin - profit->modnaxisn[0] - 1;
        if (!(profit->modnaxisn[0]&1))
          {
          *(pixin++) = 0.0;
          npix2--;
          }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4141
4142
4143
        for (i=npix2; i--;)
          *(pixin++) = *(pixin2--);
        }
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158

/*---- Compute the sharp part of the profile */
      ix1max = profit->modnaxisn[0];
      ix2max = profit->modnaxisn[1];
      dx1cout = x1cout + 0.4999999;
      dx2cout = x2cout + 0.4999999;
      invdet = 1.0/fabsf(cd11*cd22 - cd12*cd21);
      a11 = cd22*invdet;
      a12 = -cd12*invdet;
      a21 = -cd21*invdet;
      a22 = cd11*invdet;
      nang = 72 / 2;		/* 36 angles; only half of them are computed*/
      angstep = PI/nang;
      ang = 0.0;
      for (a=0; a<nang; a++)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4159
        {
4160
#ifdef HAVE_SINCOSF
4161
4162
4163
4164
4165
4166
4167
        sincosf(ang, &dsa, &dca);
#else
        dsa = sinf(ang);
        dca = cosf(ang);
#endif
        ddx1[a] = a11*dsa+a12*dca;
        ddx2[a] = a21*dsa+a22*dca;
4168
        ang += angstep;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4169
        }
4170
4171
4172
4173
4174
4175
4176
      r = DEXPF(-4.0);
      dr = DEXPF(0.05);
      selem = 0.5*angstep*(dr - 1.0/dr)/(xscale*yscale);
      krpinvn = k*DEXPF(-4.0*invn);
      dkrpinvn = DEXPF(0.05*invn);
      pixin = prof->pix;
      for (; r<rs; r *= dr)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4177
        {
4178
4179
4180
        r2 = r*r;
        val = (expf(krpinvn) - (a0 + r2*(a2+a3*r)))*r2*selem;
        for (a=0; a<nang; a++)
4181
          {
4182
4183
4184
4185
4186
4187
4188
4189
          ix1 = (int)(dx1cout + r*ddx1[a]);
          ix2 = (int)(dx2cout + r*ddx2[a]);
          if (ix1>=0 && ix1<ix1max && ix2>=0 && ix2<ix2max)
            pixin[ix2*ix1max+ix1] += val;
          ix1 = (int)(dx1cout - r*ddx1[a]);
          ix2 = (int)(dx2cout - r*ddx2[a]);
          if (ix1>=0 && ix1<ix1max && ix2>=0 && ix2<ix2max)
            pixin[ix2*ix1max+ix1] += val;
4190
          }
4191
        krpinvn *= dkrpinvn;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4192
        }
4193

4194
      prof->lostfluxfrac = prof->code==MODEL_EXPONENTIAL?
4195
4196
		(1.0 + rmax)*exp(-rmax)
		:1.0 - prof_gammainc(2.0*n, bn*pow(r2max, hinvn));
4197
      threshflag = 0;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4198
      break;
4199
    case MODEL_ARMS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
      r2min = *prof->featstart**prof->featstart;
      r2minxin = r2min * (1.0 - PROFIT_BARXFADE) * (1.0 - PROFIT_BARXFADE);
      r2minxout = r2min * (1.0 + PROFIT_BARXFADE) * (1.0 + PROFIT_BARXFADE);
      if ((invr2xdif = (r2minxout - r2minxin)) > 0.0)
        invr2xdif = 1.0 / invr2xdif;
      else
        invr2xdif = 1.0;
      umin = 0.5*logf(r2minxin + 0.00001);
      arm2amp = *prof->featfrac;
      armamp = 1.0 - arm2amp;
      armrdphidr = 1.0/tan(*prof->featpitch*DEG);
      armrdphidrvar = 0.0 /**prof->featpitchvar*/;
      posang = *prof->featposang*DEG;
      width = fabs(*prof->featwidth);
width = 3.0;
      x1 = -x1cout - dx1;
      x2 = -x2cout - dx2;
4217
      pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
      for (ix2=profit->modnaxisn[1]; ix2--; x2+=1.0)
        {
        x1t = cd12*x2 + cd11*x1;
        x2t = cd22*x2 + cd21*x1;
        for (ix1=profit->modnaxisn[0]; ix1--;)
          {
          r2 = x1t*x1t+x2t*x2t;
          if (r2>r2minxin)
            {
            u = 0.5*logf(r2 + 0.00001);
            theta = (armrdphidr+armrdphidrvar*(u-umin))*u+posang;
            ca = cosf(theta);
            sa = sinf(theta);
            x1in = (x1t*ca - x2t*sa);
            x2in = (x1t*sa + x2t*ca);
            amp = expf(-sqrtf(x1t*x1t+x2t*x2t));
            if (r2<r2minxout)
              amp *= (r2 - r2minxin)*invr2xdif;
            ra = x1in*x1in/r2;
            rb = x2in*x2in/r2;
            *(pixin++) = amp * (armamp*PROFIT_POWF(ra,width)
				+ arm2amp*PROFIT_POWF(rb,width));
            }
          else
            *(pixin++) = 0.0;
          x1t += cd11;
          x2t += cd21; 
         }
        }
4247
4248
      prof->lostfluxfrac = 0.0;
      threshflag = 1;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4249
      break;
4250
    case MODEL_BAR:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
      r2min = *prof->featstart**prof->featstart;
      r2minxin = r2min * (1.0 - PROFIT_BARXFADE) * (1.0 - PROFIT_BARXFADE);
      r2minxout = r2min * (1.0 + PROFIT_BARXFADE) * (1.0 + PROFIT_BARXFADE);
      if ((invr2xdif = (r2minxout - r2minxin)) > 0.0)
        invr2xdif = 1.0 / invr2xdif;
      else
        invr2xdif = 1.0;
      invwidth2 = fabs(1.0 / (*prof->featstart**prof->feataspect));
      posang = *prof->featposang*DEG;
      ca = cosf(posang);
      sa = sinf(posang);
      x1 = -x1cout - dx1;
      x2 = -x2cout - dx2;
4264
      pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
      for (ix2=profit->modnaxisn[1]; ix2--; x2+=1.0)
        {
        x1t = cd12*x2 + cd11*x1;
        x2t = cd22*x2 + cd21*x1;
        for (ix1=profit->modnaxisn[0]; ix1--;)
          {
          r2 = x1t*x1t+x2t*x2t;
          if (r2<r2minxout)
            {
            x1in = x1t*ca - x2t*sa;
            x2in = invwidth2*(x1t*sa + x2t*ca);
            *(pixin++) = (r2>r2minxin) ?
				(r2minxout - r2)*invr2xdif*expf(-x2in*x2in)
				: expf(-x2in*x2in);
            }
          else
            *(pixin++) = 0.0;
          x1t += cd11;
          x2t += cd21;
          }
        }
4286
4287
      prof->lostfluxfrac = 0.0;
      threshflag = 1;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4288
      break;
4289
    case MODEL_INRING:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
      rmin = *prof->featstart;
      r2minxin = *prof->featstart-4.0**prof->featwidth;
      if (r2minxin < 0.0)
        r2minxin = 0.0;
      r2minxin *= r2minxin;
      r2minxout = *prof->featstart+4.0**prof->featwidth;
      r2minxout *= r2minxout;
      invwidth2 = 0.5 / (*prof->featwidth**prof->featwidth);
      cd22 /= *prof->feataspect;
      cd21 /= *prof->feataspect;
      x1 = -x1cout - dx1;
      x2 = -x2cout - dx2;
4302
      pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
      for (ix2=profit->modnaxisn[1]; ix2--; x2+=1.0)
        {
        x1t = cd12*x2 + cd11*x1;
        x2t = cd22*x2 + cd21*x1;
        for (ix1=profit->modnaxisn[0]; ix1--;)
          {
          r2 = x1t*x1t+x2t*x2t;
          if (r2>r2minxin && r2<r2minxout)
            {
            r = sqrt(r2) - rmin;
            *(pixin++) = expf(-invwidth2*r*r);
            }
          else
            *(pixin++) = 0.0;
          x1t += cd11;
          x2t += cd21;
          }
        }
4321
4322
      prof->lostfluxfrac = 0.0;
      threshflag = 1;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4323
      break;
4324
    case MODEL_OUTRING:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
      rmin = *prof->featstart;
      r2minxin = *prof->featstart-4.0**prof->featwidth;
      if (r2minxin < 0.0)
        r2minxin = 0.0;
      r2minxin *= r2minxin;
      r2minxout = *prof->featstart+4.0**prof->featwidth;
      r2minxout *= r2minxout;
      invwidth2 = 0.5 / (*prof->featwidth**prof->featwidth);
      x1 = -x1cout - dx1;
      x2 = -x2cout - dx2;
4335
      pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
      for (ix2=profit->modnaxisn[1]; ix2--; x2+=1.0)
        {
        x1t = cd12*x2 + cd11*x1;
        x2t = cd22*x2 + cd21*x1;
        for (ix1=profit->modnaxisn[0]; ix1--;)
          {
          r2 = x1t*x1t+x2t*x2t;
          if (r2>r2minxin && r2<r2minxout)
            {
            r = sqrt(r2) - rmin;
            *(pixin++) = expf(-invwidth2*r*r);
            }
          else
            *(pixin++) = 0.0;
          x1t += cd11;
          x2t += cd21;
          }
        }
4354
4355
      prof->lostfluxfrac = 0.0;
      threshflag = 1;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
      break;
    default:
/*---- Tabulated profile: remap each pixel */
/*---- Initialize multi-dimensional counters */
     for (d=0; d<2; d++)
        {
        posout[d] = 1.0;	/* FITS convention */
        dnaxisn[d] = profit->modnaxisn[d] + 0.99999;
        }

      for (e=0; e<prof->naxis - 2; e++)
        {
        d = 2+e;
/*------ Compute position along axis */
        posin[d] = (*prof->extra[e]-prof->extrazero[e])/prof->extrascale[e]+1.0;
/*------ Keep position within boundaries and let interpolation do the rest */
        if (posin[d] < 0.99999)
          {
          if (prof->extracycleflag[e])
4375
            posin[d] += (float)prof->naxisn[d];
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4376
4377
4378
          else
            posin[d] = 1.0;
          }
4379
        else if (posin[d] > (float)prof->naxisn[d])
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4380
4381
4382
          {
          if (prof->extracycleflag[e])
          posin[d] = (prof->extracycleflag[e])?
4383
4384
		  fmod(posin[d], (float)prof->naxisn[d])
		: (float)prof->naxisn[d];
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4385
4386
          }
        }
4387
4388
      x1cin = (float)(prof->naxisn[0]/2);
      x2cin = (float)(prof->naxisn[1]/2);
4389
      pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
      for (i=npix; i--;)
        {
        x1 = posout[0] - x1cout - 1.0 - dx1;
        x2 = posout[1] - x2cout - 1.0 - dx2;
        posin[0] = cd11*x1 + cd12*x2 + x1cin + 1.0;
        posin[1] = cd21*x1 + cd22*x2 + x2cin + 1.0;
        *(pixin++) = prof_interpolate(prof, posin);
        for (d=0; d<2; d++)
          if ((posout[d]+=1.0) < dnaxisn[d])
            break;
          else
            posout[d] = 1.0;
        }
4403
4404
      prof->lostfluxfrac = 0.0;
      threshflag = 1;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4405
4406
4407
    break;
    }

4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
/* For complex profiles, threshold to the brightest pixel value at border */
  if (threshflag)
    {
/*-- Now find truncation threshold */
/*-- Find the shortest distance to a vignet border */
    rmax = x1cout;
    if (rmax > (r = x2cout))
      rmax = r;
    rmax += 0.01;
    if (rmax<1.0)
      rmax = 1.0;
    r2max = rmax*rmax;
    rmin = rmax - 1.0;
    r2min = rmin*rmin;

/*-- Find best threshold (the max around the circle with radius rmax */
    dx2 = -x2cout;
4425
    pixin = prof->pix;
4426
4427
4428
4429
4430
4431
4432
4433
    thresh = -BIG;
    for (ix2=profit->modnaxisn[1]; ix2--; dx2 += 1.0)
      {
      dx1 = -x1cout;
      for (ix1=profit->modnaxisn[0]; ix1--; dx1 += 1.0)
        if ((val=*(pixin++))>thresh && (r2=dx1*dx1+dx2*dx2)>r2min && r2<r2max)
          thresh = val;
      }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4434

4435
4436
/*-- Threshold and measure the flux */
    flux = 0.0;
4437
    pixin = prof->pix;
4438
4439
4440
4441
4442
4443
4444
    for (i=npix; i--; pixin++)
      if (*pixin >= thresh)
        flux += (double)*pixin;
      else
        *pixin = 0.0;
    }
  else
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4445
    {
4446
    flux = 0.0;
4447
    pixin = prof->pix;
4448
4449
    for (i=npix; i--;)
      flux += (double)*(pixin++);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4450
4451
    }

4452
4453
4454
4455
4456
4457
4458
  if (extfluxfac_flag)
    fluxfac = prof->fluxfac;
  else
    {
    if (prof->lostfluxfrac < 1.0)
      flux /= (1.0 - prof->lostfluxfrac);

4459
    prof->fluxfac = fluxfac = fabs(flux)>0.0? profit->fluxfac/fabs(flux) : 0.0;
4460
4461
4462
4463
4464
    }

  pixin = prof->pix;
  for (i=npix; i--;)
    *(pixin++) *= fluxfac;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4465
4466

/* Correct final flux */
4467
4468
  fluxfac = *prof->flux;
  pixin = prof->pix;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4469
  pixout = profit->modpix;
4470
  for (i=npix; i--;)
4471
    *(pixout++) += fluxfac**(pixin++);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4472

4473
  return *prof->flux;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4474
4475
4476
  }


4477
/****** prof_moments **********************************************************
4478
4479
PROTO	int	prof_moments(profitstruct *profit, profstruct *prof)
PURPOSE	Computes (analytically or numerically) the 2nd moments of a profile.
4480
INPUT	Profile-fitting structure,
4481
4482
4483
4484
	profile structure,
	optional pointer to 3xnparam Jacobian matrix.
OUTPUT	Index to the profile flux for further processing.
NOTES	.
4485
AUTHOR	E. Bertin (IAP)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4486
VERSION	20/08/2010
4487
 ***/
4488
int	prof_moments(profitstruct *profit, profstruct *prof, double *jac)
4489
  {
4490
4491
4492
4493
   double	*dmx2,*dmy2,*dmxy,
		m20, a2, ct,st, mx2fac, my2fac,mxyfac, dc2,ds2,dcs,
		bn,bn2, n,n2, nfac,nfac2, hscale2, dmdn;
   int		nparam, index;
4494

4495
4496
4497
4498
4499
4500
4501
4502
4503
  if (jac)
/*-- Clear output Jacobian */
    {
    nparam = profit->nparam;
    memset(jac, 0, nparam*3*sizeof(double));
    dmx2 = jac;
    dmy2 = jac + nparam;
    dmxy = jac + 2*nparam;
    }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4504
4505
4506
4507
4508
4509
4510
  else
    dmx2 = dmy2 = dmxy = NULL;		/* To avoid gcc -Wall warnings */

  m20 = 0.0;				/* to avoid gcc -Wall warnings */
  index = 0;				/* to avoid gcc -Wall warnings */


4511
4512
  if (prof->posangle)
    {
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
    a2 = *prof->aspect**prof->aspect;
    ct = cos(*prof->posangle*DEG);
    st = sin(*prof->posangle*DEG);
    mx2fac = ct*ct + st*st*a2;
    my2fac = st*st + ct*ct*a2;
    mxyfac = ct*st * (1.0 - a2);
    if (jac)
      {
      dc2 = -2.0*ct*st*DEG;
      ds2 =  2.0*ct*st*DEG;
      dcs = (ct*ct - st*st)*DEG;
      }
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4525
4526
    else
      dc2 = ds2 = dcs = 0.0;		/* To avoid gcc -Wall warnings */
4527
4528
    switch(prof->code)
      {
4529
      case MODEL_SERSIC:
4530
4531
4532
        n = fabs(*prof->extra[0]);
        bn = 2.0*n - 1.0/3.0 + 4.0/(405.0*n) + 46.0/(25515.0*n*n)
		+ 131.0/(1148175*n*n*n);	/* Ciotti & Bertin 1999 */
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
        nfac  = prof_gamma(4.0*n) / (prof_gamma(2.0*n)*pow(bn, 2.0*n));
        hscale2 = 0.5 * *prof->scale**prof->scale;
        m20 = hscale2 * nfac;
        if (jac)
          {
          dmx2[profit->paramindex[PARAM_SPHEROID_REFF]]
			= *prof->scale * nfac * mx2fac;
          dmy2[profit->paramindex[PARAM_SPHEROID_REFF]]
			= *prof->scale * nfac * my2fac;
          dmxy[profit->paramindex[PARAM_SPHEROID_REFF]]
			= *prof->scale * nfac * mxyfac;
          n2 = n+0.01;
          bn2 = 2.0*n2 - 1.0/3.0 + 4.0/(405.0*n2) + 46.0/(25515.0*n2*n2)
		+ 131.0/(1148175*n2*n2*n2);	/* Ciotti & Bertin 1999 */
          nfac2 = prof_gamma(4.0*n2) / (prof_gamma(2.0*n2)*pow(bn2, 2.0*n2));
          dmdn = 100.0 * hscale2 * (nfac2-nfac);
          dmx2[profit->paramindex[PARAM_SPHEROID_SERSICN]] = dmdn * mx2fac;
          dmy2[profit->paramindex[PARAM_SPHEROID_SERSICN]] = dmdn * my2fac;
          dmxy[profit->paramindex[PARAM_SPHEROID_SERSICN]] = dmdn * mxyfac;
          dmx2[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= 2.0 * m20 * st*st * *prof->aspect;
          dmy2[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= 2.0 * m20 * ct*ct * *prof->aspect;
          dmxy[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= -2.0 * m20 * ct*st * *prof->aspect;
          dmx2[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (dc2+ds2*a2);
          dmy2[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (ds2+dc2*a2);
          dmxy[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (1.0-a2)*dcs;
          }
        index = profit->paramindex[PARAM_SPHEROID_FLUX];
4563
        break; 
4564
      case MODEL_DEVAUCOULEURS:
4565
        m20 = 10.83995 * *prof->scale**prof->scale;
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
        if (jac)
          {
          dmx2[profit->paramindex[PARAM_SPHEROID_REFF]]
			= 21.680 * *prof->scale * mx2fac;
          dmy2[profit->paramindex[PARAM_SPHEROID_REFF]]
			= 21.680 * *prof->scale * my2fac;
          dmxy[profit->paramindex[PARAM_SPHEROID_REFF]]
			= 21.680 * *prof->scale * mxyfac;
          dmx2[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= 2.0 * m20 * st*st * *prof->aspect;
          dmy2[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= 2.0 * m20 * ct*ct * *prof->aspect;
          dmxy[profit->paramindex[PARAM_SPHEROID_ASPECT]]
			= -2.0 * m20 * ct*st * *prof->aspect;
          dmx2[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (dc2+ds2*a2);
          dmy2[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (ds2+dc2*a2);
          dmxy[profit->paramindex[PARAM_SPHEROID_POSANG]] = m20 * (1.0-a2)*dcs;
          }
        index = profit->paramindex[PARAM_SPHEROID_FLUX];
4585
        break;
4586
      case MODEL_EXPONENTIAL:
4587
        m20 = 3.0 * *prof->scale**prof->scale;
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
        if (jac)
          {
          dmx2[profit->paramindex[PARAM_DISK_SCALE]]
			= 6.0 * *prof->scale * mx2fac;
          dmy2[profit->paramindex[PARAM_DISK_SCALE]]
			= 6.0 * *prof->scale * my2fac;
          dmxy[profit->paramindex[PARAM_DISK_SCALE]]
			= 6.0 * *prof->scale * mxyfac;
          dmx2[profit->paramindex[PARAM_DISK_ASPECT]]
			= 2.0 * m20 * st*st * *prof->aspect;
          dmy2[profit->paramindex[PARAM_DISK_ASPECT]]
			= 2.0 * m20 * ct*ct * *prof->aspect;
          dmxy[profit->paramindex[PARAM_DISK_ASPECT]]
			= -2.0 * m20 * ct*st * *prof->aspect;
          dmx2[profit->paramindex[PARAM_DISK_POSANG]] = m20 * (dc2 + ds2*a2);
          dmy2[profit->paramindex[PARAM_DISK_POSANG]] = m20 * (ds2 + dc2*a2);
          dmxy[profit->paramindex[PARAM_DISK_POSANG]] = m20 * (1.0 - a2) * dcs;
          }
        index = profit->paramindex[PARAM_DISK_FLUX];
4607
        break;
4608
      case MODEL_ARMS:
4609
4610
4611
        m20 = 1.0;
        index = profit->paramindex[PARAM_ARMS_FLUX];
        break;
4612
      case MODEL_BAR:
4613
4614
4615
        m20 = 1.0;
        index = profit->paramindex[PARAM_BAR_FLUX];
        break;
4616
      case MODEL_INRING:
4617
4618
4619
        m20 = 1.0;
        index = profit->paramindex[PARAM_INRING_FLUX];
        break;
4620
      case MODEL_OUTRING:
4621
4622
        m20 = 1.0;
        index = profit->paramindex[PARAM_OUTRING_FLUX];
4623
4624
4625
4626
4627
4628
4629
        break;
      default:
        error(EXIT_FAILURE, "*Internal Error*: Unknown oriented model in ",
		"prof_moments()");
      break;
      }

4630
4631
4632
4633
    prof->mx2 = m20*mx2fac;
    prof->my2 = m20*my2fac;
    prof->mxy = m20*mxyfac;
    
4634
4635
4636
4637
    }
  else
    prof->mx2 = prof->my2 = prof->mxy = 0.0;

4638
  return index;
4639
4640
4641
  }


Emmanuel Bertin's avatar
Emmanuel Bertin committed
4642
/****** prof_interpolate ******************************************************
4643
PROTO	float	prof_interpolate(profstruct *prof, float *posin)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4644
4645
4646
4647
4648
4649
4650
4651
PURPOSE	Interpolate a multidimensional model profile at a given position.
INPUT	Profile structure,
	input position vector.
OUTPUT	-.
NOTES	-.
AUTHOR	E. Bertin (IAP)
VERSION	10/12/2006
 ***/
4652
static float	prof_interpolate(profstruct *prof, float *posin)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4653
  {
4654
   float		dpos[2+PROFIT_MAXEXTRA],
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
			kernel_vector[INTERP_MAXKERNELWIDTH],
			*kvector, *pixin,*pixout,
			val;
   long			step[2+PROFIT_MAXEXTRA],
			start, fac;
   int			linecount[2+PROFIT_MAXEXTRA],
			*naxisn,
			i,j,n, ival, nlines, kwidth,width, badpixflag, naxis;

  naxis = prof->naxis;
  naxisn = prof->naxisn;
  start = 0;
  fac = 1;
  for (n=0; n<naxis; n++)
    {
    val = *(posin++);
    width = *(naxisn++);
/*-- Get the integer part of the current coordinate or nearest neighbour */
    ival = (prof->interptype[n]==INTERP_NEARESTNEIGHBOUR)?
                                        (int)(val-0.50001):(int)val;
/*-- Store the fractional part of the current coordinate */
    dpos[n] = val - ival;
/*-- Check if interpolation start/end exceed image boundary... */
    kwidth = prof->kernelwidth[n];
    ival-=kwidth/2;
    if (ival<0 || ival+kwidth<=0 || ival+kwidth>width)
      return 0.0;

/*-- Update starting pointer */
    start += ival*fac;
/*-- Update step between interpolated regions */
    step[n] = fac*(width-kwidth);
    linecount[n] = 0.0;
    fac *= width;
    }

/* Update Interpolation kernel vectors */
  make_kernel(*dpos, kernel_vector, prof->interptype[0]);
  kwidth = prof->kernelwidth[0];
  nlines = prof->kernelnlines;
/* First step: interpolate along NAXIS1 from the data themselves */
  badpixflag = 0;
  pixin = prof->pix+start;
  pixout = prof->kernelbuf;
  for (j=nlines; j--;)
    {
    val = 0.0;
    kvector = kernel_vector;
    for (i=kwidth; i--;)
       val += *(kvector++)**(pixin++);
    *(pixout++) = val;
    for (n=1; n<naxis; n++)
      {
      pixin+=step[n-1];
      if (++linecount[n]<prof->kernelwidth[n])
        break;
      else
        linecount[n] = 0;       /* No need to initialize it to 0! */
      }
    }

/* Second step: interpolate along other axes from the interpolation buffer */
  for (n=1; n<naxis; n++)
    {
    make_kernel(dpos[n], kernel_vector, prof->interptype[n]);
    kwidth = prof->kernelwidth[n];
    pixout = pixin = prof->kernelbuf;
    for (j = (nlines/=kwidth); j--;)
      {
      val = 0.0;
      kvector = kernel_vector;
      for (i=kwidth; i--;)
        val += *(kvector++)**(pixin++);
      *(pixout++) = val;
     }
    }

  return prof->kernelbuf[0];
  }


/****** interpolate_pix ******************************************************
4737
PROTO	void interpolate_pix(float *posin, float *pix, int naxisn,
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
		interpenum interptype)
PURPOSE	Interpolate a model profile at a given position.
INPUT	Profile structure,
	input position vector,
	input pixmap dimension vector,
	interpolation type.
OUTPUT	-.
NOTES	-.
AUTHOR	E. Bertin (IAP)
VERSION	07/12/2006
 ***/
4749
static float	interpolate_pix(float *posin, float *pix, int *naxisn,
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4750
4751
			interpenum interptype)
  {
4752
   float	buffer[INTERP_MAXKERNELWIDTH],
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
		kernel[INTERP_MAXKERNELWIDTH], dpos[2],
		*kvector, *pixin, *pixout,
		val;
   int		fac, ival, kwidth, start, width, step,
		i,j, n;

  kwidth = interp_kernwidth[interptype];
  start = 0;
  fac = 1;
  for (n=0; n<2; n++)
    {
    val = *(posin++);
    width = naxisn[n];
/*-- Get the integer part of the current coordinate or nearest neighbour */
    ival = (interptype==INTERP_NEARESTNEIGHBOUR)? (int)(val-0.50001):(int)val;
/*-- Store the fractional part of the current coordinate */
    dpos[n] = val - ival;
/*-- Check if interpolation start/end exceed image boundary... */
    ival-=kwidth/2;
    if (ival<0 || ival+kwidth<=0 || ival+kwidth>width)
      return 0.0;
/*-- Update starting pointer */
    start += ival*fac;
/*-- Update step between interpolated regions */
    fac *= width;
    }

/* First step: interpolate along NAXIS1 from the data themselves */
  make_kernel(dpos[0], kernel, interptype);
  step = naxisn[0]-kwidth;
  pixin = pix+start;
  pixout = buffer;
  for (j=kwidth; j--;)
    {
    val = 0.0;
    kvector = kernel;
    for (i=kwidth; i--;)
      val += *(kvector++)**(pixin++);
    *(pixout++) = val;
    pixin += step;
    }

/* Second step: interpolate along NAXIS2 from the interpolation buffer */
  make_kernel(dpos[1], kernel, interptype);
  pixin = buffer;
  val = 0.0;
  kvector = kernel;
  for (i=kwidth; i--;)
    val += *(kvector++)**(pixin++);

  return val;
  }


/****** make_kernel **********************************************************
4808
PROTO	void make_kernel(float pos, float *kernel, interpenum interptype)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4809
4810
4811
4812
4813
4814
4815
PURPOSE	Conpute interpolation-kernel data
INPUT	Position,
	Pointer to the output kernel data,
	Interpolation method.
OUTPUT	-.
NOTES	-.
AUTHOR	E. Bertin (IAP)
4816
VERSION	25/07/2011
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4817
 ***/
4818
void	make_kernel(float pos, float *kernel, interpenum interptype)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4819
  {
4820
   float	x, val, sinx1,sinx2,sinx3,cosx1;
4821

Emmanuel Bertin's avatar
Emmanuel Bertin committed
4822
4823
4824
4825
  if (interptype == INTERP_NEARESTNEIGHBOUR)
    *kernel = 1;
  else if (interptype == INTERP_BILINEAR)
    {
4826
    *(kernel++) = 1.0f-pos;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4827
4828
4829
4830
    *kernel = pos;
    }
  else if (interptype == INTERP_LANCZOS2)
    {
4831
    if (pos<1e-5f && pos>-1e-5f)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4832
      {
4833
4834
4835
4836
      *(kernel++) = 0.0f;
      *(kernel++) = 1.0f;
      *(kernel++) = 0.0f;
      *kernel = 0.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4837
4838
4839
      }
    else
      {
4840
      x = -PI/2.0f*(pos+1.0f);
4841
#ifdef HAVE_SINCOSF
4842
      sincosf(x, &sinx1, &cosx1);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4843
#else
4844
4845
      sinx1 = sinf(x);
      cosx1 = cosf(x);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4846
4847
#endif
      val = (*(kernel++) = sinx1/(x*x));
4848
      x += PI/2.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4849
      val += (*(kernel++) = -cosx1/(x*x));
4850
      x += PI/2.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4851
      val += (*(kernel++) = -sinx1/(x*x));
4852
      x += PI/2.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4853
      val += (*kernel = cosx1/(x*x));
4854
      val = 1.0f/val;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4855
4856
4857
4858
4859
4860
4861
4862
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *kernel *= val;
      }
    }
  else if (interptype == INTERP_LANCZOS3)
    {
4863
    if (pos<1e-5f && pos>-1e-5f)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4864
      {
4865
4866
4867
4868
4869
4870
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 1.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *kernel = 0.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4871
4872
4873
      }
    else
      {
4874
      x = -PI/3.0f*(pos+2.0f);
4875
#ifdef HAVE_SINCOSF
4876
      sincosf(x, &sinx1, &cosx1);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4877
#else
4878
4879
      sinx1 = sinf(x);
      cosx1 = cosf(x);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4880
4881
#endif
      val = (*(kernel++) = sinx1/(x*x));
4882
4883
      x += PI/3.0f;
      val += (*(kernel++) = (sinx2=-0.5f*sinx1-0.866025403785f*cosx1)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4884
				/ (x*x));
4885
4886
      x += PI/3.0f;
      val += (*(kernel++) = (sinx3=-0.5f*sinx1+0.866025403785f*cosx1)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4887
				/(x*x));
4888
      x += PI/3.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4889
      val += (*(kernel++) = sinx1/(x*x));
4890
      x += PI/3.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4891
      val += (*(kernel++) = sinx2/(x*x));
4892
      x += PI/3.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4893
      val += (*kernel = sinx3/(x*x));
4894
      val = 1.0f/val;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *kernel *= val;
      }
    }
  else if (interptype == INTERP_LANCZOS4)
    {
4905
    if (pos<1e-5f && pos>-1e-5f)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4906
      {
4907
4908
4909
4910
4911
4912
4913
4914
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 1.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *(kernel++) = 0.0f;
      *kernel = 0.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4915
4916
4917
      }
    else
      {
4918
      x = -PI/4.0f*(pos+3.0f);
4919
#ifdef HAVE_SINCOSF
4920
      sincosf(x, &sinx1, &cosx1);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4921
#else
4922
4923
      sinx1 = sinf(x);
      cosx1 = cosf(x);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4924
4925
#endif
      val = (*(kernel++) = sinx1/(x*x));
4926
4927
      x += PI/4.0f;
      val +=(*(kernel++) = -(sinx2=0.707106781186f*(sinx1+cosx1))
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4928
				/(x*x));
4929
      x += PI/4.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4930
      val += (*(kernel++) = cosx1/(x*x));
4931
4932
4933
      x += PI/4.0f;
      val += (*(kernel++) = -(sinx3=0.707106781186f*(cosx1-sinx1))/(x*x));
      x += PI/4.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4934
      val += (*(kernel++) = -sinx1/(x*x));
4935
      x += PI/4.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4936
      val += (*(kernel++) = sinx2/(x*x));
4937
      x += PI/4.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4938
      val += (*(kernel++) = -cosx1/(x*x));
4939
      x += PI/4.0f;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4940
      val += (*kernel = sinx3/(x*x));
4941
      val = 1.0f/val;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *(kernel--) *= val;
      *kernel *= val;
      }
    }
  else
    error(EXIT_FAILURE, "*Internal Error*: Unknown interpolation type in ",
		"make_kernel()");

  return;
  }
For faster browsing, not all history is shown. View entire blame