// @(#)root/hist:$Name: $:$Id: TSpectrum2.cxx,v 1.6 2003/05/08 15:00:38 brun Exp $
// Author: Miroslav Morhac 11/04/2003
/////////////////////////////////////////////////////////////////////////////
// THIS CLASS CONTAINS ADVANCED SPECTRA PROCESSING FUNCTIONS. //
// //
// ONE-DIMENSIONAL BACKGROUND ESTIMATION FUNCTIONS //
// TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTIONS //
// ONE-DIMENSIONAL SMOOTHING FUNCTIONS //
// TWO-DIMENSIONAL SMOOTHING FUNCTIONS //
// ONE-DIMENSIONAL DECONVOLUTION FUNCTIONS //
// TWO-DIMENSIONAL DECONVOLUTION FUNCTIONS //
// ONE-DIMENSIONAL PEAK SEARCH FUNCTIONS //
// TWO-DIMENSIONAL PEAK SEARCH FUNCTIONS //
// ONE-DIMENSIONAL PEAKS FITTING FUNCTIONS //
// TWO-DIMENSIONAL PEAKS FITTING FUNCTIONS //
// ONE-DIMENSIONAL ORTHOGONAL TRANSFORMS FUNCTIONS //
// TWO-DIMENSIONAL ORTHOGONAL TRANSFORMS FUNCTIONS //
// //
// These functions were written by: //
// Miroslav Morhac //
// Institute of Physics //
// Slovak Academy of Sciences //
// Dubravska cesta 9, 842 28 BRATISLAVA //
// SLOVAKIA //
// //
// email:fyzimiro@savba.sk, fax:+421 7 54772479 //
// //
// The original code in C has been repackaged as a C++ class by R.Brun // //
// //
// The algorithms in this class have been published in the following //
// references: //
// [1] M.Morhac et al.: Background elimination methods for //
// multidimensional coincidence gamma-ray spectra. Nuclear //
// Instruments and Methods in Physics Research A 401 (1997) 113- //
// 132. //
// //
// [2] M.Morhac et al.: Efficient one- and two-dimensional Gold //
// deconvolution and its application to gamma-ray spectra //
// decomposition. Nuclear Instruments and Methods in Physics //
// Research A 401 (1997) 385-408. //
// //
// [3] M.Morhac et al.: Identification of peaks in multidimensional //
// coincidence gamma-ray spectra. Submitted for publication in //
// Nuclear Instruments and Methods in Physics Research A. //
// //
// These NIM papers are also available as Postscript files from: //
//
/*
ftp://root.cern.ch/root/SpectrumDec.ps.gz
ftp://root.cern.ch/root/SpectrumSrc.ps.gz
ftp://root.cern.ch/root/SpectrumBck.ps.gz
*/
//
/////////////////////////////////////////////////////////////////////////////
#include "TSpectrum2.h"
#include "TPolyMarker.h"
#include "TMath.h"
#define PEAK_WINDOW 1024
ClassImp(TSpectrum2)
//______________________________________________________________________________
TSpectrum2::TSpectrum2() :TNamed("Spectrum", "Miroslav Morhac peak finder")
{
Int_t n = 100;
fMaxPeaks = n;
fPosition = new Float_t[n];
fPositionX = new Float_t[n];
fPositionY = new Float_t[n];
fResolution = 1;
fHistogram = 0;
fNPeaks = 0;
}
//______________________________________________________________________________
TSpectrum2::TSpectrum2(Int_t maxpositions, Float_t resolution) :TNamed("Spectrum", "Miroslav Morhac peak finder")
{
// maxpositions: maximum number of peaks
// resolution: determines resolution of the neighboring peaks
// default value is 1 correspond to 3 sigma distance
// between peaks. Higher values allow higher resolution
// (smaller distance between peaks.
// May be set later through SetResolution.
Int_t n = TMath::Max(maxpositions, 100);
fMaxPeaks = n;
fPosition = new Float_t[n];
fPositionX = new Float_t[n];
fPositionY = new Float_t[n];
fHistogram = 0;
fNPeaks = 0;
SetResolution(resolution);
}
//______________________________________________________________________________
TSpectrum2::~TSpectrum2()
{
delete[]fPosition;
delete[]fPositionX;
delete[]fPositionY;
delete fHistogram;
}
//______________________________________________________________________________
const char *TSpectrum2::Background(TH1 * h, int number_of_iterations,
Option_t * option)
{
/////////////////////////////////////////////////////////////////////////////
// ONE-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION //
// This function calculates background spectrum from source in h. //
// The result is placed in the vector pointed by spectrum pointer. //
// //
// Function parameters: //
// spectrum: pointer to the vector of source spectrum //
// size: length of spectrum and working space vectors //
// number_of_iterations, for details we refer to manual //
// //
/////////////////////////////////////////////////////////////////////////////
printf
("Background function not yet implemented: h=%s, iter=%d, option=%sn"
, h->GetName(), number_of_iterations, option);
return 0;
}
//______________________________________________________________________________
Int_t TSpectrum2::Search(TH1 * hin, Double_t sigma,
Option_t * option)
{
/////////////////////////////////////////////////////////////////////////////
// ONE-DIMENSIONAL PEAK SEARCH FUNCTION //
// This function searches for peaks in source spectrum in hin //
// The number of found peaks and their positions are written into //
// the members fNpeaks and fPositionX. //
// //
// Function parameters: //
// hin: pointer to the histogram of source spectrum //
// sigma: sigma of searched peaks, for details we refer to manual //
// Note that sigma is in number of bins //
// //
// if option is not equal to "goff" (goff is the default), then //
// a polymarker object is created and added to the list of functions of //
// the histogram. The histogram is drawn with the specified option and //
// the polymarker object drawn on top of the histogram. //
// The polymarker coordinates correspond to the npeaks peaks found in //
// the histogram. //
// A pointer to the polymarker object can be retrieved later via: //
// TList *functions = hin->GetListOfFunctions(); //
// TPolyMarker *pm = (TPolyMarker*)functions->FindObject("TPolyMarker") //
// //
/////////////////////////////////////////////////////////////////////////////
if (hin == 0)
return 0;
Int_t dimension = hin->GetDimension();
if (dimension > 2) {
Error("Search", "Only implemented for 1-d and 2-d histograms");
return 0;
}
if (dimension == 2) {
Int_t sizex = hin->GetXaxis()->GetNbins();
Int_t sizey = hin->GetYaxis()->GetNbins();
Int_t i, j, binx,biny, npeaks;
Float_t ** source = new float *[sizex];
for (i = 0; i < sizex; i++) {
source[i] = new float[sizey];
for (j = 0; j < sizey; j++) {
source[i][j] = (Float_t) hin->GetBinContent(i + 1, j + 1);
}
}
Double_t threshold = 4;
npeaks = Search2General(source, sizex, sizey, sigma, threshold, kTRUE, 10);
//The logic in the loop should be improved to use the fact
//that fPositionX,Y give a precise position inside a bin.
//The current algorithm takes the center of the bin only.
for (i = 0; i < npeaks; i++) {
binx = 1 + Int_t(fPositionX[i] + 0.5);
biny = 1 + Int_t(fPositionY[i] + 0.5);
fPositionX[i] = hin->GetXaxis()->GetBinCenter(binx);
fPositionY[i] = hin->GetYaxis()->GetBinCenter(biny);
}
if (strstr(option, "goff"))
return npeaks;
TPolyMarker * pm = new TPolyMarker(npeaks, fPositionX, fPositionY);
hin->GetListOfFunctions()->Add(pm);
pm->SetMarkerStyle(23);
pm->SetMarkerColor(kRed);
pm->SetMarkerSize(1.3);
hin->Draw(option);
return npeaks;
}
return 0;
}
//______________________________________________________________________________
void TSpectrum2::SetResolution(Float_t resolution)
{
// resolution: determines resolution of the neighboring peaks
// default value is 1 correspond to 3 sigma distance
// between peaks. Higher values allow higher resolution
// (smaller distance between peaks.
// May be set later through SetResolution.
if (resolution > 1)
fResolution = resolution;
else
fResolution = 1;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
/////////////////////NEW FUNCTIONS APRIL 2003
//______________________________________________________________________________
const char *TSpectrum2::Background2(float **spectrum, int sizex, int sizey,
int number_of_iterations)
{
/////////////////////////////////////////////////////////////////////////////
// TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION //
// This function calculates background spectrum from source spectrum. //
// The result is placed to the array pointed by spectrum pointer. //
// //
// Function parameters: //
// spectrum: pointer to the array of source spectrum //
// sizex: x length of spectrum and working space arrays //
// sizey: y length of spectrum and working space arrays //
// number_of_iterations, for details we refer to manual //
// //
/////////////////////////////////////////////////////////////////////////////
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations < 1)
return "Width of Clipping Window Must Be Positive";
if (sizex < 2 * number_of_iterations + 1)
return ("Too Large Clipping Window");
// working_space-pointer to the working array
float **working_space = new float *[sizex];
int i, x, y;
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
float a, b, p1, p2, p3, p4, s1, s2, s3, s4;
for (i = 1; i <= number_of_iterations; i++) {
for (y = i; y < sizey - i; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
p1 = spectrum[x - i][y - i];
p2 = spectrum[x - i][y + i];
p3 = spectrum[x + i][y - i];
p4 = spectrum[x + i][y + i];
s1 = spectrum[x][y - i];
s2 = spectrum[x - i][y];
s3 = spectrum[x + i][y];
s4 = spectrum[x][y + i];
b = (p1 + p2) / 2.0;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 + p3 +
p4) / 4.0;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = i; y < sizey - i; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Background2RectangularRidges(float **spectrum,
int sizex, int sizey,
int
number_of_iterations_x,
int
number_of_iterations_y,
int direction,
int filter_order,
int filter_type)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - RECTANGULAR RIDGES*/
/* This function calculates background spectrum from source spectrum. */
/* The result is placed to the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* number_of_iterations_x-maximal x width of clipping window */
/* number_of_iterations_y-maximal y width of clipping window */
/* for details we refer to manual */
/* direction- direction of change of clipping window */
/* - possible values=BACK2_INCREASING_WINDOW */
/* BACK2_DECREASING_WINDOW */
/* filter_order-order of clipping filter, */
/* -possible values=BACK2_ORDER2 */
/* BACK2_ORDER4 */
/* BACK2_ORDER6 */
/* BACK2_ORDER8 */
/* filter_type-determines the algorithm of the filtering */
/* -possible values=BACK2_SUCCESSIVE_FILTERING */
/* BACK2_ONE_STEP_FILTERING */
/* */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, x, y, sampling, r1, r2;
float a, b, c, d, e, p1, p2, p3, p4, s1, s2, s3, s4, ar1, ar2;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations_x < 1 || number_of_iterations_y < 1)
return "Width of Clipping Window Must Be Positive";
if (sizex < 2 * number_of_iterations_x + 1
|| sizey < 2 * number_of_iterations_y + 1)
return ("Too Large Clipping Window");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
sampling =
(int) TMath::Max(number_of_iterations_x, number_of_iterations_y);
if (direction == BACK2_INCREASING_WINDOW) {
if (filter_type == BACK2_SUCCESSIVE_FILTERING) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2;
ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - r1][y - (int) (3 * ar2)] -
6 * spectrum[x - r1][y - (int) (2 * ar2)] +
15 * spectrum[x - r1][y - (int) ar2] +
15 * spectrum[x - r1][y + (int) ar2] -
6 * spectrum[x - r1][y + (int) (2 * ar2)] +
spectrum[x - r1][y + (int) (3 * ar2)]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y - r2] -
6 * spectrum[x - (int) (2 * ar1)][y - r2] +
15 * spectrum[x - (int) ar1][y - r2] +
15 * spectrum[x + (int) ar1][y - r2] -
6 * spectrum[x + (int) (2 * ar1)][y - r2] +
spectrum[x + (int) (3 * ar1)][y - r2]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y + r2] -
6 * spectrum[x - (int) (2 * ar1)][y + r2] +
15 * spectrum[x - (int) ar1][y + r2] +
15 * spectrum[x + (int) ar1][y + r2] -
6 * spectrum[x + (int) (2 * ar1)][y + r2] +
spectrum[x + (int) (3 * ar1)][y + r2]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x + r1][y - (int) (3 * ar2)] -
6 * spectrum[x + r1][y - (int) (2 * ar2)] +
15 * spectrum[x + r1][y - (int) ar2] +
15 * spectrum[x + r1][y + (int) ar2] -
6 * spectrum[x + r1][y + (int) (2 * ar2)] +
spectrum[x + r1][y + (int) (3 * ar2)]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - r1][y - (int) (3 * ar2)] -
6 * spectrum[x - r1][y - (int) (2 * ar2)] +
15 * spectrum[x - r1][y - (int) ar2] +
15 * spectrum[x - r1][y + (int) ar2] -
6 * spectrum[x - r1][y + (int) (2 * ar2)] +
spectrum[x - r1][y + (int) (3 * ar2)]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - r1][y - (int) (4 * ar2)] +
8 * spectrum[x - r1][y - (int) (3 * ar2)] -
28 * spectrum[x - r1][y - (int) (2 * ar2)] +
56 * spectrum[x - r1][y - (int) ar2] +
56 * spectrum[x - r1][y + (int) ar2] -
28 * spectrum[x - r1][y + (int) (2 * ar2)] +
8 * spectrum[x - r1][y + (int) (3 * ar2)] -
spectrum[x - r1][y + (int) (4 * ar2)]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y - r2] -
6 * spectrum[x - (int) (2 * ar1)][y - r2] +
15 * spectrum[x - (int) ar1][y - r2] +
15 * spectrum[x + (int) ar1][y - r2] -
6 * spectrum[x + (int) (2 * ar1)][y - r2] +
spectrum[x + (int) (3 * ar1)][y - r2]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - (int) (4 * ar1)][y - r2] +
8 * spectrum[x - (int) (3 * ar1)][y - r2] -
28 * spectrum[x - (int) (2 * ar1)][y - r2] +
56 * spectrum[x - (int) ar1][y - r2] +
56 * spectrum[x + (int) ar1][y - r2] -
28 * spectrum[x + (int) (2 * ar1)][y - r2] +
8 * spectrum[x + (int) (3 * ar1)][y - r2] -
spectrum[x + (int) (4 * ar1)][y - r2]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y + r2] -
6 * spectrum[x - (int) (2 * ar1)][y + r2] +
15 * spectrum[x - (int) ar1][y + r2] +
15 * spectrum[x + (int) ar1][y + r2] -
6 * spectrum[x + (int) (2 * ar1)][y + r2] +
spectrum[x + (int) (3 * ar1)][y + r2]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - (int) (4 * ar1)][y + r2] +
8 * spectrum[x - (int) (3 * ar1)][y + r2] -
28 * spectrum[x - (int) (2 * ar1)][y + r2] +
56 * spectrum[x - (int) ar1][y + r2] +
56 * spectrum[x + (int) ar1][y + r2] -
28 * spectrum[x + (int) (2 * ar1)][y + r2] +
8 * spectrum[x + (int) (3 * ar1)][y + r2] -
spectrum[x + (int) (4 * ar1)][y + r2]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x + r1][y - (int) (3 * ar2)] -
6 * spectrum[x + r1][y - (int) (2 * ar2)] +
15 * spectrum[x + r1][y - (int) ar2] +
15 * spectrum[x + r1][y + (int) ar2] -
6 * spectrum[x + r1][y + (int) (2 * ar2)] +
spectrum[x + r1][y + (int) (3 * ar2)]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x + r1][y - (int) (4 * ar2)] +
8 * spectrum[x + r1][y - (int) (3 * ar2)] -
28 * spectrum[x + r1][y - (int) (2 * ar2)] +
56 * spectrum[x + r1][y - (int) ar2] +
56 * spectrum[x + r1][y + (int) ar2] -
28 * spectrum[x + r1][y + (int) (2 * ar2)] +
8 * spectrum[x + r1][y + (int) (3 * ar2)] -
spectrum[x + r1][y + (int) (4 * ar2)]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (filter_type == BACK2_ONE_STEP_FILTERING) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = i; y < sizey - i; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
e = -(spectrum[x - (int) (4 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x -
(int) (4 *
ar1)][y
+
(int)
(4
*
ar2)]
+ spectrum[x + (int) (4 * ar1)][y -
(int) (4 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (4 *
ar2)]);
e +=
8 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (4 * ar2)]);
e +=
8 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (3 * ar2)]);
e -=
28 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (4 * ar2)]);
e -=
28 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (2 * ar2)]);
e +=
56 *
(spectrum[x - (int) ar1][y - (int) (4 * ar2)] +
spectrum[x + (int) ar1][y - (int) (4 * ar2)] +
spectrum[x - (int) ar1][y + (int) (4 * ar2)] +
spectrum[x + (int) ar1][y + (int) (4 * ar2)]);
e +=
56 *
(spectrum[x - (int) (4 * ar1)][y - (int) ar2] +
spectrum[x + (int) (4 * ar1)][y - (int) ar2] +
spectrum[x - (int) (4 * ar1)][y + (int) ar2] +
spectrum[x + (int) (4 * ar1)][y + (int) ar2]);
e -=
70 * (spectrum[x][y - (int) (4 * ar2)] +
spectrum[x - (int) (4 * ar1)][y] +
spectrum[x][y + (int) (4 * ar2)] +
spectrum[x + (int) (4 * ar1)][y]);
e -=
64 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y +
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
e -=
448 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
e -=
448 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
e +=
560 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e -=
784 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e +=
1568 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
e +=
1568 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
e -=
1960 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
e -=
3136 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
e +=
3920 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
}
else if (direction == BACK2_DECREASING_WINDOW) {
if (filter_type == BACK2_SUCCESSIVE_FILTERING) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2;
ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - r1][y - (int) (3 * ar2)] -
6 * spectrum[x - r1][y - (int) (2 * ar2)] +
15 * spectrum[x - r1][y - (int) ar2] +
15 * spectrum[x - r1][y + (int) ar2] -
6 * spectrum[x - r1][y + (int) (2 * ar2)] +
spectrum[x - r1][y + (int) (3 * ar2)]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y - r2] -
6 * spectrum[x - (int) (2 * ar1)][y - r2] +
15 * spectrum[x - (int) ar1][y - r2] +
15 * spectrum[x + (int) ar1][y - r2] -
6 * spectrum[x + (int) (2 * ar1)][y - r2] +
spectrum[x + (int) (3 * ar1)][y - r2]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y + r2] -
6 * spectrum[x - (int) (2 * ar1)][y + r2] +
15 * spectrum[x - (int) ar1][y + r2] +
15 * spectrum[x + (int) ar1][y + r2] -
6 * spectrum[x + (int) (2 * ar1)][y + r2] +
spectrum[x + (int) (3 * ar1)][y + r2]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x + r1][y - (int) (3 * ar2)] -
6 * spectrum[x + r1][y - (int) (2 * ar2)] +
15 * spectrum[x + r1][y - (int) ar2] +
15 * spectrum[x + r1][y + (int) ar2] -
6 * spectrum[x + r1][y + (int) (2 * ar2)] +
spectrum[x + r1][y + (int) (3 * ar2)]) / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
b = (p1 + p2) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - r1][y - (int) (2 * ar2)] +
4 * spectrum[x - r1][y - (int) ar2] +
4 * spectrum[x - r1][y + (int) ar2] -
spectrum[x - r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - r1][y - (int) (3 * ar2)] -
6 * spectrum[x - r1][y - (int) (2 * ar2)] +
15 * spectrum[x - r1][y - (int) ar2] +
15 * spectrum[x - r1][y + (int) ar2] -
6 * spectrum[x - r1][y + (int) (2 * ar2)] +
spectrum[x - r1][y + (int) (3 * ar2)]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - r1][y - (int) (4 * ar2)] +
8 * spectrum[x - r1][y - (int) (3 * ar2)] -
28 * spectrum[x - r1][y - (int) (2 * ar2)] +
56 * spectrum[x - r1][y - (int) ar2] +
56 * spectrum[x - r1][y + (int) ar2] -
28 * spectrum[x - r1][y + (int) (2 * ar2)] +
8 * spectrum[x - r1][y + (int) (3 * ar2)] -
spectrum[x - r1][y + (int) (4 * ar2)]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s2)
s2 = b;
b = (p1 + p3) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y - r2] +
4 * spectrum[x - (int) ar1][y - r2] +
4 * spectrum[x + (int) ar1][y - r2] -
spectrum[x + (int) (2 * ar1)][y - r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y - r2] -
6 * spectrum[x - (int) (2 * ar1)][y - r2] +
15 * spectrum[x - (int) ar1][y - r2] +
15 * spectrum[x + (int) ar1][y - r2] -
6 * spectrum[x + (int) (2 * ar1)][y - r2] +
spectrum[x + (int) (3 * ar1)][y - r2]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - (int) (4 * ar1)][y - r2] +
8 * spectrum[x - (int) (3 * ar1)][y - r2] -
28 * spectrum[x - (int) (2 * ar1)][y - r2] +
56 * spectrum[x - (int) ar1][y - r2] +
56 * spectrum[x + (int) ar1][y - r2] -
28 * spectrum[x + (int) (2 * ar1)][y - r2] +
8 * spectrum[x + (int) (3 * ar1)][y - r2] -
spectrum[x + (int) (4 * ar1)][y - r2]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s1)
s1 = b;
b = (p2 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x - (int) (2 * ar1)][y + r2] +
4 * spectrum[x - (int) ar1][y + r2] +
4 * spectrum[x + (int) ar1][y + r2] -
spectrum[x + (int) (2 * ar1)][y + r2]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x - (int) (3 * ar1)][y + r2] -
6 * spectrum[x - (int) (2 * ar1)][y + r2] +
15 * spectrum[x - (int) ar1][y + r2] +
15 * spectrum[x + (int) ar1][y + r2] -
6 * spectrum[x + (int) (2 * ar1)][y + r2] +
spectrum[x + (int) (3 * ar1)][y + r2]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x - (int) (4 * ar1)][y + r2] +
8 * spectrum[x - (int) (3 * ar1)][y + r2] -
28 * spectrum[x - (int) (2 * ar1)][y + r2] +
56 * spectrum[x - (int) ar1][y + r2] +
56 * spectrum[x + (int) ar1][y + r2] -
28 * spectrum[x + (int) (2 * ar1)][y + r2] +
8 * spectrum[x + (int) (3 * ar1)][y + r2] -
spectrum[x + (int) (4 * ar1)][y + r2]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s4)
s4 = b;
b = (p3 + p4) / 2.0;
ar1 = r1 / 2, ar2 = r2 / 2;
c = (-spectrum[x + r1][y - (int) (2 * ar2)] +
4 * spectrum[x + r1][y - (int) ar2] +
4 * spectrum[x + r1][y + (int) ar2] -
spectrum[x + r1][y + (int) (2 * ar2)]) / 6;
ar1 = r1 / 3, ar2 = r2 / 3;
d = (spectrum[x + r1][y - (int) (3 * ar2)] -
6 * spectrum[x + r1][y - (int) (2 * ar2)] +
15 * spectrum[x + r1][y - (int) ar2] +
15 * spectrum[x + r1][y + (int) ar2] -
6 * spectrum[x + r1][y + (int) (2 * ar2)] +
spectrum[x + r1][y + (int) (3 * ar2)]) / 20;
ar1 = r1 / 4, ar2 = r2 / 4;
e = (-spectrum[x + r1][y - (int) (4 * ar2)] +
8 * spectrum[x + r1][y - (int) (3 * ar2)] -
28 * spectrum[x + r1][y - (int) (2 * ar2)] +
56 * spectrum[x + r1][y - (int) ar2] +
56 * spectrum[x + r1][y + (int) ar2] -
28 * spectrum[x + r1][y + (int) (2 * ar2)] +
8 * spectrum[x + r1][y + (int) (3 * ar2)] -
spectrum[x + r1][y + (int) (4 * ar2)]) / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b > s3)
s3 = b;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
b = (s1 + s4) / 2.0 + (s2 + s3) / 2.0 + (p1 + p2 +
p3 +
p4) / 4.0;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (filter_type == BACK2_ONE_STEP_FILTERING) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = i; y < sizey - i; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
e = -(spectrum[x - (int) (4 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x -
(int) (4 *
ar1)][y
+
(int)
(4
*
ar2)]
+ spectrum[x + (int) (4 * ar1)][y -
(int) (4 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (4 *
ar2)]);
e +=
8 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (4 * ar2)]);
e +=
8 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (3 * ar2)]);
e -=
28 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (4 * ar2)]);
e -=
28 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (2 * ar2)]);
e +=
56 *
(spectrum[x - (int) ar1][y - (int) (4 * ar2)] +
spectrum[x + (int) ar1][y - (int) (4 * ar2)] +
spectrum[x - (int) ar1][y + (int) (4 * ar2)] +
spectrum[x + (int) ar1][y + (int) (4 * ar2)]);
e +=
56 *
(spectrum[x - (int) (4 * ar1)][y - (int) ar2] +
spectrum[x + (int) (4 * ar1)][y - (int) ar2] +
spectrum[x - (int) (4 * ar1)][y + (int) ar2] +
spectrum[x + (int) (4 * ar1)][y + (int) ar2]);
e -=
70 * (spectrum[x][y - (int) (4 * ar2)] +
spectrum[x - (int) (4 * ar1)][y] +
spectrum[x][y + (int) (4 * ar2)] +
spectrum[x + (int) (4 * ar1)][y]);
e -=
64 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y +
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
e -=
448 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
e -=
448 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
e +=
560 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e -=
784 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e +=
1568 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
e +=
1568 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
e -=
1960 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
e -=
3136 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
e +=
3920 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Background2RectangularRidgesX(float **spectrum,
int sizex, int sizey,
int
number_of_iterations,
int direction,
int filter_order)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - */
/* RECTANGULAR 1D-RIDGES IN X-DIMENSION */
/* This function calculates background spectrum from source spectrum. */
/* The result is placed to the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* number_of_iterations-maximal x width of clipping window */
/* for details we refer to manual */
/* direction- direction of change of clipping window */
/* - possible values=BACK2_INCREASING_WINDOW */
/* BACK2_DECREASING_WINDOW */
/* filter_order-order of clipping filter, */
/* -possible values=BACK2_ORDER2 */
/* BACK2_ORDER4 */
/* BACK2_ORDER6 */
/* BACK2_ORDER8 */
/* */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, x, y, sampling;
float a, b, c, d, e, ai;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations < 1)
return "Width of Clipping Window Must Be Positive";
if (sizex < 2 * number_of_iterations + 1)
return ("Too Large Clipping Window");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
sampling = number_of_iterations;
if (direction == BACK2_INCREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
d = 0;
ai = i / 3;
d += spectrum[x - (int) (3 * ai)][y] / 20;
d -= 6 * spectrum[x - (int) (2 * ai)][y] / 20;
d += 15 * spectrum[x - (int) ai][y] / 20;
d += 15 * spectrum[x + (int) ai][y] / 20;
d -= 6 * spectrum[x + (int) (2 * ai)][y] / 20;
d += spectrum[x + (int) (3 * ai)][y] / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
d = 0;
ai = i / 3;
d += spectrum[x - (int) (3 * ai)][y] / 20;
d -= 6 * spectrum[x - (int) (2 * ai)][y] / 20;
d += 15 * spectrum[x - (int) ai][y] / 20;
d += 15 * spectrum[x + (int) ai][y] / 20;
d -= 6 * spectrum[x + (int) (2 * ai)][y] / 20;
d += spectrum[x + (int) (3 * ai)][y] / 20;
e = 0;
ai = i / 4;
e -= spectrum[x - (int) (4 * ai)][y] / 70;
e += 8 * spectrum[x - (int) (3 * ai)][y] / 70;
e -= 28 * spectrum[x - (int) (2 * ai)][y] / 70;
e += 56 * spectrum[x - (int) ai][y] / 70;
e += 56 * spectrum[x + (int) ai][y] / 70;
e -= 28 * spectrum[x + (int) (2 * ai)][y] / 70;
e += 8 * spectrum[x + (int) (3 * ai)][y] / 70;
e -= spectrum[x + (int) (4 * ai)][y] / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (direction == BACK2_DECREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
d = 0;
ai = i / 3;
d += spectrum[x - (int) (3 * ai)][y] / 20;
d -= 6 * spectrum[x - (int) (2 * ai)][y] / 20;
d += 15 * spectrum[x - (int) ai][y] / 20;
d += 15 * spectrum[x + (int) ai][y] / 20;
d -= 6 * spectrum[x + (int) (2 * ai)][y] / 20;
d += spectrum[x + (int) (3 * ai)][y] / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
a = spectrum[x][y];
b = (spectrum[x - i][y] + spectrum[x + i][y]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x - (int) (2 * ai)][y] / 6;
c += 4 * spectrum[x - (int) ai][y] / 6;
c += 4 * spectrum[x + (int) ai][y] / 6;
c -= spectrum[x + (int) (2 * ai)][y] / 6;
d = 0;
ai = i / 3;
d += spectrum[x - (int) (3 * ai)][y] / 20;
d -= 6 * spectrum[x - (int) (2 * ai)][y] / 20;
d += 15 * spectrum[x - (int) ai][y] / 20;
d += 15 * spectrum[x + (int) ai][y] / 20;
d -= 6 * spectrum[x + (int) (2 * ai)][y] / 20;
d += spectrum[x + (int) (3 * ai)][y] / 20;
e = 0;
ai = i / 4;
e -= spectrum[x - (int) (4 * ai)][y] / 70;
e += 8 * spectrum[x - (int) (3 * ai)][y] / 70;
e -= 28 * spectrum[x - (int) (2 * ai)][y] / 70;
e += 56 * spectrum[x - (int) ai][y] / 70;
e += 56 * spectrum[x + (int) ai][y] / 70;
e -= 28 * spectrum[x + (int) (2 * ai)][y] / 70;
e += 8 * spectrum[x + (int) (3 * ai)][y] / 70;
e -= spectrum[x + (int) (4 * ai)][y] / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (y = 0; y < sizey; y++) {
for (x = i; x < sizex - i; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Background2RectangularRidgesY(float **spectrum,
int sizex, int sizey,
int
number_of_iterations,
int direction,
int filter_order)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - */
/* RECTANGULAR 1D-RIDGES IN Y-DIMENSION */
/* This function calculates background spectrum from source spectrum. */
/* The result is placed to the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* number_of_iterations-maximal y width of clipping window */
/* for details we refer to manual */
/* direction- direction of change of clipping window */
/* - possible values=BACK2_INCREASING_WINDOW */
/* BACK2_DECREASING_WINDOW */
/* filter_order-order of clipping filter, */
/* -possible values=BACK2_ORDER2 */
/* BACK2_ORDER4 */
/* BACK2_ORDER6 */
/* BACK2_ORDER8 */
/* */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, x, y, sampling;
float a, b, c, d, e, ai;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations < 1)
return "Width of Clipping Window Must Be Positive";
if (sizey < 2 * number_of_iterations + 1)
return ("Too Large Clipping Window");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
sampling = number_of_iterations;
if (direction == BACK2_INCREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
d = 0;
ai = i / 3;
d += spectrum[x][y - (int) (3 * ai)] / 20;
d -= 6 * spectrum[x][y - (int) (2 * ai)] / 20;
d += 15 * spectrum[x][y - (int) ai] / 20;
d += 15 * spectrum[x][y + (int) ai] / 20;
d -= 6 * spectrum[x][y + (int) (2 * ai)] / 20;
d += spectrum[x][y + (int) (3 * ai)] / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
d = 0;
ai = i / 3;
d += spectrum[x][y - (int) (3 * ai)] / 20;
d -= 6 * spectrum[x][y - (int) (2 * ai)] / 20;
d += 15 * spectrum[x][y - (int) ai] / 20;
d += 15 * spectrum[x][y + (int) ai] / 20;
d -= 6 * spectrum[x][y + (int) (2 * ai)] / 20;
d += spectrum[x][y + (int) (3 * ai)] / 20;
e = 0;
ai = i / 4;
e -= spectrum[x][y - (int) (4 * ai)] / 70;
e += 8 * spectrum[x][y - (int) (3 * ai)] / 70;
e -= 28 * spectrum[x][y - (int) (2 * ai)] / 70;
e += 56 * spectrum[x][y - (int) ai] / 70;
e += 56 * spectrum[x][y + (int) ai] / 70;
e -= 28 * spectrum[x][y + (int) (2 * ai)] / 70;
e += 8 * spectrum[x][y + (int) (3 * ai)] / 70;
e -= spectrum[x][y + (int) (4 * ai)] / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (direction == BACK2_DECREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
d = 0;
ai = i / 3;
d += spectrum[x][y - (int) (3 * ai)] / 20;
d -= 6 * spectrum[x][y - (int) (2 * ai)] / 20;
d += 15 * spectrum[x][y - (int) ai] / 20;
d += 15 * spectrum[x][y + (int) ai] / 20;
d -= 6 * spectrum[x][y + (int) (2 * ai)] / 20;
d += spectrum[x][y + (int) (3 * ai)] / 20;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
a = spectrum[x][y];
b = (spectrum[x][y - i] + spectrum[x][y + i]) / 2.0;
c = 0;
ai = i / 2;
c -= spectrum[x][y - (int) (2 * ai)] / 6;
c += 4 * spectrum[x][y - (int) ai] / 6;
c += 4 * spectrum[x][y + (int) ai] / 6;
c -= spectrum[x][y + (int) (2 * ai)] / 6;
d = 0;
ai = i / 3;
d += spectrum[x][y - (int) (3 * ai)] / 20;
d -= 6 * spectrum[x][y - (int) (2 * ai)] / 20;
d += 15 * spectrum[x][y - (int) ai] / 20;
d += 15 * spectrum[x][y + (int) ai] / 20;
d -= 6 * spectrum[x][y + (int) (2 * ai)] / 20;
d += spectrum[x][y + (int) (3 * ai)] / 20;
e = 0;
ai = i / 4;
e -= spectrum[x][y - (int) (4 * ai)] / 70;
e += 8 * spectrum[x][y - (int) (3 * ai)] / 70;
e -= 28 * spectrum[x][y - (int) (2 * ai)] / 70;
e += 56 * spectrum[x][y - (int) ai] / 70;
e += 56 * spectrum[x][y + (int) ai] / 70;
e -= 28 * spectrum[x][y + (int) (2 * ai)] / 70;
e += 8 * spectrum[x][y + (int) (3 * ai)] / 70;
e -= spectrum[x][y + (int) (4 * ai)] / 70;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a)
a = b;
working_space[x][y] = a;
}
}
for (x = 0; x < sizex; x++) {
for (y = i; y < sizey - i; y++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Background2SkewRidges(float **spectrum, int sizex,
int sizey,
int number_of_iterations_x,
int number_of_iterations_y,
int direction,
int filter_order)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - SKEW RIDGES */
/* This function calculates background spectrum from source spectrum. */
/* The result is placed to the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* number_of_iterations_x-maximal x width of clipping window */
/* number_of_iterations_y-maximal y width of clipping window */
/* for details we refer to manual */
/* direction- direction of change of clipping window */
/* - possible values=BACK2_INCREASING_WINDOW */
/* BACK2_DECREASING_WINDOW */
/* filter_order-order of clipping filter, */
/* -possible values=BACK2_ORDER2 */
/* BACK2_ORDER4 */
/* BACK2_ORDER6 */
/* BACK2_ORDER8 */
/* */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, j, k, x, y, sampling, r1, r2;
float a, b, c, d, e, p, ar1, ar2, array[32];
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations_x < 1 || number_of_iterations_y < 1)
return "Width of Clipping Window Must Be Positive";
if (sizex < 2 * number_of_iterations_x + 1
|| sizey < 2 * number_of_iterations_y + 1)
return ("Too Large Clipping Window");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
sampling =
(int) TMath::Max(number_of_iterations_x, number_of_iterations_y);
if (direction == BACK2_INCREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * (array[0] + array[1] + array[2] + array[3]) -
225 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * (array[0] + array[1] + array[2] +
array[3]) + 90 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) -
36 * (array[12] + array[13] + array[14] + array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * (array[0] + array[1] + array[2] +
array[3]) - 15 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) +
6 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] + array[19]) -
(array[20] + array[21] + array[22] + array[23]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * (array[0] + array[1] + array[2] + array[3]) -
225 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * (array[0] + array[1] + array[2] +
array[3]) + 90 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) -
36 * (array[12] + array[13] + array[14] + array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * (array[0] + array[1] + array[2] +
array[3]) - 15 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) +
6 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] + array[19]) -
(array[20] + array[21] + array[22] + array[23]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = 3920 * (array[0] + array[1] + array[2] + array[3]) -
3136 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * (array[0] + array[1] + array[2] +
array[3]) + 1568 * (array[4] +
array[5] +
array[6] +
array[7] +
array[8] +
array[9] +
array[10] +
array[11]) -
784 * (array[12] + array[13] + array[14] +
array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * (array[0] + array[1] + array[2] +
array[3]) - 448 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) +
224 * (array[12] + array[13] + array[14] +
array[15] + array[16] + array[17] +
array[18] + array[19]) - 64 * (array[20] +
array[21] +
array[22] +
array[23]);
for (j = -4, k = 0; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (4 * ar2)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (4 * ar1)][y +
(int) (j * ar1)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (4 * ar2)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x - (int) (4 * ar1)][y +
(int) (j * ar1)];
} for (j = 31; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * (array[0] + array[1] + array[2] +
array[3]) + 56 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
28 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] +
array[19]) + 8 * (array[20] + array[21] +
array[22] + array[23] +
array[24] + array[25] +
array[26] + array[27]) -
(array[28] + array[29] + array[30] + array[31]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (direction == BACK2_DECREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * (array[0] + array[1] + array[2] + array[3]) -
225 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * (array[0] + array[1] + array[2] +
array[3]) + 90 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) -
36 * (array[12] + array[13] + array[14] + array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * (array[0] + array[1] + array[2] +
array[3]) - 15 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) +
6 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] + array[19]) -
(array[20] + array[21] + array[22] + array[23]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y - r2];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + r1][y + j * r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x + j * r1][y + r1];
}
for (j = -1; j < 1; j++, k++) {
array[k] = spectrum[x - r1][y + j * r1];
}
for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * (array[0] + array[1] + array[2] + array[3]) -
(array[4] + array[5] + array[6] + array[7])) / 4;
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * (array[0] + array[1] + array[2] + array[3]) -
16 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * (array[0] + array[1] + array[2] +
array[3]) + 4 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
(array[12] + array[13] + array[14] + array[15]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * (array[0] + array[1] + array[2] + array[3]) -
225 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * (array[0] + array[1] + array[2] +
array[3]) + 90 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) -
36 * (array[12] + array[13] + array[14] + array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * (array[0] + array[1] + array[2] +
array[3]) - 15 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) +
6 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] + array[19]) -
(array[20] + array[21] + array[22] + array[23]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
for (j = -1, k = 0; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y - (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y + (int) (j * ar1)];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y + (int) ar2];
} for (j = -1; j < 1; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y + (int) (j * ar1)];
} for (j = 7; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = 3920 * (array[0] + array[1] + array[2] + array[3]) -
3136 * (array[4] + array[5] + array[6] + array[7]);
for (j = -2, k = 0; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (2 * ar2)];
} for (j = -2; j < 2; j++, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1)];
} for (j = 15; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * (array[0] + array[1] + array[2] +
array[3]) + 1568 * (array[4] +
array[5] +
array[6] +
array[7] +
array[8] +
array[9] +
array[10] +
array[11]) -
784 * (array[12] + array[13] + array[14] +
array[15]);
for (j = -3, k = 0; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (3 * ar2)];
} for (j = -3; j < 3; j++, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1)];
} for (j = 23; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * (array[0] + array[1] + array[2] +
array[3]) - 448 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] +
array[11]) +
224 * (array[12] + array[13] + array[14] +
array[15] + array[16] + array[17] +
array[18] + array[19]) - 64 * (array[20] +
array[21] +
array[22] +
array[23]);
for (j = -4, k = 0; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y -
(int) (4 * ar2)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (4 * ar1)][y +
(int) (j * ar1)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1)][y +
(int) (4 * ar2)];
} for (j = -4; j < 4; j++, k++) {
array[k] =
spectrum[x - (int) (4 * ar1)][y +
(int) (j * ar1)];
} for (j = 31; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * (array[0] + array[1] + array[2] +
array[3]) + 56 * (array[4] + array[5] +
array[6] + array[7] +
array[8] + array[9] +
array[10] + array[11]) -
28 * (array[12] + array[13] + array[14] + array[15] +
array[16] + array[17] + array[18] +
array[19]) + 8 * (array[20] + array[21] +
array[22] + array[23] +
array[24] + array[25] +
array[26] + array[27]) -
(array[28] + array[29] + array[30] + array[31]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Background2NonlinearRidges(float **spectrum,
int sizex, int sizey,
int
number_of_iterations_x,
int
number_of_iterations_y,
int direction,
int filter_order)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL BACKGROUND ESTIMATION FUNCTION - NONLINEAR RIDGES */
/* This function calculates background spectrum from source spectrum. */
/* The result is placed to the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* number_of_iterations_x-maximal x width of clipping window */
/* number_of_iterations_y-maximal y width of clipping window */
/* for details we refer to manual */
/* direction- direction of change of clipping window */
/* - possible values=BACK2_INCREASING_WINDOW */
/* BACK2_DECREASING_WINDOW */
/* filter_order-order of clipping filter, */
/* -possible values=BACK2_ORDER2 */
/* BACK2_ORDER4 */
/* BACK2_ORDER6 */
/* BACK2_ORDER8 */
/* */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, j, k, x, y, sampling, r1, r2, x1max, x2max, y1max, y2max;
float a, b, c, d, e, f, p, ar1, ar2, array[1000], p1, p2, p3, p4, s1,
s2, s3, s4;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations_x < 1 || number_of_iterations_y < 1)
return "Width of Clipping Window Must Be Positive";
if (sizex < 2 * number_of_iterations_x + 1
|| sizey < 2 * number_of_iterations_y + 1)
return ("Too Large Clipping Window");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
sampling =
(int) TMath::Max(number_of_iterations_x, number_of_iterations_y);
if (direction == BACK2_INCREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
if (b < a && b > 0)
a = b;
}
else {
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = 1; i <= sampling; i++) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
e = -(spectrum[x - (int) (4 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x -
(int) (4 *
ar1)][y
+
(int)
(4
*
ar2)]
+ spectrum[x + (int) (4 * ar1)][y -
(int) (4 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (4 *
ar2)]);
e +=
8 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (4 * ar2)]);
e +=
8 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (3 * ar2)]);
e -=
28 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (4 * ar2)]);
e -=
28 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (2 * ar2)]);
e +=
56 *
(spectrum[x - (int) ar1][y - (int) (4 * ar2)] +
spectrum[x + (int) ar1][y - (int) (4 * ar2)] +
spectrum[x - (int) ar1][y + (int) (4 * ar2)] +
spectrum[x + (int) ar1][y + (int) (4 * ar2)]);
e +=
56 *
(spectrum[x - (int) (4 * ar1)][y - (int) ar2] +
spectrum[x + (int) (4 * ar1)][y - (int) ar2] +
spectrum[x - (int) (4 * ar1)][y + (int) ar2] +
spectrum[x + (int) (4 * ar1)][y + (int) ar2]);
e -=
70 * (spectrum[x][y - (int) (4 * ar2)] +
spectrum[x - (int) (4 * ar1)][y] +
spectrum[x][y + (int) (4 * ar2)] +
spectrum[x + (int) (4 * ar1)][y]);
e -=
64 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y +
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
e -=
448 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
e -=
448 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
e +=
560 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e -=
784 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e +=
1568 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
e +=
1568 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
e -=
1960 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
e -=
3136 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
e +=
3920 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = 3920 * array[0] - 3136 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r1 - 1] +
array[r1]) -
784 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r2 - 1] +
array[r2]) -
784 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r1 - 1] +
array[r1]) -
784 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r2 - 1] +
array[r2]) -
784 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
224 * (array[4 * r1 / 3 - 1] +
array[4 * r1 / 3]) - 64 * array[2 * r1 -
1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
224 * (array[4 * r2 / 3 - 1] +
array[4 * r2 / 3]) - 64 * array[2 * r2 -
1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
224 * (array[4 * r1 / 3 - 1] +
array[4 * r1 / 3]) - 64 * array[2 * r1 -
1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
224 * (array[4 * r2 / 3 - 1] +
array[4 * r2 / 3]) - 64 * array[2 * r2 -
1];
for (j = -4 * r1, k = 0; j < 4 * r1; j += 4, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (4 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r1 / 4 - 1] +
array[2 * r1 / 4]) -
28 * (array[r1 - 1] + array[r1]) +
8 * (array[3 * r1 / 4 - 1] + array[3 * r1 / 4]) -
array[2 * r1 - 1];
for (j = -4 * r2, k = 0; j < 4 * r2; j += 4, k++) {
array[k] =
spectrum[x + (int) (4 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r2 / 4 - 1] +
array[2 * r2 / 4]) -
28 * (array[r2 - 1] + array[r2]) +
8 * (array[3 * r2 / 4 - 1] + array[3 * r2 / 4]) -
array[2 * r2 - 1];
for (j = -4 * r1, k = 0; j < 4 * r1; j += 4, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (4 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r1 / 4 - 1] +
array[2 * r1 / 4]) -
28 * (array[r1 - 1] + array[r1]) +
8 * (array[3 * r1 / 4 - 1] + array[3 * r1 / 4]) -
array[2 * r1 - 1];
for (j = -4 * r2, k = 0; j < 4 * r2; j += 4, k++) {
array[k] =
spectrum[x - (int) (4 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r2 / 4 - 1] +
array[2 * r2 / 4]) -
28 * (array[r2 - 1] + array[r2]) +
8 * (array[3 * r2 / 4 - 1] + array[3 * r2 / 4]) -
array[2 * r2 - 1];
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
else if (direction == BACK2_DECREASING_WINDOW) {
if (filter_order == BACK2_ORDER2) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
if (b < a && b > 0)
a = b;
}
else {
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER4) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
ar1 = r1 / 2, ar2 = r2 / 2;
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER6) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
d = d / 400;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
else if (filter_order == BACK2_ORDER8) {
for (i = sampling; i >= 1; i--) {
r1 = (int) TMath::Min(i, number_of_iterations_x), r2 =
(int) TMath::Min(i, number_of_iterations_y);
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
a = spectrum[x][y];
f = 0, x1max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x + j][y - r2];
if (array[k] > f) {
f = array[k];
x1max = k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b = (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y1max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x + r1][y + j];
if (array[k] > f) {
f = array[k];
y1max = k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
f = 0, x2max = 0;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] = spectrum[x - j][y + r2];
if (array[k] > f) {
f = array[k];
x2max = 2 * r1 - k;
}
}
for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r1 - 1]) / 4;
f = 0, y2max = 0;
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] = spectrum[x - r1][y - j];
if (array[k] > f) {
f = array[k];
y2max = 2 * r2 - k;
}
}
for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
b += (2 * array[0] - array[2 * r2 - 1]) / 4;
p1 = spectrum[x - r1][y - r2];
p2 = spectrum[x - r1][y + r2];
p3 = spectrum[x + r1][y - r2];
p4 = spectrum[x + r1][y + r2];
s1 = spectrum[x][y - r2];
s2 = spectrum[x - r1][y];
s3 = spectrum[x + r1][y];
s4 = spectrum[x][y + r2];
c = (p1 + p2) / 2.0;
if (c > s2)
s2 = c;
c = (p1 + p3) / 2.0;
if (c > s1)
s1 = c;
c = (p2 + p4) / 2.0;
if (c > s4)
s4 = c;
c = (p3 + p4) / 2.0;
if (c > s3)
s3 = c;
s1 = s1 - (p1 + p3) / 2.0;
s2 = s2 - (p1 + p2) / 2.0;
s3 = s3 - (p3 + p4) / 2.0;
s4 = s4 - (p2 + p4) / 2.0;
if (s1 > 0 && s4 > 0 && x1max == x2max && s2 > 0
&& s3 > 0 && y1max == y2max) {
b = -(spectrum[x - r1][y - r2] +
spectrum[x - r1][y + r2] + spectrum[x + r1][y -
r2]
+ spectrum[x + r1][y + r2]) / 4 +
(spectrum[x][y - r2] + spectrum[x - r1][y] +
spectrum[x + r1][y] + spectrum[x][y + r2]) / 2;
ar1 = r1 / 2, ar2 = r2 / 2;
c = -(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y
+
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 *
ar2)]);
c +=
4 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
c +=
4 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
c -=
6 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
c -=
16 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
c +=
24 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] + spectrum[x][y +
(int)
ar2]
+ spectrum[x + (int) ar1][y]);
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
d = -(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y
+
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 *
ar2)]);
d +=
6 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
d +=
6 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
d -=
15 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
d -=
15 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
d +=
20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d -=
36 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
d +=
90 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
d +=
90 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
d -=
120 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
d -=
225 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
d +=
300 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
e = -(spectrum[x - (int) (4 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x -
(int) (4 *
ar1)][y
+
(int)
(4
*
ar2)]
+ spectrum[x + (int) (4 * ar1)][y -
(int) (4 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (4 *
ar2)]);
e +=
8 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (4 * ar2)]);
e +=
8 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (3 * ar2)]);
e -=
28 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (4 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(4
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (4 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (4 * ar2)]);
e -=
28 *
(spectrum[x - (int) (4 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (4 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (4 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (4 * ar1)][y +
(int) (2 * ar2)]);
e +=
56 *
(spectrum[x - (int) ar1][y - (int) (4 * ar2)] +
spectrum[x + (int) ar1][y - (int) (4 * ar2)] +
spectrum[x - (int) ar1][y + (int) (4 * ar2)] +
spectrum[x + (int) ar1][y + (int) (4 * ar2)]);
e +=
56 *
(spectrum[x - (int) (4 * ar1)][y - (int) ar2] +
spectrum[x + (int) (4 * ar1)][y - (int) ar2] +
spectrum[x - (int) (4 * ar1)][y + (int) ar2] +
spectrum[x + (int) (4 * ar1)][y + (int) ar2]);
e -=
70 * (spectrum[x][y - (int) (4 * ar2)] +
spectrum[x - (int) (4 * ar1)][y] +
spectrum[x][y + (int) (4 * ar2)] +
spectrum[x + (int) (4 * ar1)][y]);
e -=
64 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x -
(int) (3 *
ar1)][y +
(int)
(3
*
ar2)]
+ spectrum[x + (int) (3 * ar1)][y -
(int) (3 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (3 * ar2)] + spectrum[x +
(int) (2 *
ar1)][y -
(int)
(3
*
ar2)]
+ spectrum[x - (int) (2 * ar1)][y +
(int) (3 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (3 * ar2)]);
e +=
224 *
(spectrum[x - (int) (3 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x +
(int) (3 *
ar1)][y -
(int)
(2
*
ar2)]
+ spectrum[x - (int) (3 * ar1)][y +
(int) (2 *
ar2)] +
spectrum[x + (int) (3 * ar1)][y +
(int) (2 * ar2)]);
e -=
448 *
(spectrum[x - (int) ar1][y - (int) (3 * ar2)] +
spectrum[x + (int) ar1][y - (int) (3 * ar2)] +
spectrum[x - (int) ar1][y + (int) (3 * ar2)] +
spectrum[x + (int) ar1][y + (int) (3 * ar2)]);
e -=
448 *
(spectrum[x - (int) (3 * ar1)][y - (int) ar2] +
spectrum[x + (int) (3 * ar1)][y - (int) ar2] +
spectrum[x - (int) (3 * ar1)][y + (int) ar2] +
spectrum[x + (int) (3 * ar1)][y + (int) ar2]);
e +=
560 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e -=
784 *
(spectrum[x - (int) (2 * ar1)]
[y - (int) (2 * ar2)] + spectrum[x -
(int) (2 *
ar1)][y +
(int)
(2
*
ar2)]
+ spectrum[x + (int) (2 * ar1)][y -
(int) (2 *
ar2)] +
spectrum[x + (int) (2 * ar1)][y +
(int) (2 * ar2)]);
d += 20 * (spectrum[x][y - (int) (3 * ar2)] +
spectrum[x - (int) (3 * ar1)][y] +
spectrum[x][y + (int) (3 * ar2)] +
spectrum[x + (int) (3 * ar1)][y]);
e +=
1568 *
(spectrum[x - (int) ar1][y - (int) (2 * ar2)] +
spectrum[x + (int) ar1][y - (int) (2 * ar2)] +
spectrum[x - (int) ar1][y + (int) (2 * ar2)] +
spectrum[x + (int) ar1][y + (int) (2 * ar2)]);
e +=
1568 *
(spectrum[x - (int) (2 * ar1)][y - (int) ar2] +
spectrum[x + (int) (2 * ar1)][y - (int) ar2] +
spectrum[x - (int) (2 * ar1)][y + (int) ar2] +
spectrum[x + (int) (2 * ar1)][y + (int) ar2]);
e -=
1960 * (spectrum[x][y - (int) (2 * ar2)] +
spectrum[x - (int) (2 * ar1)][y] +
spectrum[x][y + (int) (2 * ar2)] +
spectrum[x + (int) (2 * ar1)][y]);
e -=
3136 * (spectrum[x - (int) ar1][y - (int) ar2] +
spectrum[x - (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y + (int) ar2] +
spectrum[x + (int) ar1][y - (int) ar2]);
e +=
3920 * (spectrum[x][y - (int) ar2] +
spectrum[x - (int) ar1][y] +
spectrum[x][y + (int) ar2] + spectrum[x +
(int)
ar1]
[y]);
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
else {
ar1 = r1 / 2, ar2 = r2 / 2;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c + 24 * array[0] - 16 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r1 - 1] +
array[r1]) -
array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
c = c - 6 * array[0] + 4 * (array[r2 - 1] +
array[r2]) -
array[2 * r2 - 1];
c = c / 36;
ar1 = r1 / 3, ar2 = r2 / 3;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = 300 * array[0] - 255 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d += 300 * array[0] - 225 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r1 - 1] +
array[r1]) -
36 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d - 120 * array[0] + 90 * (array[r2 - 1] +
array[r2]) -
36 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
6 * (array[4 * r1 / 3 - 1] + array[4 * r1 / 3]) -
array[2 * r1 - 1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
d = d + 20 * array[0] - 15 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
6 * (array[4 * r2 / 3 - 1] + array[4 * r2 / 3]) -
array[2 * r2 - 1];
d = d / 400;
ar1 = r1 / 4, ar2 = r2 / 4;
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = 3920 * array[0] - 3136 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x + (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r2 - 1];
for (j = -r1, k = 0; j < r1; j++, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) ar2];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r1 - 1];
for (j = -r2, k = 0; j < r2; j++, k++) {
array[k] =
spectrum[x - (int) ar1][y +
(int) (j * ar1 / r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e += 3920 * array[0] - 3136 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r1 - 1] +
array[r1]) -
784 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x + (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r2 - 1] +
array[r2]) -
784 * array[2 * r2 - 1];
for (j = -2 * r1, k = 0; j < 2 * r1; j += 2, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (2 *
ar2)];
} for (j = 2 * r1 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r1 - 1] +
array[r1]) -
784 * array[2 * r1 - 1];
for (j = -2 * r2, k = 0; j < 2 * r2; j += 2, k++) {
array[k] =
spectrum[x - (int) (2 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2 - 1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 1960 * array[0] + 1568 * (array[r2 - 1] +
array[r2]) -
784 * array[2 * r2 - 1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
224 * (array[4 * r1 / 3 - 1] +
array[4 * r1 / 3]) - 64 * array[2 * r1 -
1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x + (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
224 * (array[4 * r2 / 3 - 1] +
array[4 * r2 / 3]) - 64 * array[2 * r2 -
1];
for (j = -3 * r1, k = 0; j < 3 * r1; j += 3, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (3 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r1 / 3 - 1] +
array[2 * r1 / 3]) +
224 * (array[4 * r1 / 3 - 1] +
array[4 * r1 / 3]) - 64 * array[2 * r1 -
1];
for (j = -3 * r2, k = 0; j < 3 * r2; j += 3, k++) {
array[k] =
spectrum[x - (int) (3 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e + 560 * array[0] -
448 * (array[2 * r2 / 3 - 1] +
array[2 * r2 / 3]) +
224 * (array[4 * r2 / 3 - 1] +
array[4 * r2 / 3]) - 64 * array[2 * r2 -
1];
for (j = -4 * r1, k = 0; j < 4 * r1; j += 4, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y -
(int) (4 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r1 / 4 - 1] +
array[2 * r1 / 4]) -
28 * (array[r1 - 1] + array[r1]) +
8 * (array[3 * r1 / 4 - 1] + array[3 * r1 / 4]) -
array[2 * r1 - 1];
for (j = -4 * r2, k = 0; j < 4 * r2; j += 4, k++) {
array[k] =
spectrum[x + (int) (4 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r2 / 4 - 1] +
array[2 * r2 / 4]) -
28 * (array[r2 - 1] + array[r2]) +
8 * (array[3 * r2 / 4 - 1] + array[3 * r2 / 4]) -
array[2 * r2 - 1];
for (j = -4 * r1, k = 0; j < 4 * r1; j += 4, k++) {
array[k] =
spectrum[x + (int) (j * ar1 / r1)][y +
(int) (4 *
ar2)];
} for (j = 2 * r1; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r1 / 4 - 1] +
array[2 * r1 / 4]) -
28 * (array[r1 - 1] + array[r1]) +
8 * (array[3 * r1 / 4 - 1] + array[3 * r1 / 4]) -
array[2 * r1 - 1];
for (j = -4 * r2, k = 0; j < 4 * r2; j += 4, k++) {
array[k] =
spectrum[x - (int) (4 * ar1)][y +
(int) (j * ar1 /
r2)];
} for (j = 2 * r2; j > 0; j--) {
for (k = 0; k < j; k++) {
if (array[k + 1] > array[k]) {
p = array[k];
array[k] = array[k + 1];
array[k + 1] = p;
}
}
}
e = e - 70 * array[0] + 56 * (array[2 * r2 / 4 - 1] +
array[2 * r2 / 4]) -
28 * (array[r2 - 1] + array[r2]) +
8 * (array[3 * r2 / 4 - 1] + array[3 * r2 / 4]) -
array[2 * r2 - 1];
e = e / 4900;
if (b < e)
b = e;
if (b < d)
b = d;
if (b < c)
b = c;
if (b < a && b > 0)
a = b;
}
working_space[x][y] = a;
}
}
for (y = r2; y < sizey - r2; y++) {
for (x = r1; x < sizex - r1; x++) {
spectrum[x][y] = working_space[x][y];
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
const char *TSpectrum2::Smooth2(float **spectrum, int sizex, int sizey,
int pointsx, int pointsy)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL SPECTRUM SMOOTHING FUNCTION */
/* */
/* This function calculates smoothed spectrum from source spectrum. */
/* The result is placed in the array pointed by spectrum pointer. */
/* */
/* Function parameters: */
/* spectrum-pointer to the array of source spectrum */
/* sizex-x length of spectrum */
/* sizey-y length of spectrum */
/* points-width of smoothing window */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, ix, iy, jx, jy, kx, ky;
double a, b, c, d;
float coef[7][8] = {
{2, 1, 0, 0, 0, 0, 0, 0},
{17, 12, -3, 0, 0, 0, 0, 0},
{7, 6, 3, -2, 0, 0, 0, 0},
{59, 54, 39, 14, -21, 0, 0, 0},
{89, 84, 69, 44, 9, -36, 0, 0},
{25, 24, 21, 16, 9, 0, -11, 0},
{167, 162, 147, 122, 87, 42, -13, -78}
};
float men[7] = { 4, 35, 21, 231, 429, 143, 1105 };
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (pointsx < 3 || pointsx > 15 || pointsx % 2 == 0 || pointsy < 3
|| pointsy > 15 || pointsy % 2 == 0)
return ("Incorrect Number of Smoothing Points");
float **working_space = new float *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new float[sizey];
kx = pointsx / 2 - 1;
ky = pointsy / 2 - 1;
b = men[kx] * men[ky];
for (ix = 0; ix < sizex; ix++) {
for (iy = 0; iy < sizey; iy++) {
a = 0;
for (jx = ix - pointsx / 2; jx <= ix + pointsx / 2; jx++) {
for (jy = iy - pointsy / 2; jy <= iy + pointsy / 2; jy++) {
if (jx >= 0 && jx < sizex && jy >= 0 && jy < sizey) {
d = spectrum[jx][jy];
c = coef[kx][TMath::Abs(ix - jx)] *
coef[ky][TMath::Abs(iy - jy)];
a += c * d;
}
}
}
working_space[ix][iy] = a / b;
}
}
for (ix = 0; ix < sizex; ix++) {
for (iy = 0; iy < sizey; iy++) {
spectrum[ix][iy] = working_space[ix][iy];
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
double TSpectrum2::Lls(double a)
{
/////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// LLS operator. It calculates log(log(sqrt(a+1))) value of a. //
// //
/////////////////////////////////////////////////////////////////////////////
if (a < 0)
a = 0;
a = TMath::Sqrt(a + 1.0);
a = TMath::Log(a + 1.0);
a = TMath::Log(a + 1.0);
return (a);
}
//______________________________________________________________________________________________________________________________
const char *TSpectrum2::Deconvolution2(float **source, const float **resp,
int sizex, int sizey,
int number_of_iterations)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL DECONVOLUTION FUNCTION */
/* This function calculates deconvolution from source spectrum */
/* according to response spectrum */
/* The result is placed in the matrix pointed by source pointer. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum */
/* resp-pointer to the matrix of response spectrum */
/* sizex-x length of source and response spectra */
/* sizey-y length of source and response spectra */
/* number_of_iterations, for details we refer to manual */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, j, k, lhx, lhy, i1, i2, j1, j2, k1, k2, lindex, i1min, i1max,
i2min, i2max, j1min, j1max, j2min, j2max, positx = 0, posity = 0;
double lda, ldb, ldc, area, maximum = 0;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations <= 0)
return "Number of iterations must be positive";
double **working_space = new double *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new double[21 * sizey];
area = 0;
lhx = -1, lhy = -1;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
lda = resp[i][j];
if (lda != 0) {
if ((i + 1) > lhx)
lhx = i + 1;
if ((j + 1) > lhy)
lhy = j + 1;
}
working_space[i][j] = lda;
area = area + lda;
if (lda > maximum) {
maximum = lda;
positx = i, posity = j;
}
}
}
if (lhx == -1 || lhy == -1)
return ("ZERO RESPONSE DATA");
/*calculate at*y and write into p*/
i2min = -lhy + 1, i2max = sizey + lhy - 2;
i1min = -lhx + 1, i1max = sizex + lhx - 2;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
for (j2 = 0; j2 <= (lhy - 1); j2++) {
for (j1 = 0; j1 <= (lhx - 1); j1++) {
k2 = i2 + j2, k1 = i1 + j1;
if (k2 >= 0 && k2 < sizey && k1 >= 0 && k1 < sizex) {
lda = working_space[j1][j2];
ldb = source[k1][k2];
ldc = ldc + lda * ldb;
}
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + sizey +
k * 3 * sizey] = ldc;
}
}
/*calculate matrix b=ht*h*/
i1min = -(lhx - 1), i1max = lhx - 1;
i2min = -(lhy - 1), i2max = lhy - 1;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
j2min = -i2;
if (j2min < 0)
j2min = 0;
j2max = lhy - 1 - i2;
if (j2max > lhy - 1)
j2max = lhy - 1;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = -i1;
if (j1min < 0)
j1min = 0;
j1max = lhx - 1 - i1;
if (j1max > lhx - 1)
j1max = lhx - 1;
for (j1 = j1min; j1 <= j1max; j1++) {
lda = working_space[j1][j2];
ldb = working_space[i1 + j1][i2 + j2];
ldc = ldc + lda * ldb;
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + 10 * sizey +
k * 2 * sizey] = ldc;
}
}
/*calculate ht*h*ht*y and write into ygold*/
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++) {
ldc = 0;
j2min = i2min, j2max = i2max;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = i1min, j1max = i1max;
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
lda =
working_space[(j1 + sizex) % sizex][j2 + sizey +
10 * sizey +
k * 2 * sizey];
k = (i1 + j1 + sizex) / sizex;
ldb =
working_space[(i1 + j1 + sizex) % sizex][i2 + j2 +
sizey + sizey +
k * 3 * sizey];
ldc = ldc + lda * ldb;
}
}
working_space[i1][i2 + 14 * sizey] = ldc;
}
}
/*calculate matrix cc*/
i2 = 2 * lhy - 2;
if (i2 > sizey)
i2 = sizey;
i2min = -i2, i2max = i2;
i1 = 2 * lhx - 2;
if (i1 > sizex)
i1 = sizex;
i1min = -i1, i1max = i1;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
j2min = -lhy + i2 + 1;
if (j2min < -lhy + 1)
j2min = -lhy + 1;
j2max = lhy + i2 - 1;
if (j2max > lhy - 1)
j2max = lhy - 1;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = -lhx + i1 + 1;
if (j1min < -lhx + 1)
j1min = -lhx + 1;
j1max = lhx + i1 - 1;
if (j1max > lhx - 1)
j1max = lhx - 1;
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
lda =
working_space[(j1 + sizex) % sizex][j2 + sizey +
10 * sizey +
k * 2 * sizey];
k = (j1 - i1 + sizex) / sizex;
ldb =
working_space[(j1 - i1 + sizex) % sizex][j2 - i2 +
sizey +
10 * sizey +
k * 2 * sizey];
ldc = ldc + lda * ldb;
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + 15 * sizey +
k * 2 * sizey] = ldc;
}
}
/*initialization in x1 matrix*/
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++) {
working_space[i1][i2 + 19 * sizey] = 1;
working_space[i1][i2 + 20 * sizey] = 0;
}
}
/***START OF ITERATIONS***/
for (lindex = 0; lindex < number_of_iterations; lindex++) {
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++) {
lda = working_space[i1][i2 + 19 * sizey];
ldc = working_space[i1][i2 + 14 * sizey];
if (lda > 0.000001 && ldc > 0.000001) {
ldb = 0;
j2min = i2;
if (j2min > 2 * lhy - 2)
j2min = 2 * lhy - 2;
j2min = -j2min;
j2max = sizey - i2 - 1;
if (j2max > 2 * lhy - 2)
j2max = 2 * lhy - 2;
j1min = i1;
if (j1min > 2 * lhx - 2)
j1min = 2 * lhx - 2;
j1min = -j1min;
j1max = sizex - i1 - 1;
if (j1max > 2 * lhx - 2)
j1max = 2 * lhx - 2;
for (j2 = j2min; j2 <= j2max; j2++) {
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
ldc =
working_space[(j1 + sizex) % sizex][j2 + sizey +
15 * sizey +
k * 2 *
sizey];
lda = working_space[i1 + j1][i2 + j2 + 19 * sizey];
ldb = ldb + lda * ldc;
}
}
lda = working_space[i1][i2 + 19 * sizey];
ldc = working_space[i1][i2 + 14 * sizey];
if (ldc * lda != 0 && ldb != 0) {
lda = lda * ldc / ldb;
}
else
lda = 0;
working_space[i1][i2 + 20 * sizey] = lda;
}
}
}
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++)
working_space[i1][i2 + 19 * sizey] =
working_space[i1][i2 + 20 * sizey];
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++)
source[(i + positx) % sizex][(j + posity) % sizey] =
area * working_space[i][j + 19 * sizey];
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//____________________________________________________________________________
void TSpectrum2::DecFourier2(double *working_space, int num, int iter,
int inv)
{
//////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates Fourier deconvolution using in-place algorithm.//
// It calculates Fourier transform of the data in working space. //
// Function parameters: //
// -working_space-pointer of source data. It is replaced by result //
// -num-size of vector //
// -iter-number of iterations //
// -inv-1-forward transform, 2-inverse transform //
// //
//////////////////////////////////////////////////////////////////////////////
int nxp2, nxp, i, j, k, m, mxp, j1, j2, n1, n2, it;
long double a, b, c, d, sign, wpwr, arg, wr, wi, tr, ti, pi =
3.14159265358979323846;
long double val1, val2, val3, val4;
sign = -1;
if (inv == 2)
sign = 1;
nxp2 = num;
for (it = 1; it <= iter; it++) {
nxp = nxp2;
nxp2 = nxp / 2;
a = nxp2;
wpwr = pi / a;
for (m = 1; m <= nxp2; m++) {
a = m - 1;
arg = a * wpwr;
wr = TMath::Cos(arg);
wi = sign * TMath::Sin(arg);
for (mxp = nxp; mxp <= num; mxp += nxp) {
j1 = mxp - nxp + m;
j2 = j1 + nxp2;
val1 = working_space[j1 - 1];
val2 = working_space[j2 - 1];
val3 = working_space[num + j1 - 1];
val4 = working_space[num + j2 - 1];
a = val1;
b = val2;
c = val3;
d = val4;
tr = a - b;
ti = c - d;
a = a + b;
working_space[j1 - 1] = a;
c = c + d;
working_space[num + j1 - 1] = c;
a = tr * wr - ti * wi;
working_space[j2 - 1] = a;
a = ti * wr + tr * wi;
working_space[num + j2 - 1] = a;
}
}
}
n2 = num / 2;
n1 = num - 1;
j = 1;
for (i = 1; i <= n1; i++) {
if (i < j) {
val1 = working_space[j - 1];
val2 = working_space[num + j - 1];
val3 = working_space[i - 1];
val4 = working_space[num + i - 1];
working_space[i - 1] = val1;
working_space[num + i - 1] = val2;
working_space[j - 1] = val3;
working_space[num + j - 1] = val4;
}
k = n2;
for (; k < j;) {
j = j - k;
k = k / 2;
}
j = j + k;
}
if (inv == 2) {
a = num;
for (i = 0; i < num; i++) {
working_space[i] /= a;
working_space[i + num] /= a;
}
}
return;
}
const char *TSpectrum2::Deconvolution2HighResolution(float **source,
const float **resp,
int sizex,
int sizey,
int
number_of_iterations,
int
number_of_repetitions,
double boost)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL HIGH RESOLUTION DECONVOLUTION FUNCTION */
/* This function calculates deconvolution from source spectrum */
/* according to response spectrum */
/* The result is placed in the matrix pointed by source pointer. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum */
/* resp-pointer to the matrix of response spectrum */
/* sizex-x length of source and response spectra */
/* sizey-y length of source and response spectra */
/* number_of_iterations, for details we refer to manual */
/* number_of_repetitions, for details we refer to manual */
/* boost, boosting factor, for details we refer to manual */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, j, k, lhx, lhy, i1, i2, j1, j2, k1, k2, lindex, i1min, i1max,
i2min, i2max, j1min, j1max, j2min, j2max, positx = 0, posity =
0, iterx, itery, repet;
double lda, ldb, ldc, area, maximum = 0, a, b, c, d;
double ws[8192];
if (sizex > 4096 || sizey > 4096)
return ("Maximum Dimension is 4096");
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (number_of_iterations <= 0)
return "Number of iterations must be positive";
if (number_of_repetitions <= 0)
return "Number of repetitions must be positive";
if (boost <= 0)
return ("Boosting Factor Must be Positive Number");
double **working_space = new double *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new double[22 * sizey];
//////////////////////*Fourier deconvolution*///////////////////////////
for (i = sizex, iterx = 0, j = 1; i > 1;) {
iterx += 1;
i = i / 2;
j = j * 2;
}
if (j != sizex)
return ("SIZE MUST BE POWER OF 2");
for (i = sizey, itery = 0, j = 1; i > 1;) {
itery += 1;
i = i / 2;
j = j * 2;
}
if (j != sizey)
return ("SIZE MUST BE POWER OF 2");
//read response matrix
area = 0;
lhx = -1, lhy = -1;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
lda = resp[i][j];
if (lda != 0) {
if ((i + 1) > lhx)
lhx = i + 1;
if ((j + 1) > lhy)
lhy = j + 1;
}
working_space[i][j] = lda;
area = area + lda;
if (lda > maximum) {
maximum = lda;
positx = i, posity = j;
}
}
}
if (lhx == -1 || lhy == -1)
return ("ZERO RESPONSE DATA");
//forward transform of response
for (j = 0; j < sizey; j++) {
for (i = 0; i < sizex; i++) {
ws[i] = working_space[i][j];
ws[sizex + i] = 0;
}
DecFourier2(ws, sizex, iterx, 1);
for (i = 0; i < sizex; i++) {
working_space[i][j] = ws[i];
working_space[i][j + sizey] = ws[i + sizex];
}
}
for (j = 0; j < sizex; j++) {
for (i = 0; i < sizey; i++) {
ws[i] = working_space[j][i];
ws[i + sizey] = working_space[j][i + sizey];
}
DecFourier2(ws, sizey, itery, 1);
for (i = 0; i < sizey; i++) {
working_space[j][i] = ws[i];
working_space[j][i + sizey] = ws[i + sizey];
}
}
//read source matrix
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j + 2 * sizey] = source[i][j];
}
}
//forward transform of source
for (j = 0; j < sizey; j++) {
for (i = 0; i < sizex; i++) {
ws[i] = working_space[i][j + 2 * sizey];
ws[sizex + i] = 0;
}
DecFourier2(ws, sizex, iterx, 1);
for (i = 0; i < sizex; i++) {
working_space[i][j + 2 * sizey] = ws[i];
working_space[i][j + 3 * sizey] = ws[i + sizex];
}
}
for (j = 0; j < sizex; j++) {
for (i = 0; i < sizey; i++) {
ws[i] = working_space[j][i + 2 * sizey];
ws[i + sizey] = working_space[j][i + 3 * sizey];
}
DecFourier2(ws, sizey, itery, 1);
for (i = 0; i < sizey; i++) {
working_space[j][i + 2 * sizey] = ws[i];
working_space[j][i + 3 * sizey] = ws[i + sizey];
}
}
//division of complex numbers of transformed source by response
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
a = working_space[i][j + 2 * sizey];
b = working_space[i][j + 3 * sizey];
c = working_space[i][j];
d = working_space[i][j + sizey];
working_space[i][j] = (a * c + b * d) / (c * c + d * d);
working_space[i][j + sizey] = (b * c - a * d) / (c * c + d * d);
}
}
//inverse transform of result
for (j = 0; j < sizex; j++) {
for (i = 0; i < sizey; i++) {
ws[i] = working_space[j][i];
ws[i + sizey] = working_space[j][i + sizey];
}
DecFourier2(ws, sizey, itery, 2);
for (i = 0; i < sizey; i++) {
working_space[j][i] = ws[i];
working_space[j][i + sizey] = ws[i + sizey];
}
}
for (j = 0; j < sizey; j++) {
for (i = 0; i < sizex; i++) {
ws[i] = working_space[i][j];
ws[sizex + i] = working_space[i][j + sizey];
}
DecFourier2(ws, sizex, iterx, 2);
for (i = 0; i < sizex; i++) {
working_space[i][j] = ws[i];
working_space[i][j + sizey] = ws[i + sizex];
}
}
a = 0;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
a += working_space[i][j];
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j] /= a;
working_space[i][j] *= area;
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
b = working_space[i][j];
working_space[i][j + 21 * sizey] = Lls(b);
}
}
////////////////////End of Fourier deconvolution///////////////////////
//read response matrix once more
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j] = resp[i][j];
}
}
/*calculate at*y and write into p*/
i2min = -lhy + 1, i2max = sizey + lhy - 2;
i1min = -lhx + 1, i1max = sizex + lhx - 2;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
for (j2 = 0; j2 <= (lhy - 1); j2++) {
for (j1 = 0; j1 <= (lhx - 1); j1++) {
k2 = i2 + j2, k1 = i1 + j1;
if (k2 >= 0 && k2 < sizey && k1 >= 0 && k1 < sizex) {
lda = working_space[j1][j2];
ldb = source[k1][k2];
ldc = ldc + lda * ldb;
}
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + sizey +
k * 3 * sizey] = ldc;
}
}
/*calculate matrix b=ht*h*/
i1min = -(lhx - 1), i1max = lhx - 1;
i2min = -(lhy - 1), i2max = lhy - 1;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
j2min = -i2;
if (j2min < 0)
j2min = 0;
j2max = lhy - 1 - i2;
if (j2max > lhy - 1)
j2max = lhy - 1;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = -i1;
if (j1min < 0)
j1min = 0;
j1max = lhx - 1 - i1;
if (j1max > lhx - 1)
j1max = lhx - 1;
for (j1 = j1min; j1 <= j1max; j1++) {
lda = working_space[j1][j2];
ldb = working_space[i1 + j1][i2 + j2];
ldc = ldc + lda * ldb;
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + 10 * sizey +
k * 2 * sizey] = ldc;
}
}
/*calculate ht*h*ht*y and write into ygold*/
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++) {
ldc = 0;
j2min = i2min, j2max = i2max;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = i1min, j1max = i1max;
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
lda =
working_space[(j1 + sizex) % sizex][j2 + sizey +
10 * sizey +
k * 2 * sizey];
k = (i1 + j1 + sizex) / sizex;
ldb =
working_space[(i1 + j1 + sizex) % sizex][i2 + j2 +
sizey + sizey +
k * 3 * sizey];
ldc = ldc + lda * ldb;
}
}
working_space[i1][i2 + 14 * sizey] = ldc;
}
}
/*calculate matrix cc*/
i2 = 2 * lhy - 2;
if (i2 > sizey)
i2 = sizey;
i2min = -i2, i2max = i2;
i1 = 2 * lhx - 2;
if (i1 > sizex)
i1 = sizex;
i1min = -i1, i1max = i1;
for (i2 = i2min; i2 <= i2max; i2++) {
for (i1 = i1min; i1 <= i1max; i1++) {
ldc = 0;
j2min = -lhy + i2 + 1;
if (j2min < -lhy + 1)
j2min = -lhy + 1;
j2max = lhy + i2 - 1;
if (j2max > lhy - 1)
j2max = lhy - 1;
for (j2 = j2min; j2 <= j2max; j2++) {
j1min = -lhx + i1 + 1;
if (j1min < -lhx + 1)
j1min = -lhx + 1;
j1max = lhx + i1 - 1;
if (j1max > lhx - 1)
j1max = lhx - 1;
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
lda =
working_space[(j1 + sizex) % sizex][j2 + sizey +
10 * sizey +
k * 2 * sizey];
k = (j1 - i1 + sizex) / sizex;
ldb =
working_space[(j1 - i1 + sizex) % sizex][j2 - i2 +
sizey +
10 * sizey +
k * 2 * sizey];
ldc = ldc + lda * ldb;
}
}
k = (i1 + sizex) / sizex;
working_space[(i1 + sizex) % sizex][i2 + sizey + 15 * sizey +
k * 2 * sizey] = ldc;
}
}
/*initialization in x1 matrix*/
for (i = 0, a = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j + 19 * sizey] =
working_space[i][j + 21 * sizey];
a += working_space[i][j + 21 * sizey];
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j + 19 * sizey] =
working_space[i][j + 19 * sizey] / a;
working_space[i][j + 20 * sizey] = 0;
}
}
/***START OF ITERATIONS***/
for (repet = 0; repet < number_of_repetitions; repet++) {
if (repet != 0) {
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j + 19 * sizey] =
TMath::Power(working_space[i][j + 19 * sizey], boost);
}
}
}
for (lindex = 0; lindex < number_of_iterations; lindex++) {
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++) {
lda = working_space[i1][i2 + 19 * sizey];
ldc = working_space[i1][i2 + 14 * sizey];
ldb = 0;
j2min = i2;
if (j2min > 2 * lhy - 2)
j2min = 2 * lhy - 2;
j2min = -j2min;
j2max = sizey - i2 - 1;
if (j2max > 2 * lhy - 2)
j2max = 2 * lhy - 2;
j1min = i1;
if (j1min > 2 * lhx - 2)
j1min = 2 * lhx - 2;
j1min = -j1min;
j1max = sizex - i1 - 1;
if (j1max > 2 * lhx - 2)
j1max = 2 * lhx - 2;
for (j2 = j2min; j2 <= j2max; j2++) {
for (j1 = j1min; j1 <= j1max; j1++) {
k = (j1 + sizex) / sizex;
ldc =
working_space[(j1 + sizex) % sizex][j2 + sizey +
15 * sizey +
k * 2 *
sizey];
lda = working_space[i1 + j1][i2 + j2 + 19 * sizey];
ldb = ldb + lda * ldc;
}
}
lda = working_space[i1][i2 + 19 * sizey];
ldc = working_space[i1][i2 + 14 * sizey];
if (ldc * lda != 0 && ldb != 0) {
lda = lda * ldc / ldb;
}
else
lda = 0;
working_space[i1][i2 + 20 * sizey] = lda;
}
}
for (i2 = 0; i2 < sizey; i2++) {
for (i1 = 0; i1 < sizex; i1++)
working_space[i1][i2 + 19 * sizey] =
working_space[i1][i2 + 20 * sizey];
}
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++)
source[(i + positx) % sizex][(j + posity) % sizey] =
area * working_space[i][j + 19 * sizey];
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
return 0;
}
//_______________________________________________________________________________
Int_t TSpectrum2::PeakEvaluate(const double *temp, int size, int xmax,
double xmin, bool markov)
{
//////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion looks for peaks in the temp vector. //
// It calculates Fourier transform of the data in working space. //
// Function parameters: //
// -temp-pointer of source data. //
// -size-size of vector //
// -xmin-low limit of search //
// -xmax-upper limit of search //
// -markov-determines Markov estimate //
// //
//////////////////////////////////////////////////////////////////////////////
int i, i1, i2, i3, i4, i5, n1, n2, n3, stav, peak_index;
double a, b, s, f, si4, fi4, suma, sumai, sold, fold = 0;
i1 = i2 = i3 = i4 = 0;
si4 = fi4 = 0;
stav = 1;
peak_index = 0;
sold = 1000000.0;
suma = 0;
sumai = 0;
for (i = 0; i < xmax; i++) {
s = temp[i], f = temp[i + size];
if ((s < 0) && (stav >= 2) && (stav <= 5)) {
a = i + xmin;
a *= s;
suma += s;
sumai += a;
}
if ((stav == 1) && (s > f)) {
stav = 2;
i1 = i;
}
else if ((stav == 2) && (s <= f)) {
stav = 3;
i2 = i;
}
else if (stav == 3) {
if (s <= 0) {
stav = 4;
i3 = i;
}
}
else if ((stav == 4) && (s >= sold)) {
si4 = sold;
fi4 = fold;
stav = 5;
i4 = i - 1;
}
else if ((stav == 5) && (s >= 0)) {
stav = 6;
i5 = i;
if (si4 == 0)
stav = 0;
else {
n1 = i5 - i3 + 1;
a = n1 + 2;
a = fi4 * a / (2. * si4) + 1 / 2.;
a = TMath::Abs(a);
n2 = (int) a;
a = n1 - 4;
if (a < 0)
a = 0;
a = a * (1 - 2. * (fi4 / si4)) + 1 / 2.;
a = TMath::Abs(a);
n3 = (int) (a / fResolution);
a = TMath::Abs(si4);
if (markov == false) {
if (a <= (2.0 * fi4))
stav = 0;
if (n2 >= 1) {
if ((i3 - i2 - 1) > n2)
stav = 0;
}
else {
if ((i3 - i2 - 1) > 1)
stav = 0;
}
if ((i2 - i1 + 1) < n3)
stav = 0;
n1 = i5 - i3 + 1;
a = n1 + 2;
a = fi4 * a / (2. * si4) + 1 / 2.;
a = TMath::Abs(a);
n2 = (int) a;
a = n1 - 2;
a = a * (1 - 2. * (fi4 / si4)) + 1 / 2.;
a = TMath::Abs(a);
n3 = (int) (a / fResolution);
a = TMath::Abs(si4);
if (a <= (2. * fi4))
stav = 0;
if (n2 >= 1) {
if ((i3 - i2 - 1) > n2)
stav = 0;
}
else {
if ((i3 - i2 - 1) > 1)
stav = 0;
}
if (temp[0] < temp[size]) {
if ((i2 - i1 + 1) < n3)
stav = 0;
}
}
}
if (stav != 0) {
if (suma != 0)
b = sumai / suma;
else
b = i4 + xmin;
if (peak_index >= fMaxPeaks)
return (-1);
else {
fPosition[peak_index] = b;
peak_index += 1;
}
}
stav = 1;
suma = 0;
sumai = 0;
i = i4;
}
sold = s;
fold = f;
}
fNPeaks = peak_index;
return fNPeaks;
}
//______________________________________________________________________________
Int_t TSpectrum2::Search2(float **source, int sizex, int sizey,
double sigma)
{
/////////////////////////////////////////////////////////////////////////////
// TWO-DIMENSIONAL PEAK SEARCH FUNCTION //
// This function searches for peaks in source spectrum //
// The number of found peaks and their positions are written into //
// the members fNPeaks, fPositionX and fPositionY. //
// //
// Function parameters: //
// source: pointer to the vector of source spectrum //
// sizex: x length of source spectrum //
// sizey: y length of source spectrum //
// sigma: sigma of searched peaks, for details we refer to manual //
// //
/////////////////////////////////////////////////////////////////////////////
// if (sizex <=0 || sizey <= 0) return -1;
//start of checking (has been inserted up to end of checking)
double pocet_sigma = 5;
if (sizex <= 0 || sizey <= 0) {
Error("Search2", "Wrong size, must positive");
return 0;
}
if (sigma <= 0) {
Error("Search2", "Invalid sigma, must be positive");
return 0;
}
int j = (int) (pocet_sigma * sigma + 0.5);
if (j >= PEAK_WINDOW / 2) {
Error("Search2", "Too large sigma");
return 0;
}
//end of checking
// working_space-pointer to the working matrix
// (its size must be sizex*2*sizey of source spectrum)
// working_vector_x-pointer to the working vector x
// (its size must be 2*sizex of source spectrum)
// working_vector_y-pointer to the working vector y
// (its size must be 2*sizey of source spectrum)
double **working_space = new double *[sizex];
double *working_vector_x = new double[2 * sizex];
double *working_vector_y = new double[2 * sizey];
double a, b, s, f, dpeakx, dpeaky, dxmin, dxmax, dymin, dymax,
filter[PEAK_WINDOW], norma, val, val1, val2, val3, val4, val5, val6,
val7, val8;
int x, y, n, priz, polx, poly, peak_index =
0, i, li, lj, lmin, lmax, xmin, xmax, ymin, ymax;
for (i = 0; i < sizex; i++)
working_space[i] = new double[2 * sizey];
polx = poly = 0;
for (j = 0; j < sizey; j++) {
for (i = 0; i < sizex; i++) {
working_space[i][j] = 0;
working_space[i][j + sizey] = 0;
}
}
for (i = 0; i < PEAK_WINDOW; i++)
filter[i] = 0;
for (i = -j; i <= j; i++) {
a = i;
a = -a * a;
b = 2.0 * sigma * sigma;
a = a / b;
a = exp(a);
s = i;
s = s * s;
s = s - sigma * sigma;
s = s / (sigma * sigma * sigma * sigma);
s = s * a;
filter[PEAK_WINDOW / 2 + i] = s;
}
norma = 0;
for (i = 0; i < PEAK_WINDOW; i++) {
norma = norma + TMath::Abs(filter[i]);
}
for (i = 0; i < PEAK_WINDOW; i++) {
filter[i] = filter[i] / norma;
}
a = pocet_sigma * sigma + 0.5;
i = (int) a;
ymin = i;
ymax = sizey - i;
xmin = i;
xmax = sizex - i;
lmin = PEAK_WINDOW / 2 - i;
lmax = PEAK_WINDOW / 2 + i;
for (i = xmin; i < xmax; i++) {
for (j = ymin; j < ymax; j++) {
s = 0;
f = 0;
for (li = lmin; li <= lmax; li++) {
for (lj = lmin; lj <= lmax; lj++) {
a = source[j + lj - PEAK_WINDOW / 2][i + li -
PEAK_WINDOW / 2];
s += a * filter[li] * filter[lj];
f += a * filter[li] * filter[li] * filter[lj] * filter[lj];
}
}
f = TMath::Sqrt(f);
working_space[i][j] = s;
working_space[i][j + sizey] = f;
}
}
for (x = xmin; x < xmax; x++) {
for (y = ymin + 1; y < ymax; y++) {
val = working_space[x][y];
val1 = working_space[x - 1][y - 1];
if (val >= val1) {
val2 = working_space[x][y - 1];
if (val >= val2) {
val3 = working_space[x + 1][y - 1];
if (val >= val3) {
val4 = working_space[x - 1][y];
if (val >= val4) {
val5 = working_space[x + 1][y];
if (val >= val5) {
val6 = working_space[x - 1][y + 1];
if (val >= val6) {
val7 = working_space[x][y + 1];
if (val >= val7) {
val8 = working_space[x + 1][y + 1];
if (val >= val8) {
if (val != val1 || val != val2
|| val != val3 || val != val4
|| val != val5 || val != val6
|| val != val7 || val != val8) {
priz = 0;
for (j = 0;
(j < peak_index) && (priz == 0);
j++) {
dxmin = fPositionX[j] - sigma;
dxmax = fPositionX[j] + sigma;
dymin = fPositionY[j] - sigma;
dymax = fPositionY[j] + sigma;
if ((x >= dxmin) && (x <= dxmax)
&& (y >= dymin)
&& (y <= dymax))
priz = 1;
}
if (priz == 0) {
s = 0;
f = 0;
for (li = lmin; li <= lmax; li++) {
a = source[x][y + li -
PEAK_WINDOW / 2];
s += a * filter[li];
f +=
a * filter[li] * filter[li];
}
f = TMath::Sqrt(f);
if (s < f) {
s = 0;
f = 0;
for (li = lmin; li <= lmax;
li++) {
a = source[x + li -
PEAK_WINDOW /
2][y];
s += a * filter[li];
f +=
a * filter[li] *
filter[li];
}
f = TMath::Sqrt(f);
if (s < f) {
for (i =
x + lmin -
PEAK_WINDOW / 2;
i <=
x + lmax -
PEAK_WINDOW / 2; i++) {
working_vector_x[i - x -
lmin +
PEAK_WINDOW
/ 2] =
-working_space[i][y];
working_vector_x[i - x -
lmin +
PEAK_WINDOW
/ 2 +
sizex] =
working_space[i][y +
sizey];
}
//find peaks in y-th column
n =
PeakEvaluate
(working_vector_x, sizex,
lmax - lmin + 1,
x + lmin -
PEAK_WINDOW / 2, false);
if (n == -1) {
Warning("Search2",
"TOO MANY PEAKS IN ONE COLUMN");
return -1;
}
if (n != 0) {
val = sizex;
for (i = 0; i < n; i++) {
a = fPosition[i];
a = TMath::Abs(a - x);
if (a < val) {
val = a;
polx = i;
}
}
dpeakx = fPosition[polx];
for (i =
y + lmin -
PEAK_WINDOW / 2;
i <=
y + lmax -
PEAK_WINDOW / 2;
i++) {
working_vector_y[i -
y -
lmin +
PEAK_WINDOW
/ 2] =
-working_space[x]
[i];
working_vector_y[i -
y -
lmin +
PEAK_WINDOW
/ 2 +
sizey]
=
working_space[x][i +
sizey];
}
//find peaks in x-th row
n =
PeakEvaluate
(working_vector_y,
sizey,
lmax - lmin + 1,
y + lmin -
PEAK_WINDOW / 2,
false);
if (n == -1) {
Warning("Search2",
"TOO MANY PEAKS IN ONE ROW");
return -1;
}
if (n != 0) {
val = sizey;
for (i = 0; i < n; i++) {
a = fPosition[i];
a = TMath::Abs(a -
y);
if (a < val) {
val = a;
poly = i;
}
}
dpeaky =
fPosition[poly];
if (peak_index <
fMaxPeaks) {
fPositionX
[peak_index] =
dpeakx;
fPositionY
[peak_index] =
dpeaky;
peak_index += 1;
} else {
Warning("Search2",
"PEAK BUFFER FULL");
return 0;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
delete[]working_vector_x;
delete[]working_vector_y;
fNPeaks = peak_index;
return fNPeaks;
}
//____________________________________________________________________________
Int_t TSpectrum2::Search2General(float **source, int sizex, int sizey,
double sigma, double threshold,
bool markov, int aver_window)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL PEAK SEARCH FUNCTION */
/* This function searches for peaks in source spectrum */
/* The number of found peaks and their positions are written into */
/* structure pointed by two_dim_peak structure pointer. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum */
/* sizex-x length of source spectrum */
/* sizey-y length of source spectrum */
/* sigma-sigma of searched peaks, for details we refer to manual */
/* threshold-threshold value for selected peaks */
/* markov-logical variable, if it is true, first the source spectrum */
/* is replaced by new spectrum calculated using Markov */
/* chains method. */
/* aver_window-averanging window of searched peaks, for details */
/* we refer to manual (applies only for Markov method) */
/* */
/////////////////////////////////////////////////////////////////////////////
int xmin = 0, xmax = sizex, ymin = 0, ymax = sizey, i, j, l, peak_index = 0;
double a, b, maxch, plocha = 0;
double nom, nip, nim, sp, sm, spx, spy, smx, smy;
double s, f, dpeakx, dpeaky, dxmin, dxmax, dymin, dymax,filter[PEAK_WINDOW], norma, val, val1, val2, val3, val4, val5, val6, val7, val8;
int x, y, priz, li, lj, lmin, lmax;
double s4, f4, norma4, filter4[PEAK_WINDOW];
double s6, f6, norma6, filter6[PEAK_WINDOW], s6two;
double pocet_sigma=3, suma, sumai, maxamp;
if (sizex <= 0 || sizey <= 0) {
Error("Search2General", "Wrong size, must be positive");
return 0;
}
if (sigma < 0) {
Error("Search2General", "Invalid sigma, must be positive");
return 0;
}
if (threshold <= 1) {
Error("Search2General", "Invalid threshold, must be greater than 1");
return 0;
}
j = (int) (pocet_sigma * sigma + 0.5);
if (j >= PEAK_WINDOW / 2) {
Error("Search2General", "Too large sigma");
return 0;
}
if (markov == true) {
if (aver_window <= 0) {
Error("Search2General", "AVERAGING WINDOW, MUST BE POSITIVE");
return 0;
}
xmin = aver_window;
xmax = sizex - aver_window;
ymin = aver_window;
ymax = sizey - aver_window;
if (xmax <= xmin || ymax <= ymin) {
Error("Search2General", "TOO LARGE AVERAGING WINDOW");
return 0;
}
}
double **working_space = new double *[sizex];
for (i = 0; i < sizex; i++)
working_space[i] = new double[3 * sizey];
for (j = 0; j < sizey; j++) {
for (i = 0; i < sizex; i++) {
working_space[i][j] = 0;
working_space[i][j + sizey] = 0;
}
}
for (i = 0; i < PEAK_WINDOW; i++){
filter[i] = 0;
filter4[i] = 0;
filter6[i] = 0;
}
j = (int) (pocet_sigma * sigma + 0.5);
for (i = -j; i <= j; i++) {
a = i;
a = -a * a;
b = 2.0 * sigma * sigma;
a = a / b;
a = exp(a);
s = i;
s = s * s;
s = s - sigma * sigma;
s = s / (sigma * sigma * sigma * sigma);
s = s * a;
filter[PEAK_WINDOW / 2 + i] = s;
b = i;
s = (b * b * b * b - 6 * b * b * sigma * sigma + 3 * sigma * sigma * sigma * sigma) / (sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma);
s = s * a;
filter4[PEAK_WINDOW / 2 + i]=s;
s = (b * b * b * b * b * b - 15 * b * b * b * b * sigma * sigma + 45 * b * b * sigma * sigma * sigma * sigma - 15 * sigma * sigma * sigma * sigma * sigma * sigma) / (sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma * sigma);
s = s * a;
filter6[PEAK_WINDOW / 2 + i]=s;
}
norma = 0,norma4 = 0,norma6 = 0;
for (i = 0; i < PEAK_WINDOW; i++) {
norma = norma + TMath::Abs(filter[i]);
norma4 = norma4 + TMath::Abs(filter4[i]);
norma6 = norma6 + TMath::Abs(filter6[i]);
}
for (i = 0; i < PEAK_WINDOW; i++) {
filter[i] = filter[i] / norma;
filter4[i] = filter4[i] / norma4;
filter6[i] = filter6[i] / norma6;
}
if (markov == true) {
for (i = 0, maxch = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_space[i][j] = 0;
if (maxch < source[i][j])
maxch = source[i][j];
plocha += source[i][j];
}
}
if (maxch == 0)
return (0);
nom = 0;
working_space[xmin][ymin] = 1;
for (i = xmin; i < xmax; i++) {
nip = source[i][ymin] / maxch;
nim = source[i + 1][ymin] / maxch;
sp = 0, sm = 0;
for (l = 1; l <= aver_window; l++) {
if((i + l) > xmax)
a = source[xmax][ymin] / maxch;
else
a = source[i + l][ymin] / maxch;
b = a - nip;
if (a + nip <= 0)
a = 1;
else
a = TMath::Sqrt(a + nip);
b = b / a;
b = TMath::Exp(b);
sp = sp + b;
if(i - l + 1 < xmin)
a = source[xmin][ymin] / maxch;
else
a = source[i - l + 1][ymin] / maxch;
b = a - nim;
if (a + nim <= 0)
a = 1;
else
a = TMath::Sqrt(a + nim);
b = b / a;
b = TMath::Exp(b);
sm = sm + b;
}
a = sp / sm;
a = working_space[i + 1][ymin] = a * working_space[i][ymin];
nom = nom + a;
}
for (i = ymin; i < ymax; i++) {
nip = source[xmin][i] / maxch;
nim = source[xmin][i + 1] / maxch;
sp = 0, sm = 0;
for (l = 1; l <= aver_window; l++) {
if((i + l) > ymax)
a = source[xmin][ymax] / maxch;
else
a = source[xmin][i + l] / maxch;
b = a - nip;
if (a + nip <= 0)
a = 1;
else
a = TMath::Sqrt(a + nip);
b = b / a;
b = TMath::Exp(b);
sp = sp + b;
if(i - l + 1 < ymin)
a=source[xmin][ymin] / maxch;
else
a = source[xmin][i - l + 1] / maxch;
b = a - nim;
if (a + nim <= 0)
a = 1;
else
a = TMath::Sqrt(a + nim);
b = b / a;
b = TMath::Exp(b);
sm = sm + b;
}
a = sp / sm;
a = working_space[xmin][i + 1] = a * working_space[xmin][i];
nom = nom + a;
}
for (i = xmin; i < xmax; i++) {
for (j = ymin; j < ymax; j++) {
nip = source[i][j + 1] / maxch;
nim = source[i + 1][j + 1] / maxch;
spx = 0, smx = 0;
for (l = 1; l <= aver_window; l++) {
if(i + l > xmax)
a = source[xmax][j] / maxch;
else
a = source[i + l][j] / maxch;
b = a - nip;
if (a + nip <= 0)
a = 1;
else
a = TMath::Sqrt(a + nip);
b = b / a;
b = TMath::Exp(b);
spx = spx + b;
if(i - l + 1 < xmin)
a = source[xmin][j] / maxch;
else
a = source[i - l + 1][j] / maxch;
b = a - nim;
if (a + nim <= 0)
a = 1;
else
a = TMath::Sqrt(a + nim);
b = b / a;
b = TMath::Exp(b);
smx = smx + b;
}
spy = 0, smy = 0;
nip = source[i + 1][j] / maxch;
nim = source[i + 1][j + 1] / maxch;
for (l = 1; l <= aver_window; l++) {
if(j + l > ymax)
a = source[i][ymax] / maxch;
else
a = source[i][j + l] / maxch;
b = a - nip;
if (a + nip <= 0)
a = 1;
else
a = TMath::Sqrt(a + nip);
b = b / a;
b = TMath::Exp(b);
spy = spy + b;
if(j - l + 1 < ymin)
a = source[i][ymin] / maxch;
else
a = source[i][j - l + 1] / maxch;
b = a - nim;
if (a + nim <= 0)
a = 1;
else
a = TMath::Sqrt(a + nim);
b = b / a;
b = TMath::Exp(b);
smy = smy + b;
}
a = (spx * working_space[i][j + 1] +
spy * working_space[i + 1][j]) / (smx + smy);
working_space[i + 1][j + 1] = a;
nom = nom + a;
}
}
for (i = xmin; i <= xmax; i++) {
for (j = ymin; j <= ymax; j++) {
working_space[i][j] = working_space[i][j] / nom;
}
}
for (i = xmin; i < xmax; i++) {
for (j = ymin; j < ymax; j++) {
source[i][j] = plocha * working_space[i][j];
}
}
}
if(sigma >= 2){
a = pocet_sigma*sigma+0.5;
i = (int)a;
ymin = -i;
ymax = sizey + i;
xmin = -i;
xmax = sizex + i;
lmin = PEAK_WINDOW / 2 - i;
lmax = PEAK_WINDOW / 2 + i;
for(i = xmin,maxamp = 0;i < xmax;i++){
for(j = ymin;j < ymax;j++){
s = 0,f = 0,s6two = 0,f6 = 0,s4 = 0,f4 = 0;
for(li = lmin;li <= lmax;li++){
for(lj = lmin;lj <= lmax;lj++){
if((i + li - PEAK_WINDOW / 2) < 0){
if((j + lj - PEAK_WINDOW/2) < 0)
a = source[0][0];
else if((j + lj - PEAK_WINDOW / 2) >= sizey)
a = source[0][sizey - 1];
else
a = source[0][j + lj - PEAK_WINDOW / 2];
}
else if((i + li - PEAK_WINDOW / 2) >= sizex){
if((j + lj - PEAK_WINDOW / 2) < 0)
a = source[sizex - 1][0];
else if((j + lj - PEAK_WINDOW / 2) >= sizey)
a = source[sizex - 1][sizey - 1];
else
a = source[sizex - 1][j + lj - PEAK_WINDOW / 2];
}
else{
if((j + lj - PEAK_WINDOW / 2) < 0)
a = source[i + li - PEAK_WINDOW / 2][0];
else if((j + lj - PEAK_WINDOW / 2) >= sizey)
a = source[i + li - PEAK_WINDOW / 2][sizey - 1];
else
a = source[i + li - PEAK_WINDOW / 2][j + lj - PEAK_WINDOW / 2];
}
s += a * filter[li] * filter[lj];
f += a * filter[li] * filter[li] * filter[lj] * filter[lj];
s4 += a * filter4[li] * filter4[lj];
f4 += a * filter4[li] * filter4[li] * filter4[lj] * filter4[lj];
s6two += a * filter6[li] * filter6[lj];
f6 += a * filter6[li] * filter6[li] * filter6[lj] * filter6[lj];
}
}
f = TMath::Sqrt(f);
f4 = TMath::Sqrt(f4);
f6 = TMath::Sqrt(f6);
if(i >= 0 && i < sizex && j >= 0 && j < sizey){
working_space[i][j] = s6two;
working_space[i][j + sizey] = f6;
if(s6two > f6 && s > f && s4 > f4){
s = 0,s4 = 0,s6 = 0;
for(li = lmin;li <= lmax;li++){
if(j + li - PEAK_WINDOW / 2 < 0)
a = source[i][0];
else if(j + li - PEAK_WINDOW / 2 >= sizey)
a = source[i][sizey - 1];
else
a = source[i][j + li - PEAK_WINDOW / 2];
s += a * filter[li];
s4 += a * filter4[li];
s6 += a * filter6[li];
}
if(s < 0 && s4 > 0 && s6 < 0){
s = 0,s4 = 0,s6 = 0;
for(li = lmin;li <= lmax;li++){
if(i + li - PEAK_WINDOW / 2 < 0)
a = source[0][j];
else if(i + li - PEAK_WINDOW / 2 >= sizex)
a = source[sizex - 1][j];
else
a = source[i + li - PEAK_WINDOW / 2][j];
s += a * filter[li];
s4 += a * filter4[li];
s6 += a * filter6[li];
}
if(s < 0 && s4 > 0 && s6 < 0){
working_space[i][j + 2 * sizey] = s6two;
if(maxamp < s6two)
maxamp = s6two;
}
else
working_space[i][j + 2 * sizey] = 0;
}
else
working_space[i][j + 2 * sizey] = 0;
}
else
working_space[i][j + 2 * sizey] = 0;
}
}
}
for(x = 1;x < sizex - 1;x++){
for(y = 1;y < sizey - 1;y++){
val = working_space[x][2 * sizey + y];
val1 = working_space[x - 1][2 * sizey + y - 1];
val2 = working_space[x][2 * sizey + y - 1];
val3 = working_space[x + 1][2 * sizey + y - 1];
val4 = working_space[x - 1][2 * sizey + y];
val5 = working_space[x + 1][2 * sizey + y];
val6 = working_space[x - 1][2 * sizey + y + 1];
val7 = working_space[x][2 * sizey + y + 1];
val8 = working_space[x + 1][2 * sizey + y + 1];
if(val >= val1 && val >= val2 && val >= val3 && val >= val4 && val >= val5 && val >= val6 && val >= val7 && val >= val8 && val > maxamp/100){
if(val != val1 || val != val2 || val != val3 || val != val4 || val != val5 || val != val6 || val != val7 || val != val8){
priz=0;
for(j = 0;(j < peak_index)&&(priz == 0);j++){
//dxmin = p->positionx[j] - sigma;
//dxmax = p->positionx[j] + sigma;
//dymin = p->positiony[j] - sigma;
//dymax = p->positiony[j] + sigma;
dxmin = fPositionX[j] - sigma;
dxmax = fPositionX[j] + sigma;
dymin = fPositionY[j] - sigma;
dymax = fPositionY[j] + sigma;
if((x >= dxmin) && (x <= dxmax) && (y >= dymin) && (y <= dymax))
priz=1;
}
if(priz == 0){
suma = 0,sumai = 0;
priz = 0;
j = 0;
for(i = x;i >= 0 && priz == 0;i--){
if(working_space[i][y + 2 * sizey] > 0){
a = i;
b = working_space[i][y + 2 * sizey];
suma += b;
sumai += a*b;
j += 1;
}
else
priz=1;
}
priz = 0;
for(i = x + 1;i < sizex && priz == 0;i++){
if(working_space[i][y + 2 * sizey] > 0){
a = i;
b = working_space[i][y + 2 * sizey];
suma += b;
sumai += a * b;
j += 1;
}
else
priz=1;
}
dpeakx = sumai / suma;
suma = 0,sumai = 0;
priz = 0;
l = 0;
for(i = y;i >= 0 && priz == 0;i--){
if(working_space[x][i + 2 * sizey] > 0){
a = i;
b = working_space[x][i + 2 * sizey];
suma += b;
sumai += a * b;
l += 1;
}
else
priz=1;
}
priz = 0;
for(i = y + 1;i < sizey && priz == 0;i++){
if(working_space[x][i + 2 * sizey] > 0){
a = i;
b = working_space[x][i + 2 * sizey];
suma += b;
sumai += a * b;
l += 1;
}
else
priz = 1;
}
if(j > 2 && l > 2){
dpeaky = sumai / suma;
i = (int)(dpeakx + 0.5);
j = (int)(dpeaky + 0.5);
s = working_space[i][j];
f = working_space[i][j + sizey];
if(threshold * f < TMath::Abs(s)){
if(peak_index < fMaxPeaks){
fPositionX[peak_index] = dpeakx;
fPositionY[peak_index] = dpeaky;
peak_index += 1;
}
else{
Warning("Search2","PEAK BUFFER FULL");
return 0;
}
}
}
}
}
}
}
}
}
else{
for(x = 1;x < sizex - 1;x++){
for(y = 1;y < sizey - 1;y++){
a = (source[x - 1][y - 1] + source[x - 1][y + 1] + source[x + 1][y - 1] + source[x + 1][y + 1] - 2 * (source[x - 1][y] + source[x + 1][y] + source[x][y - 1] + source[x][y + 1]) + 4 * source[x][y]) / 16;
b = (source[x - 1][y - 1] + source[x - 1][y + 1] + source[x + 1][y - 1] + source[x + 1][y + 1] + 4 * (source[x - 1][y] + source[x + 1][y] + source[x][y - 1] + source[x][y + 1]) + 16 * source[x][y]) / 256;
b=TMath::Sqrt(b);
if(TMath::Abs(a) > (threshold * b)){
if(peak_index < fMaxPeaks){
fPositionX[peak_index] = x;
fPositionY[peak_index] = y;
peak_index += 1;
}
else{
Warning("Search2","PEAK BUFFER FULL");
return 0;
}
}
}
}
}
for (i = 0; i < sizex; i++)
delete[]working_space[i];
delete[]working_space;
fNPeaks = peak_index;
return fNPeaks;
}
//_____________________________________________________________________________
/////////////////BEGINNING OF AUXILIARY FUNCTIONS USED BY FITTING FUNCIONS//////////////////////////
double TSpectrum2::Erfc(double x)
{
//////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates error function of x. //
// //
//////////////////////////////////////////////////////////////////////////////
double da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap =
0.47047;
double a, t, c, w;
a = TMath::Abs(x);
w = 1. + dap * a;
t = 1. / w;
w = a * a;
if (w < 700)
c = exp(-w);
else {
c = 0;
}
c = c * t * (da1 + t * (da2 + t * da3));
if (x < 0)
c = 1. - c;
return (c);
}
double TSpectrum2::Derfc(double x)
{
//////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of error function of x. //
// //
//////////////////////////////////////////////////////////////////////////////
double a, t, c, w;
double da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap =
0.47047;
a = TMath::Abs(x);
w = 1. + dap * a;
t = 1. / w;
w = a * a;
if (w < 700)
c = exp(-w);
else {
c = 0;
}
c = (-1.) * dap * c * t * t * (da1 + t * (2. * da2 + t * 3. * da3)) -
2. * a * Erfc(a);
return (c);
}
double TSpectrum2::Ourpowl(double a, int pw)
{ //power function
double c;
c = 1;
if (pw > 0)
c = c * a * a;
else if (pw > 2)
c = c * a * a;
else if (pw > 4)
c = c * a * a;
else if (pw > 6)
c = c * a * a;
else if (pw > 8)
c = c * a * a;
else if (pw > 10)
c = c * a * a;
else if (pw > 12)
c = c * a * a;
return (c);
}
void TSpectrum2::StiefelInversion(double **a, int size)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates solution of the system of linear equations. //
// The matrix a should have a dimension size*(size+4) //
// The calling function should fill in the matrix, the column size should //
// contain vector y (right side of the system of equations). The result is //
// placed into size+1 column of the matrix. //
// according to sigma of peaks. //
// Function parameters: //
// -a-matrix with dimension size*(size+4) // //
// -size-number of rows of the matrix //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j, k = 0;
double sk = 0, b, lambdak, normk, normk_old = 0;
do {
normk = 0;
//calculation of rk and norm
for (i = 0; i < size; i++) {
a[i][size + 2] = -a[i][size]; //rk=-C
for (j = 0; j < size; j++) {
a[i][size + 2] += a[i][j] * a[j][size + 1]; //A*xk-C
}
normk += a[i][size + 2] * a[i][size + 2]; //calculation normk
}
//calculation of sk
if (k != 0) {
sk = normk / normk_old;
}
//calculation of uk
for (i = 0; i < size; i++) {
a[i][size + 3] = -a[i][size + 2] + sk * a[i][size + 3]; //uk=-rk+sk*uk-1
}
//calculation of lambdak
lambdak = 0;
for (i = 0; i < size; i++) {
for (j = 0, b = 0; j < size; j++) {
b += a[i][j] * a[j][size + 3]; //A*uk
}
lambdak += b * a[i][size + 3];
}
if (TMath::Abs(lambdak) > 1e-50) //computer zero
lambdak = normk / lambdak;
else
lambdak = 0;
for (i = 0; i < size; i++)
a[i][size + 1] += lambdak * a[i][size + 3]; //xk+1=xk+lambdak*uk
normk_old = normk;
k += 1;
} while (k < size && TMath::Abs(normk) > 1e-50); //computer zero
return;
}
double TSpectrum2::Shape2(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double ro, double a0, double ax,
double ay, double txy, double sxy, double tx,
double ty, double sx, double sy, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates 2D peaks shape function (see manual) //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -a0,ax,ay-bac kground coefficients //
// -txy,tx,ty, sxy,sy,sx-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
int j;
double r, p, r1, e, ex, ey, vx, s2, px, py, rx, ry, erx, ery;
vx = 0;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
p = (x - parameter[7 * j + 1]) / sigmax;
r = (y - parameter[7 * j + 2]) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
if (txy != 0) {
px = 0, py = 0;
erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * txy * px * py;
}
if (sxy != 0) {
rx = Erfc(p / s2), ry = Erfc(r / s2);
r1 += 0.5 * sxy * rx * ry;
}
vx = vx + parameter[7 * j] * r1;
}
p = (x - parameter[7 * j + 5]) / sigmax;
if (TMath::Abs(p) < 3) {
e = p * p / 2;
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
if (tx != 0) {
px = 0;
erx = Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9) {
px = exp(ex) * erx;
}
r1 += 0.5 * tx * px;
}
if (sx != 0) {
rx = Erfc(p / s2);
r1 += 0.5 * sx * rx;
}
vx = vx + parameter[7 * j + 3] * r1;
}
r = (y - parameter[7 * j + 6]) / sigmay;
if (TMath::Abs(r) < 3) {
e = r * r / 2;
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
if (ty != 0) {
py = 0;
ery = Erfc(r / s2 + 1 / (2 * by));
ey = r / (s2 * by);
if (TMath::Abs(ey) < 9) {
py = exp(ey) * ery;
}
r1 += 0.5 * ty * py;
}
if (sy != 0) {
ry = Erfc(r / s2);
r1 += 0.5 * sy * ry;
}
vx = vx + parameter[7 * j + 4] * r1;
}
}
vx = vx + a0 + ax * x + ay * y;
return (vx);
}
double TSpectrum2::Deramp2(double x, double y, double x0, double y0,
double sigmax, double sigmay, double ro,
double txy, double sxy, double bx, double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of 2D peaks shape function (see manual) //
// according to amplitude of 2D peak //
// Function parameters: //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -txy, sxy-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
s2 = TMath::Sqrt(2.0);
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
if (txy != 0) {
px = 0, py = 0;
erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * txy * px * py;
}
if (sxy != 0) {
rx = Erfc(p / s2), ry = Erfc(r / s2);
r1 += 0.5 * sxy * rx * ry;
}
}
return (r1);
}
double TSpectrum2::Derampx(double x, double x0, double sigmax, double tx,
double sx, double bx)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of 2D peaks shape function (see manual) //
// according to amplitude of the ridge //
// Function parameters: //
// -x-channel in x-dimension //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -ro-correlation coefficient //
// -tx, sx-relative amplitudes //
// -bx-slope //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r1 = 0, px, erx, rx, ex, s2;
p = (x - x0) / sigmax;
if (TMath::Abs(p) < 3) {
s2 = TMath::Sqrt(2.0);
p = p * p / 2;
if (p < 700)
r1 = exp(-p);
else {
r1 = 0;
}
if (tx != 0) {
px = 0;
erx = Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9) {
px = exp(ex) * erx;
}
r1 += 0.5 * tx * px;
}
if (sx != 0) {
rx = Erfc(p / s2);
r1 += 0.5 * sx * rx;
}
}
return (r1);
}
double TSpectrum2::Deri02(double x, double y, double a, double x0,
double y0, double sigmax, double sigmay,
double ro, double txy, double sxy, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of 2D peaks shape function (see manual) //
// according to x position of 2D peak //
// Function parameters: //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -a-amplitude //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -txy, sxy-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
s2 = TMath::Sqrt(2.0);
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
e = -(ro * r - p) / sigmax;
e = e / (1 - ro * ro);
r1 = r1 * e;
if (txy != 0) {
px = 0, py = 0;
erx =
(-Erfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * sigmax) -
Derfc(p / s2 + 1 / (2 * bx)) / (s2 * sigmax)), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * txy * px * py;
}
if (sxy != 0) {
rx = -Derfc(p / s2) / (s2 * sigmax), ry = Erfc(r / s2);
r1 += 0.5 * sxy * rx * ry;
}
r1 = a * r1;
}
return (r1);
}
double TSpectrum2::Derderi02(double x, double y, double a, double x0,
double y0, double sigmax, double sigmay,
double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates second derivative of 2D peaks shape function //
// (see manual) according to x position of 2D peak //
// Function parameters: //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -a-amplitude //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e;
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
e = -(ro * r - p) / sigmax;
e = e / (1 - ro * ro);
r1 = r1 * (e * e - 1 / ((1 - ro * ro) * sigmax * sigmax));
r1 = a * r1;
}
return (r1);
}
double TSpectrum2::Derj02(double x, double y, double a, double x0,
double y0, double sigmax, double sigmay,
double ro, double txy, double sxy, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of 2D peaks shape function (see manual) //
// according to y position of 2D peak //
// Function parameters: //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -a-amplitude //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -txy, sxy-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
s2 = TMath::Sqrt(2.0);
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
e = -(ro * p - r) / sigmay;
e = e / (1 - ro * ro);
r1 = r1 * e;
if (txy != 0) {
px = 0, py = 0;
ery =
(-Erfc(r / s2 + 1 / (2 * by)) / (s2 * by * sigmay) -
Derfc(r / s2 + 1 / (2 * by)) / (s2 * sigmay)), erx =
Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * txy * px * py;
}
if (sxy != 0) {
ry = -Derfc(r / s2) / (s2 * sigmay), rx = Erfc(p / s2);
r1 += 0.5 * sxy * rx * ry;
}
r1 = a * r1;
}
return (r1);
}
double TSpectrum2::Derderj02(double x, double y, double a, double x0,
double y0, double sigmax, double sigmay,
double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates second derivative of 2D peaks shape function //
// (see manual) according to y position of 2D peak //
// Function parameters: //
// -x-channel in x-dimension //
// -y-channel in y-dimension //
// -a-amplitude //
// -x0-position of peak in x-dimension //
// -y0-position of peak in y-dimension //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e;
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
e = -(ro * p - r) / sigmay;
e = e / (1 - ro * ro);
r1 = r1 * (e * e - 1 / ((1 - ro * ro) * sigmay * sigmay));
r1 = a * r1;
}
return (r1);
}
double TSpectrum2::Deri01(double x, double ax, double x0, double sigmax,
double tx, double sx, double bx)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of 2D peaks shape function (see manual) //
// according to x position of 1D ridge //
// Function parameters: //
// -x-channel in x-dimension //
// -ax-amplitude of ridge //
// -x0-position of peak in x-dimension //
// -sigmax-sigmax of peaks //
// -ro-correlation coefficient //
// -tx, sx-relative amplitudes //
// -bx-slope //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, e, r1 = 0, px, rx, erx, ex, s2;
p = (x - x0) / sigmax;
if (TMath::Abs(p) < 3) {
s2 = TMath::Sqrt(2.0);
e = p * p / 2;
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
r1 = r1 * p / sigmax;
if (tx != 0) {
px = 0;
erx =
(-Erfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * sigmax) -
Derfc(p / s2 + 1 / (2 * bx)) / (s2 * sigmax));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9)
px = exp(ex) * erx;
r1 += 0.5 * tx * px;
}
if (sx != 0) {
rx = -Derfc(p / s2) / (s2 * sigmax);
r1 += 0.5 * sx * rx;
}
r1 = ax * r1;
}
return (r1);
}
double TSpectrum2::Derderi01(double x, double ax, double x0,
double sigmax)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates second derivative of 2D peaks shape function //
// (see manual) according to x position of 1D ridge //
// Function parameters: //
// -x-channel in x-dimension //
// -ax-amplitude of ridge //
// -x0-position of peak in x-dimension //
// -sigmax-sigmax of peaks //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, e, r1 = 0;
p = (x - x0) / sigmax;
if (TMath::Abs(p) < 3) {
e = p * p / 2;
if (e < 700)
r1 = exp(-e);
else {
r1 = 0;
}
r1 = r1 * (p * p / (sigmax * sigmax) - 1 / (sigmax * sigmax));
r1 = ax * r1;
}
return (r1);
}
double TSpectrum2::Dersigmax(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double ro, double txy,
double sxy, double tx, double sx, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to sigmax of peaks. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -txy, sxy, tx, sx-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 =
0, e, a, b, x0, y0, s2, px, py, rx, ry, erx, ery, ex, ey;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
e = exp(-e);
else {
e = 0;
}
b = -(ro * p * r - p * p) / sigmax;
e = e * b / (1 - ro * ro);
if (txy != 0) {
px = 0, py = 0;
erx =
-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * sigmax) -
Derfc(p / s2 + 1 / (2 * bx)) * p / (s2 * sigmax), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
e += 0.5 * txy * px * py;
}
if (sxy != 0) {
rx = -Derfc(p / s2) * p / (s2 * sigmax), ry = Erfc(r / s2);
e += 0.5 * sxy * rx * ry;
}
r1 = r1 + a * e;
}
if (TMath::Abs(p) < 3) {
x0 = parameter[7 * j + 5];
p = (x - x0) / sigmax;
b = p * p / 2;
if (b < 700)
e = exp(-b);
else {
e = 0;
}
e = 2 * b * e / sigmax;
if (tx != 0) {
px = 0;
erx =
(-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * sigmax) -
Derfc(p / s2 + 1 / (2 * bx)) * p / (s2 * sigmax));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9)
px = exp(ex) * erx;
e += 0.5 * tx * px;
}
if (sx != 0) {
rx = -Derfc(p / s2) * p / (s2 * sigmax);
e += 0.5 * sx * rx;
}
r1 += parameter[7 * j + 3] * e;
}
}
return (r1);
}
double TSpectrum2::Derdersigmax(int num_of_fitted_peaks, double x,
double y, const double *parameter,
double sigmax, double sigmay,
double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates second derivative of peaks shape function //
// (see manual) according to sigmax of peaks. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e, a, b, x0, y0;
int j;
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
e = exp(-e);
else {
e = 0;
}
b = -(ro * p * r - p * p) / sigmax;
e = e * (b * b / (1 - ro * ro) -
(3 * p * p - 2 * ro * p * r) / (sigmax * sigmax)) / (1 -
ro
*
ro);
r1 = r1 + a * e;
}
if (TMath::Abs(p) < 3) {
x0 = parameter[7 * j + 5];
p = (x - x0) / sigmax;
b = p * p / 2;
if (b < 700)
e = exp(-b);
else {
e = 0;
}
e = e * (4 * b * b - 6 * b) / (sigmax * sigmax);
r1 += parameter[7 * j + 3] * e;
}
}
return (r1);
}
double TSpectrum2::Dersigmay(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double ro, double txy,
double sxy, double ty, double sy, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to sigmax of peaks. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// -txy, sxy, ty, sy-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 =
0, e, a, b, x0, y0, s2, px, py, rx, ry, erx, ery, ex, ey;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
e = exp(-e);
else {
e = 0;
}
b = -(ro * p * r - r * r) / sigmay;
e = e * b / (1 - ro * ro);
if (txy != 0) {
px = 0, py = 0;
ery =
-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * sigmay) -
Derfc(r / s2 + 1 / (2 * by)) * r / (s2 * sigmay), erx =
Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
e += 0.5 * txy * px * py;
}
if (sxy != 0) {
ry = -Derfc(r / s2) * r / (s2 * sigmay), rx = Erfc(p / s2);
e += 0.5 * sxy * rx * ry;
}
r1 = r1 + a * e;
}
if (TMath::Abs(r) < 3) {
y0 = parameter[7 * j + 6];
r = (y - y0) / sigmay;
b = r * r / 2;
if (b < 700)
e = exp(-b);
else {
e = 0;
}
e = 2 * b * e / sigmay;
if (ty != 0) {
py = 0;
ery =
(-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * sigmay) -
Derfc(r / s2 + 1 / (2 * by)) * r / (s2 * sigmay));
ey = r / (s2 * by);
if (TMath::Abs(ey) < 9)
py = exp(ey) * ery;
e += 0.5 * ty * py;
}
if (sy != 0) {
ry = -Derfc(r / s2) * r / (s2 * sigmay);
e += 0.5 * sy * ry;
}
r1 += parameter[7 * j + 4] * e;
}
}
return (r1);
}
double TSpectrum2::Derdersigmay(int num_of_fitted_peaks, double x,
double y, const double *parameter,
double sigmax, double sigmay,
double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates second derivative of peaks shape function //
// (see manual) according to sigmay of peaks. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, e, a, b, x0, y0;
int j;
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
if (e < 700)
e = exp(-e);
else {
e = 0;
}
b = -(ro * p * r - r * r) / sigmay;
e = e * (b * b / (1 - ro * ro) -
(3 * r * r - 2 * ro * r * p) / (sigmay * sigmay)) / (1 -
ro
*
ro);
r1 = r1 + a * e;
}
if (TMath::Abs(r) < 3) {
y0 = parameter[7 * j + 6];
r = (y - y0) / sigmay;
b = r * r / 2;
if (b < 700)
e = exp(-b);
else {
e = 0;
}
e = e * (4 * b * b - 6 * b) / (sigmay * sigmay);
r1 += parameter[7 * j + 4] * e;
}
}
return (r1);
}
double TSpectrum2::Derro(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sx, double sy,
double r)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to correlation coefficient ro. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sx-sigmax of peaks //
// -sy-sigmay of peaks //
// -r-correlation coefficient ro //
// //
//////////////////////////////////////////////////////////////////////////////////
double px, qx, rx, vx, x0, y0, a, ex, tx;
int j;
vx = 0;
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
px = (x - x0) / sx;
qx = (y - y0) / sy;
if (TMath::Abs(px) < 3 && TMath::Abs(qx) < 3) {
rx = (px * px - 2 * r * px * qx + qx * qx);
ex = rx / (2 * (1 - r * r));
if ((ex) < 700)
ex = exp(-ex);
else {
ex = 0;
}
tx = px * qx / (1 - r * r);
tx = tx - r * rx / ((1 - r * r) * (1 - r * r));
vx = vx + a * ex * tx;
}
}
return (vx);
}
double TSpectrum2::Dertxy(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double bx, double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude txy. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, ex, ey, px, py, erx, ery, s2, x0, y0, a;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
px = 0, py = 0;
erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * a * px * py;
}
return (r1);
}
double TSpectrum2::Dersxy(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude sxy. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, rx, ry, x0, y0, a, s2;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
rx = Erfc(p / s2), ry = Erfc(r / s2);
r1 += 0.5 * a * rx * ry;
}
return (r1);
}
double TSpectrum2::Dertx(int num_of_fitted_peaks, double x,
const double *parameter, double sigmax,
double bx)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude tx. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigma of 1D ridge //
// -bx-slope //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r1 = 0, ex, px, erx, s2, ax, x0;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
ax = parameter[7 * j + 3];
x0 = parameter[7 * j + 5];
p = (x - x0) / sigmax;
px = 0;
erx = Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9) {
px = exp(ex) * erx;
}
r1 += 0.5 * ax * px;
}
return (r1);
}
double TSpectrum2::Derty(int num_of_fitted_peaks, double x,
const double *parameter, double sigmax,
double bx)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude ty. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigma of 1D ridge //
// -bx-slope //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r1 = 0, ex, px, erx, s2, ax, x0;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
ax = parameter[7 * j + 4];
x0 = parameter[7 * j + 6];
p = (x - x0) / sigmax;
px = 0;
erx = Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9) {
px = exp(ex) * erx;
}
r1 += 0.5 * ax * px;
}
return (r1);
}
double TSpectrum2::Dersx(int num_of_fitted_peaks, double x,
const double *parameter, double sigmax)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude sx. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigma of 1D ridge //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r1 = 0, rx, ax, x0, s2;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
ax = parameter[7 * j + 3];
x0 = parameter[7 * j + 5];
p = (x - x0) / sigmax;
s2 = TMath::Sqrt(2.0);
rx = Erfc(p / s2);
r1 += 0.5 * ax * rx;
}
return (r1);
}
double TSpectrum2::Dersy(int num_of_fitted_peaks, double x,
const double *parameter, double sigmax)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to relative amplitude sy. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigma of 1D ridge //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r1 = 0, rx, ax, x0, s2;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
ax = parameter[7 * j + 4];
x0 = parameter[7 * j + 6];
p = (x - x0) / sigmax;
s2 = TMath::Sqrt(2.0);
rx = Erfc(p / s2);
r1 += 0.5 * ax * rx;
}
return (r1);
}
double TSpectrum2::Derbx(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double txy, double tx, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to slope bx. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -txy, tx-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, a, x0, y0, s2, px, py, erx, ery, ex, ey;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (txy != 0) {
px = 0, py = 0;
erx =
-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * bx) -
Derfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * bx), ery =
Erfc(r / s2 + 1 / (2 * by));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * a * txy * px * py;
}
a = parameter[7 * j + 3];
x0 = parameter[7 * j + 5];
p = (x - x0) / sigmax;
if (tx != 0) {
px = 0;
erx =
(-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * bx) -
Derfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * bx));
ex = p / (s2 * bx);
if (TMath::Abs(ex) < 9)
px = exp(ex) * erx;
r1 += 0.5 * a * tx * px;
}
}
return (r1);
}
double TSpectrum2::Derby(int num_of_fitted_peaks, double x, double y,
const double *parameter, double sigmax,
double sigmay, double txy, double ty, double bx,
double by)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of peaks shape function (see manual) //
// according to slope by. //
// Function parameters: //
// -num_of_fitted_peaks-number of fitted peaks //
// -x,y-position of channel //
// -parameter-array of peaks parameters (amplitudes and positions) //
// -sigmax-sigmax of peaks //
// -sigmay-sigmay of peaks //
// -txy, ty-relative amplitudes //
// -bx, by-slopes //
// //
//////////////////////////////////////////////////////////////////////////////////
double p, r, r1 = 0, a, x0, y0, s2, px, py, erx, ery, ex, ey;
int j;
s2 = TMath::Sqrt(2.0);
for (j = 0; j < num_of_fitted_peaks; j++) {
a = parameter[7 * j];
x0 = parameter[7 * j + 1];
y0 = parameter[7 * j + 2];
p = (x - x0) / sigmax;
r = (y - y0) / sigmay;
if (txy != 0) {
px = 0, py = 0;
ery =
-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * by) -
Derfc(r / s2 + 1 / (2 * by)) / (s2 * by * by), erx =
Erfc(p / s2 + 1 / (2 * bx));
ex = p / (s2 * bx), ey = r / (s2 * by);
if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
px = exp(ex) * erx, py = exp(ey) * ery;
}
r1 += 0.5 * a * txy * px * py;
}
a = parameter[7 * j + 4];
y0 = parameter[7 * j + 6];
r = (y - y0) / sigmay;
if (ty != 0) {
py = 0;
ery =
(-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * by) -
Derfc(r / s2 + 1 / (2 * by)) / (s2 * by * by));
ey = r / (s2 * by);
if (TMath::Abs(ey) < 9)
py = exp(ey) * ery;
r1 += 0.5 * a * ty * py;
}
}
return (r1);
}
double TSpectrum2::Volume(double a, double sx, double sy, double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates volume of a peak //
// Function parameters: //
// -a-amplitude of the peak //
// -sx,sy-sigmas of peak //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double pi = 3.1415926535, r;
r = 1 - ro * ro;
if (r > 0)
r = TMath::Sqrt(r);
else {
return (0);
}
r = 2 * a * pi * sx * sy * r;
return (r);
}
double TSpectrum2::Derpa2(double sx, double sy, double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of the volume of a peak //
// according to amplitute //
// Function parameters: //
// -sx,sy-sigmas of peak //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double pi = 3.1415926535, r;
r = 1 - ro * ro;
if (r > 0)
r = TMath::Sqrt(r);
else {
return (0);
}
r = 2 * pi * sx * sy * r;
return (r);
}
double TSpectrum2::Derpsigmax(double a, double sy, double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of the volume of a peak //
// according to sigmax //
// Function parameters: //
// -a-amplitude of peak //
// -sy-sigma of peak //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double pi = 3.1415926535, r;
r = 1 - ro * ro;
if (r > 0)
r = TMath::Sqrt(r);
else {
return (0);
}
r = a * 2 * pi * sy * r;
return (r);
}
double TSpectrum2::Derpsigmay(double a, double sx, double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of the volume of a peak //
// according to sigmay //
// Function parameters: //
// -a-amplitude of peak //
// -sx-sigma of peak //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double pi = 3.1415926535, r;
r = 1 - ro * ro;
if (r > 0)
r = TMath::Sqrt(r);
else {
return (0);
}
r = a * 2 * pi * sx * r;
return (r);
}
double TSpectrum2::Derpro(double a, double sx, double sy, double ro)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates derivative of the volume of a peak //
// according to ro //
// Function parameters: //
// -a-amplitude of peak //
// -sx,sy-sigmas of peak //
// -ro-correlation coefficient //
// //
//////////////////////////////////////////////////////////////////////////////////
double pi = 3.1415926535, r;
r = 1 - ro * ro;
if (r > 0)
r = TMath::Sqrt(r);
else {
return (0);
}
r = -a * 2 * pi * sx * sy * ro / r;
return (r);
}
/////////////////END OF AUXILIARY FUNCTIONS USED BY FITTING FUNCION fit2//////////////////////////
/////////////////FITTING FUNCTION WITHOUT MATRIX INVERSION///////////////////////////////////////
const char *TSpectrum2::Fit2Awmi(float **source, TSpectrumTwoDimFit * p,
int sizex, int sizey)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL FIT FUNCTION */
/* Algorithm without matrix inversion */
/* This function fits the source spectrum. The calling program should */
/* fill in input parameters of the TSpectrumTwoDimFit class */
/* The fitted parameters are written into class pointed by */
/* TSpectrumTwoDimFit structure pointer and fitted data are written */
/* into source spectrum. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum */
/* p-pointer to the TSpectrumTwoDimFit class, see manual */
/* sizex-length x of source spectrum */
/* sizey-length y of source spectrum */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, i1, i2, j, k, shift =
7 * p->number_of_peaks + 14, peak_vel, rozmer, iter, pw,
regul_cycle, flag;
double a, b, c, d = 0, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi =
0, pi, pmin = 0, chi_cel = 0, chi_er;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (p->number_of_peaks <= 0)
return ("INVALID NUMBER OF PEAKS, MUST BE POSITIVE");
if (p->number_of_iterations <= 0)
return ("INVALID NUMBER OF ITERATIONS, MUST BE POSITIVE");
if (p->alpha <= 0 || p->alpha > 1)
return ("INVALID COEFFICIENT ALPHA, MUST BE > THAN 0 AND <=1");
if (p->statistic_type != FIT2_OPTIM_CHI_COUNTS
&& p->statistic_type != FIT2_OPTIM_CHI_FUNC_VALUES
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD)
return ("WRONG TYPE OF STATISTIC");
if (p->alpha_optim != FIT2_ALPHA_HALVING
&& p->alpha_optim != FIT2_ALPHA_OPTIMAL)
return ("WRONG OPTIMIZATION ALGORITHM");
if (p->power != FIT2_FIT_POWER2 && p->power != FIT2_FIT_POWER4
&& p->power != FIT2_FIT_POWER6 && p->power != FIT2_FIT_POWER8
&& p->power != FIT2_FIT_POWER10 && p->power != FIT2_FIT_POWER12)
return ("WRONG POWER");
if (p->fit_taylor != FIT2_TAYLOR_ORDER_FIRST
&& p->fit_taylor != FIT2_TAYLOR_ORDER_SECOND)
return ("WRONG ORDER OF TAYLOR DEVELOPMENT");
if (p->xmin < 0 || p->xmin > p->xmax)
return ("INVALID LOW LIMIT X OF FITTING REGION");
if (p->xmax >= sizex || p->xmax < p->xmin)
return ("INVALID HIGH LIMIT X OF FITTING REGION");
if (p->ymin < 0 || p->ymin > p->ymax)
return ("INVALID LOW LIMIT Y OF FITTING REGION");
if (p->ymax >= sizey || p->ymax < p->ymin)
return ("INVALID HIGH LIMIT Y OF FITTING REGION");
double *working_space = new double[5 * (7 * p->number_of_peaks + 14)];
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->amp_init[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i] = p->amp_init[i]; //vector parameter
if (p->fix_amp[i] == false) {
working_space[shift + j] = p->amp_init[i]; //vector xk
j += 1;
}
if (p->position_init_x[i] < p->xmin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_x[i] > p->xmax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 1] = p->position_init_x[i]; //vector parameter
if (p->fix_position_x[i] == false) {
working_space[shift + j] = p->position_init_x[i]; //vector xk
j += 1;
}
if (p->position_init_y[i] < p->ymin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_y[i] > p->ymax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 2] = p->position_init_y[i]; //vector parameter
if (p->fix_position_y[i] == false) {
working_space[shift + j] = p->position_init_y[i]; //vector xk
j += 1;
}
if (p->amp_init_x1[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i + 3] = p->amp_init_x1[i]; //vector parameter
if (p->fix_amp_x1[i] == false) {
working_space[shift + j] = p->amp_init_x1[i]; //vector xk
j += 1;
}
if (p->amp_init_y1[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i + 4] = p->amp_init_y1[i]; //vector parameter
if (p->fix_amp_y1[i] == false) {
working_space[shift + j] = p->amp_init_y1[i]; //vector xk
j += 1;
}
if (p->position_init_x1[i] < p->xmin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_x1[i] > p->xmax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 5] = p->position_init_x1[i]; //vector parameter
if (p->fix_position_x1[i] == false) {
working_space[shift + j] = p->position_init_x1[i]; //vector xk
j += 1;
}
if (p->position_init_y1[i] < p->ymin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_y1[i] > p->ymax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 6] = p->position_init_y1[i]; //vector parameter
if (p->fix_position_y1[i] == false) {
working_space[shift + j] = p->position_init_y1[i]; //vector xk
j += 1;
}
}
peak_vel = 7 * i;
if (p->sigma_init_x < 0)
return ("INITIAL VALUE OF SIGMA MUST BE NONNEGATIVE");
working_space[7 * i] = p->sigma_init_x; //vector parameter
if (p->fix_sigma_x == false) {
working_space[shift + j] = p->sigma_init_x; //vector xk
j += 1;
}
if (p->sigma_init_y < 0)
return ("INITIAL VALUE OF SIGMA MUST BE NONNEGATIVE");
working_space[7 * i + 1] = p->sigma_init_y; //vector parameter
if (p->fix_sigma_y == false) {
working_space[shift + j] = p->sigma_init_y; //vector xk
j += 1;
}
if (p->ro_init < -1 || p->ro_init > 1)
return ("INITIAL VALUE OF RO MUST BE FROM REGION <-1,1>");
working_space[7 * i + 2] = p->ro_init; //vector parameter
if (p->fix_ro == false) {
working_space[shift + j] = p->ro_init; //vector xk
j += 1;
}
working_space[7 * i + 3] = p->a0_init; //vector parameter
if (p->fix_a0 == false) {
working_space[shift + j] = p->a0_init; //vector xk
j += 1;
}
working_space[7 * i + 4] = p->ax_init; //vector parameter
if (p->fix_ax == false) {
working_space[shift + j] = p->ax_init; //vector xk
j += 1;
}
working_space[7 * i + 5] = p->ay_init; //vector parameter
if (p->fix_ay == false) {
working_space[shift + j] = p->ay_init; //vector xk
j += 1;
}
if (p->txy_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 6] = p->txy_init; //vector parameter
if (p->fix_txy == false) {
working_space[shift + j] = p->txy_init; //vector xk
j += 1;
}
if (p->sxy_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 7] = p->sxy_init; //vector parameter
if (p->fix_sxy == false) {
working_space[shift + j] = p->sxy_init; //vector xk
j += 1;
}
if (p->tx_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 8] = p->tx_init; //vector parameter
if (p->fix_tx == false) {
working_space[shift + j] = p->tx_init; //vector xk
j += 1;
}
if (p->ty_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 9] = p->ty_init; //vector parameter
if (p->fix_ty == false) {
working_space[shift + j] = p->ty_init; //vector xk
j += 1;
}
if (p->sx_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 10] = p->sxy_init; //vector parameter
if (p->fix_sx == false) {
working_space[shift + j] = p->sx_init; //vector xk
j += 1;
}
if (p->sy_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 11] = p->sy_init; //vector parameter
if (p->fix_sy == false) {
working_space[shift + j] = p->sy_init; //vector xk
j += 1;
}
if (p->bx_init <= 0)
return ("INITIAL VALUE OF B MUST BE POSITIVE");
working_space[7 * i + 12] = p->bx_init; //vector parameter
if (p->fix_bx == false) {
working_space[shift + j] = p->bx_init; //vector xk
j += 1;
}
if (p->by_init <= 0)
return ("INITIAL VALUE OF B MUST BE POSITIVE");
working_space[7 * i + 13] = p->by_init; //vector parameter
if (p->fix_by == false) {
working_space[shift + j] = p->by_init; //vector xk
j += 1;
}
rozmer = j;
if (rozmer == 0)
return ("ALL PARAMETERS ARE FIXED");
if (rozmer >= (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1))
return
("NUMBER OF FITTED PARAMETERS IS LARGER THAN # OF FITTED POINTS");
for (iter = 0; iter < p->number_of_iterations; iter++) {
for (j = 0; j < rozmer; j++) {
working_space[2 * shift + j] = 0, working_space[3 * shift + j] = 0; //der,temp
}
//filling vectors
alpha = p->alpha;
chi_opt = 0, pw = p->power - 2;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi_opt += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi_opt += (yw - f) * (yw - f) / ywm;
}
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else {
if (ywm == 0)
ywm = 1;
}
//calculation of gradient vector
for (j = 0, k = 0; j < p->number_of_peaks; j++) {
if (p->fix_amp[j] == false) {
a = Deramp2((double) i1, (double) i2,
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_position_x[j] == false) {
a = Deri02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derderi02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0
&& a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_position_y[j] == false) {
a = Derj02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derderj02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0
&& a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_amp_x1[j] == false) {
a = Derampx((double) i1, working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_amp_y1[j] == false) {
a = Derampx((double) i2, working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_position_x1[j] == false) {
a = Deri01((double) i1, working_space[7 * j + 3],
working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derderi01((double) i1, working_space[7 * j + 3],
working_space[7 * j + 5],
working_space[peak_vel]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0
&& a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //Der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //Der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_position_y1[j] == false) {
a = Deri01((double) i2, working_space[7 * j + 4],
working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derderi01((double) i2, working_space[7 * j + 4],
working_space[7 * j + 6],
working_space[peak_vel + 1]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0
&& a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
}
if (p->fix_sigma_x == false) {
a = Dersigmax(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derdersigmax(p->number_of_peaks, (double) i1,
(double) i2, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0 && a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_sigma_y == false) {
a = Dersigmay(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND)
d = Derdersigmay(p->number_of_peaks, (double) i1,
(double) i2, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0 && a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_ro == false) {
a = Derro(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& p->fit_taylor == FIT2_TAYLOR_ORDER_SECOND) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if ((a + d) <= 0 && a >= 0 || (a + d) >= 0 && a <= 0)
d = 0;
}
else
d = 0;
a = a + d;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_a0 == false) {
a = 1.;
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_ax == false) {
a = i1;
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_ay == false) {
a = i2;
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_txy == false) {
a = Dertxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_sxy == false) {
a = Dersxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_tx == false) {
a = Dertx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel],
working_space[peak_vel + 12]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_ty == false) {
a = Derty(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_sx == false) {
a = Dersx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_sy == false) {
a = Dersy(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_bx == false) {
a = Derbx(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
if (p->fix_by == false) {
a = Derby(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c; //der
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c; //temp
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c; //der
b = a * a / ywm;
working_space[3 * shift + k] += b * c; //temp
}
}
k += 1;
}
}
}
for (j = 0; j < rozmer; j++) {
if (TMath::Abs(working_space[3 * shift + j]) > 0.000001)
working_space[2 * shift + j] = working_space[2 * shift + j] / TMath::Abs(working_space[3 * shift + j]); //der[j]=der[j]/temp[j]
else
working_space[2 * shift + j] = 0; //der[j]
}
//calculate chi_opt
chi2 = chi_opt;
chi_opt = TMath::Sqrt(TMath::Abs(chi_opt));
//calculate new parameters
regul_cycle = 0;
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = working_space[shift + j]; //temp_xk[j]=xk[j]
}
do {
if (p->alpha_optim == FIT2_ALPHA_OPTIMAL) {
if (p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD)
chi_min = 10000 * chi2;
else
chi_min = 0.1 * chi2;
flag = 0;
for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi2 = 0;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1,
(double) i2, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi2 += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi2 += (yw - f) * (yw - f) / ywm;
}
}
}
if (chi2 < chi_min
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD
|| chi2 > chi_min
&& p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
pmin = pi, chi_min = chi2;
}
else
flag = 1;
if (pi == 0.1)
chi_min = chi2;
chi = chi_min;
}
if (pmin != 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pmin*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi = chi_min;
}
}
else {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi = 0;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi += (yw - f) * (yw - f) / ywm;
}
}
}
}
chi2 = chi;
chi = TMath::Sqrt(TMath::Abs(chi));
if (p->alpha_optim == FIT2_ALPHA_HALVING && chi > 1E-6)
alpha = alpha * chi_opt / (2 * chi);
else if (p->alpha_optim == FIT2_ALPHA_OPTIMAL)
alpha = alpha / 10.0;
iter += 1;
regul_cycle += 1;
} while ((chi > chi_opt
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD
|| chi < chi_opt
&& p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD)
&& regul_cycle < FIT2_NUM_OF_REGUL_CYCLES);
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = 0; //temp_xk[j]
working_space[2 * shift + j] = 0; //der[j]
}
for (i1 = p->xmin, chi_cel = 0; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
if (yw == 0)
yw = 1;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
chi_opt = (yw - f) * (yw - f) / yw;
chi_cel += (yw - f) * (yw - f) / yw;
//calculate gradient vector
for (j = 0, k = 0; j < p->number_of_peaks; j++) {
if (p->fix_amp[j] == false) {
a = Deramp2((double) i1, (double) i2,
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_x[j] == false) {
a = Deri02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_y[j] == false) {
a = Derj02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_amp_x1[j] == false) {
a = Derampx((double) i1, working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_amp_y1[j] == false) {
a = Derampx((double) i2, working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_x1[j] == false) {
a = Deri01((double) i1, working_space[7 * j + 3],
working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_y1[j] == false) {
a = Deri01((double) i2, working_space[7 * j + 4],
working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
}
if (p->fix_sigma_x == false) {
a = Dersigmax(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_sigma_y == false) {
a = Dersigmay(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_ro == false) {
a = Derro(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_a0 == false) {
a = 1.;
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_ax == false) {
a = i1;
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_ay == false) {
a = i2;
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_txy == false) {
a = Dertxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_sxy == false) {
a = Dersxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_tx == false) {
a = Dertx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel],
working_space[peak_vel + 12]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_ty == false) {
a = Derty(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_sx == false) {
a = Dersx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_sy == false) {
a = Dersy(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_bx == false) {
a = Derbx(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
if (p->fix_by == false) {
a = Derby(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b * c; //temp_xk[k]
}
k += 1;
}
}
}
}
b = (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1) - rozmer;
chi_er = chi_cel / b;
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
p->volume[i] =
Volume(working_space[7 * i], working_space[peak_vel],
working_space[peak_vel + 1], working_space[peak_vel + 2]);
if (p->volume[i] > 0) {
c = 0;
if (p->fix_amp[i] == false) {
a = Derpa2(working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + j]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_sigma_x == false) {
a = Derpsigmax(working_space[shift + j],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_sigma_y == false) {
a = Derpsigmay(working_space[shift + j],
working_space[peak_vel],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel + 1]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_ro == false) {
a = Derpro(working_space[shift + j], working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel + 2]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
p->volume_err[i] = TMath::Sqrt(TMath::Abs(chi_er * c));
}
else {
p->volume_err[i] = 0;
}
if (p->fix_amp[i] == false) {
p->amp_calc[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc[i] = p->amp_init[i];
p->amp_err[i] = 0;
}
if (p->fix_position_x[i] == false) {
p->position_calc_x[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_x[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_x[i] = p->position_init_x[i];
p->position_err_x[i] = 0;
}
if (p->fix_position_y[i] == false) {
p->position_calc_y[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_y[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_y[i] = p->position_init_y[i];
p->position_err_y[i] = 0;
}
if (p->fix_amp_x1[i] == false) {
p->amp_calc_x1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err_x1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc_x1[i] = p->amp_init_x1[i];
p->amp_err_x1[i] = 0;
}
if (p->fix_amp_y1[i] == false) {
p->amp_calc_y1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err_y1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc_y1[i] = p->amp_init_y1[i];
p->amp_err_y1[i] = 0;
}
if (p->fix_position_x1[i] == false) {
p->position_calc_x1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_x1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_x1[i] = p->position_init_x1[i];
p->position_err_x1[i] = 0;
}
if (p->fix_position_y1[i] == false) {
p->position_calc_y1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_y1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_y1[i] = p->position_init_y1[i];
p->position_err_y1[i] = 0;
}
}
if (p->fix_sigma_x == false) {
p->sigma_calc_x = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sigma_err_x = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sigma_calc_x = p->sigma_init_x;
p->sigma_err_x = 0;
}
if (p->fix_sigma_y == false) {
p->sigma_calc_y = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sigma_err_y = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sigma_calc_y = p->sigma_init_y;
p->sigma_err_y = 0;
}
if (p->fix_ro == false) {
p->ro_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ro_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ro_calc = p->ro_init;
p->ro_err = 0;
}
if (p->fix_a0 == false) {
p->a0_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->a0_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->a0_calc = p->a0_init;
p->a0_err = 0;
}
if (p->fix_ax == false) {
p->ax_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ax_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ax_calc = p->ax_init;
p->ax_err = 0;
}
if (p->fix_ay == false) {
p->ay_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ay_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ay_calc = p->ay_init;
p->ay_err = 0;
}
if (p->fix_txy == false) {
p->txy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->txy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->txy_calc = p->txy_init;
p->txy_err = 0;
}
if (p->fix_sxy == false) {
p->sxy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sxy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sxy_calc = p->sxy_init;
p->sxy_err = 0;
}
if (p->fix_tx == false) {
p->tx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->tx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->tx_calc = p->tx_init;
p->tx_err = 0;
}
if (p->fix_ty == false) {
p->ty_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ty_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ty_calc = p->ty_init;
p->ty_err = 0;
}
if (p->fix_sx == false) {
p->sx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sx_calc = p->sx_init;
p->sx_err = 0;
}
if (p->fix_sy == false) {
p->sy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sy_calc = p->sy_init;
p->sy_err = 0;
}
if (p->fix_bx == false) {
p->bx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->bx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->bx_calc = p->bx_init;
p->bx_err = 0;
}
if (p->fix_by == false) {
p->by_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->by_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->by_calc = p->by_init;
p->by_err = 0;
}
b = (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1) - rozmer;
p->chi = chi_cel / b;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
source[i1][i2] = f;
} } delete[]working_space;
return 0;
}
// ____________________________________________________________________________________________________________________________
const char *TSpectrum2::Fit2Stiefel(float **source,
TSpectrumTwoDimFit * p, int sizex,
int sizey)
{
/////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL FIT FUNCTION */
/* Algorithm with matrix inversion (Stiefel-Hestens inversion) */
/* This function fits the source spectrum. The calling program should */
/* fill in input parameters of the TSpectrumTwoDimFit class */
/* The fitted parameters are written into class pointed by */
/* TSpectrumTwoDimFit structure pointer and fitted data are written */
/* back into source spectrum. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum */
/* p-pointer to the TSpectrumTwoDimFit class, see manual */
/* sizex-length x of source spectrum */
/* sizey-length y of source spectrum */
/* */
/////////////////////////////////////////////////////////////////////////////
int i, i1, i2, j, k, shift =
7 * p->number_of_peaks + 14, peak_vel, rozmer, iter, regul_cycle,
flag;
double a, b, c, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi =
0, pi, pmin = 0, chi_cel = 0, chi_er;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
if (p->number_of_peaks <= 0)
return ("INVALID NUMBER OF PEAKS, MUST BE POSITIVE");
if (p->number_of_iterations <= 0)
return ("INVALID NUMBER OF ITERATIONS, MUST BE POSITIVE");
if (p->alpha <= 0 || p->alpha > 1)
return ("INVALID COEFFICIENT ALPHA, MUST BE > THAN 0 AND <=1");
if (p->statistic_type != FIT2_OPTIM_CHI_COUNTS
&& p->statistic_type != FIT2_OPTIM_CHI_FUNC_VALUES
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD)
return ("WRONG TYPE OF STATISTIC");
if (p->alpha_optim != FIT2_ALPHA_HALVING
&& p->alpha_optim != FIT2_ALPHA_OPTIMAL)
return ("WRONG OPTIMIZATION ALGORITHM");
if (p->xmin < 0 || p->xmin > p->xmax)
return ("INVALID LOW LIMIT X OF FITTING REGION");
if (p->xmax >= sizex || p->xmax < p->xmin)
return ("INVALID HIGH LIMIT X OF FITTING REGION");
if (p->ymin < 0 || p->ymin > p->ymax)
return ("INVALID LOW LIMIT Y OF FITTING REGION");
if (p->ymax >= sizey || p->ymax < p->ymin)
return ("INVALID HIGH LIMIT Y OF FITTING REGION");
double *working_space = new double[5 * (7 * p->number_of_peaks + 14)];
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->amp_init[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i] = p->amp_init[i]; //vector parameter
if (p->fix_amp[i] == false) {
working_space[shift + j] = p->amp_init[i]; //vector xk
j += 1;
}
if (p->position_init_x[i] < p->xmin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_x[i] > p->xmax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 1] = p->position_init_x[i]; //vector parameter
if (p->fix_position_x[i] == false) {
working_space[shift + j] = p->position_init_x[i]; //vector xk
j += 1;
}
if (p->position_init_y[i] < p->ymin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_y[i] > p->ymax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 2] = p->position_init_y[i]; //vector parameter
if (p->fix_position_y[i] == false) {
working_space[shift + j] = p->position_init_y[i]; //vector xk
j += 1;
}
if (p->amp_init_x1[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i + 3] = p->amp_init_x1[i]; //vector parameter
if (p->fix_amp_x1[i] == false) {
working_space[shift + j] = p->amp_init_x1[i]; //vector xk
j += 1;
}
if (p->amp_init_y1[i] < 0)
return ("INITIAL VALUE OF AMPLITUDE MUST BE NONNEGATIVE");
working_space[7 * i + 4] = p->amp_init_y1[i]; //vector parameter
if (p->fix_amp_y1[i] == false) {
working_space[shift + j] = p->amp_init_y1[i]; //vector xk
j += 1;
}
if (p->position_init_x1[i] < p->xmin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_x1[i] > p->xmax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 5] = p->position_init_x1[i]; //vector parameter
if (p->fix_position_x1[i] == false) {
working_space[shift + j] = p->position_init_x1[i]; //vector xk
j += 1;
}
if (p->position_init_y1[i] < p->ymin)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
if (p->position_init_y1[i] > p->ymax)
return
("INITIAL VALUE OF POSITION MUST BE WITHIN FITTING REGION");
working_space[7 * i + 6] = p->position_init_y1[i]; //vector parameter
if (p->fix_position_y1[i] == false) {
working_space[shift + j] = p->position_init_y1[i]; //vector xk
j += 1;
}
}
peak_vel = 7 * i;
if (p->sigma_init_x < 0)
return ("INITIAL VALUE OF SIGMA MUST BE NONNEGATIVE");
working_space[7 * i] = p->sigma_init_x; //vector parameter
if (p->fix_sigma_x == false) {
working_space[shift + j] = p->sigma_init_x; //vector xk
j += 1;
}
if (p->sigma_init_y < 0)
return ("INITIAL VALUE OF SIGMA MUST BE NONNEGATIVE");
working_space[7 * i + 1] = p->sigma_init_y; //vector parameter
if (p->fix_sigma_y == false) {
working_space[shift + j] = p->sigma_init_y; //vector xk
j += 1;
}
if (p->ro_init < -1 || p->ro_init > 1)
return ("INITIAL VALUE OF RO MUST BE FROM REGION <-1,1>");
working_space[7 * i + 2] = p->ro_init; //vector parameter
if (p->fix_ro == false) {
working_space[shift + j] = p->ro_init; //vector xk
j += 1;
}
working_space[7 * i + 3] = p->a0_init; //vector parameter
if (p->fix_a0 == false) {
working_space[shift + j] = p->a0_init; //vector xk
j += 1;
}
working_space[7 * i + 4] = p->ax_init; //vector parameter
if (p->fix_ax == false) {
working_space[shift + j] = p->ax_init; //vector xk
j += 1;
}
working_space[7 * i + 5] = p->ay_init; //vector parameter
if (p->fix_ay == false) {
working_space[shift + j] = p->ay_init; //vector xk
j += 1;
}
if (p->txy_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 6] = p->txy_init; //vector parameter
if (p->fix_txy == false) {
working_space[shift + j] = p->txy_init; //vector xk
j += 1;
}
if (p->sxy_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 7] = p->sxy_init; //vector parameter
if (p->fix_sxy == false) {
working_space[shift + j] = p->sxy_init; //vector xk
j += 1;
}
if (p->tx_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 8] = p->tx_init; //vector parameter
if (p->fix_tx == false) {
working_space[shift + j] = p->tx_init; //vector xk
j += 1;
}
if (p->ty_init < 0)
return ("INITIAL VALUE OF T MUST BE NONNEGATIVE");
working_space[7 * i + 9] = p->ty_init; //vector parameter
if (p->fix_ty == false) {
working_space[shift + j] = p->ty_init; //vector xk
j += 1;
}
if (p->sx_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 10] = p->sxy_init; //vector parameter
if (p->fix_sx == false) {
working_space[shift + j] = p->sx_init; //vector xk
j += 1;
}
if (p->sy_init < 0)
return ("INITIAL VALUE OF S MUST BE NONNEGATIVE");
working_space[7 * i + 11] = p->sy_init; //vector parameter
if (p->fix_sy == false) {
working_space[shift + j] = p->sy_init; //vector xk
j += 1;
}
if (p->bx_init <= 0)
return ("INITIAL VALUE OF B MUST BE POSITIVE");
working_space[7 * i + 12] = p->bx_init; //vector parameter
if (p->fix_bx == false) {
working_space[shift + j] = p->bx_init; //vector xk
j += 1;
}
if (p->by_init <= 0)
return ("INITIAL VALUE OF B MUST BE POSITIVE");
working_space[7 * i + 13] = p->by_init; //vector parameter
if (p->fix_by == false) {
working_space[shift + j] = p->by_init; //vector xk
j += 1;
}
rozmer = j;
if (rozmer == 0)
return ("ALL PARAMETERS ARE FIXED");
if (rozmer >= (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1))
return
("NUMBER OF FITTED PARAMETERS IS LARGER THAN # OF FITTED POINTS");
double **working_matrix = new double *[rozmer];
for (i = 0; i < rozmer; i++)
working_matrix[i] = new double[rozmer + 4];
for (iter = 0; iter < p->number_of_iterations; iter++) {
for (j = 0; j < rozmer; j++) {
working_space[3 * shift + j] = 0; //temp
for (k = 0; k <= rozmer; k++) {
working_matrix[j][k] = 0;
}
}
//filling working matrix
alpha = p->alpha;
chi_opt = 0;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
//calculation of gradient vector
for (j = 0, k = 0; j < p->number_of_peaks; j++) {
if (p->fix_amp[j] == false) {
working_space[2 * shift + k] =
Deramp2((double) i1, (double) i2,
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_position_x[j] == false) {
working_space[2 * shift + k] =
Deri02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_position_y[j] == false) {
working_space[2 * shift + k] =
Derj02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_amp_x1[j] == false) {
working_space[2 * shift + k] =
Derampx((double) i1, working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
k += 1;
}
if (p->fix_amp_y1[j] == false) {
working_space[2 * shift + k] =
Derampx((double) i2, working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_position_x1[j] == false) {
working_space[2 * shift + k] =
Deri01((double) i1, working_space[7 * j + 3],
working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
k += 1;
}
if (p->fix_position_y1[j] == false) {
working_space[2 * shift + k] =
Deri01((double) i2, working_space[7 * j + 4],
working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
k += 1;
}
} if (p->fix_sigma_x == false) {
working_space[2 * shift + k] =
Dersigmax(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_sigma_y == false) {
working_space[2 * shift + k] =
Dersigmay(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_ro == false) {
working_space[2 * shift + k] =
Derro(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
k += 1;
}
if (p->fix_a0 == false) {
working_space[2 * shift + k] = 1.;
k += 1;
}
if (p->fix_ax == false) {
working_space[2 * shift + k] = i1;
k += 1;
}
if (p->fix_ay == false) {
working_space[2 * shift + k] = i2;
k += 1;
}
if (p->fix_txy == false) {
working_space[2 * shift + k] =
Dertxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_sxy == false) {
working_space[2 * shift + k] =
Dersxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1]);
k += 1;
}
if (p->fix_tx == false) {
working_space[2 * shift + k] =
Dertx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel],
working_space[peak_vel + 12]);
k += 1;
}
if (p->fix_ty == false) {
working_space[2 * shift + k] =
Derty(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_sx == false) {
working_space[2 * shift + k] =
Dersx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel]);
k += 1;
}
if (p->fix_sy == false) {
working_space[2 * shift + k] =
Dersy(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1]);
k += 1;
}
if (p->fix_bx == false) {
working_space[2 * shift + k] =
Derbx(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
if (p->fix_by == false) {
working_space[2 * shift + k] =
Derby(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
k += 1;
}
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi_opt += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi_opt += (yw - f) * (yw - f) / ywm;
}
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else {
if (ywm == 0)
ywm = 1;
}
for (j = 0; j < rozmer; j++) {
for (k = 0; k < rozmer; k++) {
b = working_space[2 * shift +
j] * working_space[2 * shift +
k] / ywm;
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES)
b = b * (4 * yw - 2 * f) / ywm;
working_matrix[j][k] += b;
if (j == k)
working_space[3 * shift + j] += b;
}
}
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES)
b = (f * f - yw * yw) / (ywm * ywm);
else
b = (f - yw) / ywm;
for (j = 0; j < rozmer; j++) {
working_matrix[j][rozmer] -=
b * working_space[2 * shift + j];
}
}
}
for (i = 0; i < rozmer; i++) {
working_matrix[i][rozmer + 1] = 0; //xk
}
StiefelInversion(working_matrix, rozmer);
for (i = 0; i < rozmer; i++) {
working_space[2 * shift + i] = working_matrix[i][rozmer + 1]; //der
}
//calculate chi_opt
chi2 = chi_opt;
chi_opt = TMath::Sqrt(TMath::Abs(chi_opt));
//calculate new parameters
regul_cycle = 0;
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = working_space[shift + j]; //temp_xk[j]=xk[j]
}
do {
if (p->alpha_optim == FIT2_ALPHA_OPTIMAL) {
if (p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD)
chi_min = 10000 * chi2;
else
chi_min = 0.1 * chi2;
flag = 0;
for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi2 = 0;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1,
(double) i2, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi2 += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi2 += (yw - f) * (yw - f) / ywm;
}
}
}
if (chi2 < chi_min
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD
|| chi2 > chi_min
&& p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
pmin = pi, chi_min = chi2;
}
else
flag = 1;
if (pi == 0.1)
chi_min = chi2;
chi = chi_min;
}
if (pmin != 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pmin*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi = chi_min;
}
}
else {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
}
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
if (p->fix_amp[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
j += 1;
}
if (p->fix_position_x[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
j += 1;
}
if (p->fix_position_y[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
j += 1;
}
if (p->fix_amp_x1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
j += 1;
}
if (p->fix_amp_y1[i] == false) {
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = 0; //xk[j]
working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
j += 1;
}
if (p->fix_position_x1[i] == false) {
if (working_space[shift + j] < p->xmin) //xk[j]
working_space[shift + j] = p->xmin; //xk[j]
if (working_space[shift + j] > p->xmax) //xk[j]
working_space[shift + j] = p->xmax; //xk[j]
working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
j += 1;
}
if (p->fix_position_y1[i] == false) {
if (working_space[shift + j] < p->ymin) //xk[j]
working_space[shift + j] = p->ymin; //xk[j]
if (working_space[shift + j] > p->ymax) //xk[j]
working_space[shift + j] = p->ymax; //xk[j]
working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
j += 1;
}
}
if (p->fix_sigma_x == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
j += 1;
}
if (p->fix_sigma_y == false) {
if (working_space[shift + j] < 0.001) { //xk[j]
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
j += 1;
}
if (p->fix_ro == false) {
if (working_space[shift + j] < -1) { //xk[j]
working_space[shift + j] = -1; //xk[j]
}
if (working_space[shift + j] > 1) { //xk[j]
working_space[shift + j] = 1; //xk[j]
}
working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
j += 1;
}
if (p->fix_a0 == false) {
working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
j += 1;
}
if (p->fix_ax == false) {
working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
j += 1;
}
if (p->fix_ay == false) {
working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
j += 1;
}
if (p->fix_txy == false) {
working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
j += 1;
}
if (p->fix_sxy == false) {
working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
j += 1;
}
if (p->fix_tx == false) {
working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
j += 1;
}
if (p->fix_ty == false) {
working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
j += 1;
}
if (p->fix_sx == false) {
working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
j += 1;
}
if (p->fix_sy == false) {
working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
j += 1;
}
if (p->fix_bx == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
j += 1;
}
if (p->fix_by == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
if (working_space[shift + j] < 0) //xk[j]
working_space[shift + j] = -0.001; //xk[j]
else
working_space[shift + j] = 0.001; //xk[j]
}
working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
j += 1;
}
chi = 0;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
ywm = yw;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (p->statistic_type == FIT2_OPTIM_CHI_FUNC_VALUES) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD) {
if (f > 0.00001)
chi += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi += (yw - f) * (yw - f) / ywm;
}
}
}
}
chi2 = chi;
chi = TMath::Sqrt(TMath::Abs(chi));
if (p->alpha_optim == FIT2_ALPHA_HALVING && chi > 1E-6)
alpha = alpha * chi_opt / (2 * chi);
else if (p->alpha_optim == FIT2_ALPHA_OPTIMAL)
alpha = alpha / 10.0;
iter += 1;
regul_cycle += 1;
} while ((chi > chi_opt
&& p->statistic_type != FIT2_OPTIM_MAX_LIKELIHOOD
|| chi < chi_opt
&& p->statistic_type == FIT2_OPTIM_MAX_LIKELIHOOD)
&& regul_cycle < FIT2_NUM_OF_REGUL_CYCLES);
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = 0; //temp_xk[j]
working_space[2 * shift + j] = 0; //der[j]
}
for (i1 = p->xmin, chi_cel = 0; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
yw = source[i1][i2];
if (yw == 0)
yw = 1;
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
chi_opt = (yw - f) * (yw - f) / yw;
chi_cel += (yw - f) * (yw - f) / yw;
//calculate gradient vector
for (j = 0, k = 0; j < p->number_of_peaks; j++) {
if (p->fix_amp[j] == false) {
a = Deramp2((double) i1, (double) i2,
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_x[j] == false) {
a = Deri02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_y[j] == false) {
a = Derj02((double) i1, (double) i2,
working_space[7 * j],
working_space[7 * j + 1],
working_space[7 * j + 2],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_amp_x1[j] == false) {
a = Derampx((double) i1, working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_amp_y1[j] == false) {
a = Derampx((double) i2, working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_x1[j] == false) {
a = Deri01((double) i1, working_space[7 * j + 3],
working_space[7 * j + 5],
working_space[peak_vel],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_position_y1[j] == false) {
a = Deri01((double) i2, working_space[7 * j + 4],
working_space[7 * j + 6],
working_space[peak_vel + 1],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
}
if (p->fix_sigma_x == false) {
a = Dersigmax(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 10],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_sigma_y == false) {
a = Dersigmay(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 9],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_ro == false) {
a = Derro(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_a0 == false) {
a = 1.;
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_ax == false) {
a = i1;
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_ay == false) {
a = i2;
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_txy == false) {
a = Dertxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_sxy == false) {
a = Dersxy(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_tx == false) {
a = Dertx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel],
working_space[peak_vel + 12]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_ty == false) {
a = Derty(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_sx == false) {
a = Dersx(p->number_of_peaks, (double) i1, working_space,
working_space[peak_vel]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_sy == false) {
a = Dersy(p->number_of_peaks, (double) i2, working_space,
working_space[peak_vel + 1]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_bx == false) {
a = Derbx(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
if (p->fix_by == false) {
a = Derby(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 6],
working_space[peak_vel + 8],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt; //der[k]
b = a * a / yw;
working_space[4 * shift + k] += b; //temp_xk[k]
}
k += 1;
}
}
}
}
b = (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1) - rozmer;
chi_er = chi_cel / b;
for (i = 0, j = 0; i < p->number_of_peaks; i++) {
p->volume[i] =
Volume(working_space[7 * i], working_space[peak_vel],
working_space[peak_vel + 1], working_space[peak_vel + 2]);
if (p->volume[i] > 0) {
c = 0;
if (p->fix_amp[i] == false) {
a = Derpa2(working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + j]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_sigma_x == false) {
a = Derpsigmax(working_space[shift + j],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_sigma_y == false) {
a = Derpsigmay(working_space[shift + j],
working_space[peak_vel],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel + 1]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
if (p->fix_ro == false) {
a = Derpro(working_space[shift + j], working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + peak_vel + 2]; //temp_xk[j]
if (b == 0)
b = 1;
else
b = 1 / b;
c = c + a * a * b;
}
p->volume_err[i] = TMath::Sqrt(TMath::Abs(chi_er * c));
}
else {
p->volume_err[i] = 0;
}
if (p->fix_amp[i] == false) {
p->amp_calc[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc[i] = p->amp_init[i];
p->amp_err[i] = 0;
}
if (p->fix_position_x[i] == false) {
p->position_calc_x[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_x[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_x[i] = p->position_init_x[i];
p->position_err_x[i] = 0;
}
if (p->fix_position_y[i] == false) {
p->position_calc_y[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_y[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_y[i] = p->position_init_y[i];
p->position_err_y[i] = 0;
}
if (p->fix_amp_x1[i] == false) {
p->amp_calc_x1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err_x1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc_x1[i] = p->amp_init_x1[i];
p->amp_err_x1[i] = 0;
}
if (p->fix_amp_y1[i] == false) {
p->amp_calc_y1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->amp_err_y1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->amp_calc_y1[i] = p->amp_init_y1[i];
p->amp_err_y1[i] = 0;
}
if (p->fix_position_x1[i] == false) {
p->position_calc_x1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_x1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_x1[i] = p->position_init_x1[i];
p->position_err_x1[i] = 0;
}
if (p->fix_position_y1[i] == false) {
p->position_calc_y1[i] = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0)
p->position_err_y1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->position_calc_y1[i] = p->position_init_y1[i];
p->position_err_y1[i] = 0;
}
}
if (p->fix_sigma_x == false) {
p->sigma_calc_x = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sigma_err_x = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sigma_calc_x = p->sigma_init_x;
p->sigma_err_x = 0;
}
if (p->fix_sigma_y == false) {
p->sigma_calc_y = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sigma_err_y = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sigma_calc_y = p->sigma_init_y;
p->sigma_err_y = 0;
}
if (p->fix_ro == false) {
p->ro_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ro_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ro_calc = p->ro_init;
p->ro_err = 0;
}
if (p->fix_a0 == false) {
p->a0_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->a0_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->a0_calc = p->a0_init;
p->a0_err = 0;
}
if (p->fix_ax == false) {
p->ax_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ax_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ax_calc = p->ax_init;
p->ax_err = 0;
}
if (p->fix_ay == false) {
p->ay_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ay_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ay_calc = p->ay_init;
p->ay_err = 0;
}
if (p->fix_txy == false) {
p->txy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->txy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->txy_calc = p->txy_init;
p->txy_err = 0;
}
if (p->fix_sxy == false) {
p->sxy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sxy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sxy_calc = p->sxy_init;
p->sxy_err = 0;
}
if (p->fix_tx == false) {
p->tx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->tx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->tx_calc = p->tx_init;
p->tx_err = 0;
}
if (p->fix_ty == false) {
p->ty_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->ty_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->ty_calc = p->ty_init;
p->ty_err = 0;
}
if (p->fix_sx == false) {
p->sx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sx_calc = p->sx_init;
p->sx_err = 0;
}
if (p->fix_sy == false) {
p->sy_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->sy_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->sy_calc = p->sy_init;
p->sy_err = 0;
}
if (p->fix_bx == false) {
p->bx_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->bx_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->bx_calc = p->bx_init;
p->bx_err = 0;
}
if (p->fix_by == false) {
p->by_calc = working_space[shift + j]; //xk[j]
if (working_space[3 * shift + j] != 0) //temp[j]
p->by_err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
j += 1;
}
else {
p->by_calc = p->by_init;
p->by_err = 0;
}
b = (p->xmax - p->xmin + 1) * (p->ymax - p->ymin + 1) - rozmer;
p->chi = chi_cel / b;
for (i1 = p->xmin; i1 <= p->xmax; i1++) {
for (i2 = p->ymin; i2 <= p->ymax; i2++) {
f = Shape2(p->number_of_peaks, (double) i1, (double) i2,
working_space, working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2],
working_space[peak_vel + 3],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6],
working_space[peak_vel + 7],
working_space[peak_vel + 8],
working_space[peak_vel + 9],
working_space[peak_vel + 10],
working_space[peak_vel + 11],
working_space[peak_vel + 12],
working_space[peak_vel + 13]);
source[i1][i2] = f;
} } for (i = 0; i < rozmer; i++)
delete[]working_matrix[i];
delete[]working_matrix;
delete[]working_space;
return 0;
}
//______________________________________________________________________________
//////////AUXILIARY FUNCTIONS FOR TRANSFORM BASED FUNCTIONS////////////////////////
void TSpectrum2::Haar(float *working_space, int num, int direction)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates Haar transform of a part of data //
// Function parameters: //
// -working_space-pointer to vector of transformed data //
// -num-length of processed data //
// -direction-forward or inverse transform //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, ii, li, l2, l3, j, jj, jj1, lj, iter, m, jmin, jmax;
double a, b, c, wlk;
float val;
for (i = 0; i < num; i++)
working_space[i + num] = 0;
i = num;
iter = 0;
for (; i > 1;) {
iter += 1;
i = i / 2;
}
if (direction == TRANSFORM2_FORWARD) {
for (m = 1; m <= iter; m++) {
li = iter + 1 - m;
l2 = (int) TMath::Power(2, li - 1);
for (i = 0; i < (2 * l2); i++) {
working_space[num + i] = working_space[i];
}
for (j = 0; j < l2; j++) {
l3 = l2 + j;
jj = 2 * j;
val = working_space[jj + num] + working_space[jj + 1 + num];
working_space[j] = val;
val = working_space[jj + num] - working_space[jj + 1 + num];
working_space[l3] = val;
}
}
}
val = working_space[0];
val = val / TMath::Sqrt(TMath::Power(2, iter));
working_space[0] = val;
val = working_space[1];
val = val / TMath::Sqrt(TMath::Power(2, iter));
working_space[1] = val;
for (ii = 2; ii <= iter; ii++) {
i = ii - 1;
wlk = 1 / TMath::Sqrt(TMath::Power(2, iter - i));
jmin = (int) TMath::Power(2, i);
jmax = (int) TMath::Power(2, ii) - 1;
for (j = jmin; j <= jmax; j++) {
val = working_space[j];
a = val;
a = a * wlk;
val = a;
working_space[j] = val;
}
}
if (direction == TRANSFORM2_INVERSE) {
for (m = 1; m <= iter; m++) {
a = 2;
b = m - 1;
c = TMath::Power(a, b);
li = (int) c;
for (i = 0; i < (2 * li); i++) {
working_space[i + num] = working_space[i];
}
for (j = 0; j < li; j++) {
lj = li + j;
jj = 2 * (j + 1) - 1;
jj1 = jj - 1;
val = working_space[j + num] - working_space[lj + num];
working_space[jj] = val;
val = working_space[j + num] + working_space[lj + num];
working_space[jj1] = val;
}
}
}
return;
}
void TSpectrum2::Walsh(float *working_space, int num)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates Walsh transform of a part of data //
// Function parameters: //
// -working_space-pointer to vector of transformed data //
// -num-length of processed data //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, m, nump = 1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter;
double a;
float val1, val2;
for (i = 0; i < num; i++)
working_space[i + num] = 0;
i = num;
iter = 0;
for (; i > 1;) {
iter += 1;
i = i / 2;
}
for (m = 1; m <= iter; m++) {
if (m == 1)
nump = 1;
else
nump = nump * 2;
mnum = num / nump;
mnum2 = mnum / 2;
for (mp = 0; mp < nump; mp++) {
ib = mp * mnum;
for (mp2 = 0; mp2 < mnum2; mp2++) {
mnum21 = mnum2 + mp2 + ib;
iba = ib + mp2;
val1 = working_space[iba];
val2 = working_space[mnum21];
working_space[iba + num] = val1 + val2;
working_space[mnum21 + num] = val1 - val2;
}
}
for (i = 0; i < num; i++) {
working_space[i] = working_space[i + num];
}
}
a = num;
a = TMath::Sqrt(a);
val2 = a;
for (i = 0; i < num; i++) {
val1 = working_space[i];
val1 = val1 / val2;
working_space[i] = val1;
}
return;
}
void TSpectrum2::BitReverse(float *working_space, int num)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion carries out bir-reverse reordering of data //
// Function parameters: //
// -working_space-pointer to vector of processed data //
// -num-length of processed data //
// //
//////////////////////////////////////////////////////////////////////////////////
int ipower[26];
int i, ib, il, ibd, ip, ifac, i1;
for (i = 0; i < num; i++) {
working_space[i + num] = working_space[i];
}
for (i = 1; i <= num; i++) {
ib = i - 1;
il = 1;
lab9:ibd = ib / 2;
ipower[il - 1] = 1;
if (ib == (ibd * 2))
ipower[il - 1] = 0;
if (ibd == 0)
goto lab10;
ib = ibd;
il = il + 1;
goto lab9;
lab10:ip = 1;
ifac = num;
for (i1 = 1; i1 <= il; i1++) {
ifac = ifac / 2;
ip = ip + ifac * ipower[i1 - 1];
}
working_space[ip - 1] = working_space[i - 1 + num];
}
return;
}
void TSpectrum2::Fourier(float *working_space, int num, int hartley,
int direction, int zt_clear)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates Fourier based transform of a part of data //
// Function parameters: //
// -working_space-pointer to vector of transformed data //
// -num-length of processed data //
// -hartley-1 if it is Hartley transform, 0 othewise //
// -direction-forward or inverse transform //
// //
//////////////////////////////////////////////////////////////////////////////////
int nxp2, nxp, i, j, k, m, iter, mxp, j1, j2, n1, n2, it;
double a, b, c, d, sign, wpwr, arg, wr, wi, tr, ti, pi =
3.14159265358979323846;
float val1, val2, val3, val4;
if (direction == TRANSFORM2_FORWARD && zt_clear == 0) {
for (i = 0; i < num; i++)
working_space[i + num] = 0;
}
i = num;
iter = 0;
for (; i > 1;) {
iter += 1;
i = i / 2;
}
sign = -1;
if (direction == TRANSFORM2_INVERSE)
sign = 1;
nxp2 = num;
for (it = 1; it <= iter; it++) {
nxp = nxp2;
nxp2 = nxp / 2;
a = nxp2;
wpwr = pi / a;
for (m = 1; m <= nxp2; m++) {
a = m - 1;
arg = a * wpwr;
wr = TMath::Cos(arg);
wi = sign * TMath::Sin(arg);
for (mxp = nxp; mxp <= num; mxp += nxp) {
j1 = mxp - nxp + m;
j2 = j1 + nxp2;
val1 = working_space[j1 - 1];
val2 = working_space[j2 - 1];
val3 = working_space[j1 - 1 + num];
val4 = working_space[j2 - 1 + num];
a = val1;
b = val2;
c = val3;
d = val4;
tr = a - b;
ti = c - d;
a = a + b;
val1 = a;
working_space[j1 - 1] = val1;
c = c + d;
val1 = c;
working_space[j1 - 1 + num] = val1;
a = tr * wr - ti * wi;
val1 = a;
working_space[j2 - 1] = val1;
a = ti * wr + tr * wi;
val1 = a;
working_space[j2 - 1 + num] = val1;
}
}
}
n2 = num / 2;
n1 = num - 1;
j = 1;
for (i = 1; i <= n1; i++) {
if (i >= j)
goto lab55;
val1 = working_space[j - 1];
val2 = working_space[j - 1 + num];
val3 = working_space[i - 1];
working_space[j - 1] = val3;
working_space[j - 1 + num] = working_space[i - 1 + num];
working_space[i - 1] = val1;
working_space[i - 1 + num] = val2;
lab55:k = n2;
lab60:if (k >= j)
goto lab65;
j = j - k;
k = k / 2;
goto lab60;
lab65:j = j + k;
}
a = num;
a = TMath::Sqrt(a);
for (i = 0; i < num; i++) {
if (hartley == 0) {
val1 = working_space[i];
b = val1;
b = b / a;
val1 = b;
working_space[i] = val1;
b = working_space[i + num];
b = b / a;
working_space[i + num] = b;
}
else {
b = working_space[i];
c = working_space[i + num];
b = (b + c) / a;
working_space[i] = b;
working_space[i + num] = 0;
}
}
if (hartley == 1 && direction == TRANSFORM2_INVERSE) {
for (i = 1; i < num; i++)
working_space[num - i + num] = working_space[i];
working_space[0 + num] = working_space[0];
for (i = 0; i < num; i++) {
working_space[i] = working_space[i + num];
working_space[i + num] = 0;
}
}
return;
}
void TSpectrum2::BitReverseHaar(float *working_space, int shift, int num,
int start)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion carries out bir-reverse reordering for Haar transform //
// Function parameters: //
// -working_space-pointer to vector of processed data //
// -shift-shift of position of processing //
// -start-initial position of processed data //
// -num-length of processed data //
// //
//////////////////////////////////////////////////////////////////////////////////
int ipower[26];
int i, ib, il, ibd, ip, ifac, i1;
for (i = 0; i < num; i++) {
working_space[i + shift + start] = working_space[i + start];
working_space[i + shift + start + 2 * shift] =
working_space[i + start + 2 * shift];
}
for (i = 1; i <= num; i++) {
ib = i - 1;
il = 1;
lab9:ibd = ib / 2;
ipower[il - 1] = 1;
if (ib == (ibd * 2))
ipower[il - 1] = 0;
if (ibd == 0)
goto lab10;
ib = ibd;
il = il + 1;
goto lab9;
lab10:ip = 1;
ifac = num;
for (i1 = 1; i1 <= il; i1++) {
ifac = ifac / 2;
ip = ip + ifac * ipower[i1 - 1];
}
working_space[ip - 1 + start] =
working_space[i - 1 + shift + start];
working_space[ip - 1 + start + 2 * shift] =
working_space[i - 1 + shift + start + 2 * shift];
}
return;
}
int TSpectrum2::GeneralExe(float *working_space, int zt_clear, int num,
int degree, int type)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates generalized (mixed) transforms of different degrees//
// Function parameters: //
// -working_space-pointer to vector of transformed data //
// -zt_clear-flag to clear imaginary data before staring //
// -num-length of processed data //
// -degree-degree of transform (see manual) //
// -type-type of mixed transform (see manual) //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j, k, m, nump, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter,
mp2step, mppom, ring;
double a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
3.14159265358979323846;
float val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
if (zt_clear == 0) {
for (i = 0; i < num; i++)
working_space[i + 2 * num] = 0;
}
i = num;
iter = 0;
for (; i > 1;) {
iter += 1;
i = i / 2;
}
a = num;
wpwr = 2.0 * pi / a;
nump = num;
mp2step = 1;
ring = num;
for (i = 0; i < iter - degree; i++)
ring = ring / 2;
for (m = 1; m <= iter; m++) {
nump = nump / 2;
mnum = num / nump;
mnum2 = mnum / 2;
if (m > degree
&& (type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR
|| type == TRANSFORM2_COS_HAAR
|| type == TRANSFORM2_SIN_HAAR))
mp2step *= 2;
if (ring > 1)
ring = ring / 2;
for (mp = 0; mp < nump; mp++) {
if (type != TRANSFORM2_WALSH_HAAR) {
mppom = mp;
mppom = mppom % ring;
a = 0;
j = 1;
k = num / 4;
for (i = 0; i < (iter - 1); i++) {
if ((mppom & j) != 0)
a = a + k;
j = j * 2;
k = k / 2;
}
arg = a * wpwr;
wr = TMath::Cos(arg);
wi = TMath::Sin(arg);
}
else {
wr = 1;
wi = 0;
}
ib = mp * mnum;
for (mp2 = 0; mp2 < mnum2; mp2++) {
mnum21 = mnum2 + mp2 + ib;
iba = ib + mp2;
if (mp2 % mp2step == 0) {
a0r = a0oldr;
b0r = b0oldr;
a0r = 1 / TMath::Sqrt(2.0);
b0r = 1 / TMath::Sqrt(2.0);
}
else {
a0r = 1;
b0r = 0;
}
val1 = working_space[iba];
val2 = working_space[mnum21];
val3 = working_space[iba + 2 * num];
val4 = working_space[mnum21 + 2 * num];
a = val1;
b = val2;
c = val3;
d = val4;
tr = a * a0r + b * b0r;
val1 = tr;
working_space[num + iba] = val1;
ti = c * a0r + d * b0r;
val1 = ti;
working_space[num + iba + 2 * num] = val1;
tr =
a * b0r * wr - c * b0r * wi - b * a0r * wr + d * a0r * wi;
val1 = tr;
working_space[num + mnum21] = val1;
ti =
c * b0r * wr + a * b0r * wi - d * a0r * wr - b * a0r * wi;
val1 = ti;
working_space[num + mnum21 + 2 * num] = val1;
}
}
for (i = 0; i < num; i++) {
val1 = working_space[num + i];
working_space[i] = val1;
val1 = working_space[num + i + 2 * num];
working_space[i + 2 * num] = val1;
}
}
return (0);
}
int TSpectrum2::GeneralInv(float *working_space, int num, int degree,
int type)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates inverse generalized (mixed) transforms //
// Function parameters: //
// -working_space-pointer to vector of transformed data //
// -num-length of processed data //
// -degree-degree of transform (see manual) //
// -type-type of mixed transform (see manual) //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j, k, m, nump =
1, mnum, mnum2, mp, ib, mp2, mnum21, iba, iter, mp2step, mppom,
ring;
double a, b, c, d, wpwr, arg, wr, wi, tr, ti, pi =
3.14159265358979323846;
float val1, val2, val3, val4, a0oldr = 0, b0oldr = 0, a0r, b0r;
i = num;
iter = 0;
for (; i > 1;) {
iter += 1;
i = i / 2;
}
a = num;
wpwr = 2.0 * pi / a;
mp2step = 1;
if (type == TRANSFORM2_FOURIER_HAAR || type == TRANSFORM2_WALSH_HAAR
|| type == TRANSFORM2_COS_HAAR || type == TRANSFORM2_SIN_HAAR) {
for (i = 0; i < iter - degree; i++)
mp2step *= 2;
}
ring = 1;
for (m = 1; m <= iter; m++) {
if (m == 1)
nump = 1;
else
nump = nump * 2;
mnum = num / nump;
mnum2 = mnum / 2;
if (m > iter - degree + 1)
ring *= 2;
for (mp = nump - 1; mp >= 0; mp--) {
if (type != TRANSFORM2_WALSH_HAAR) {
mppom = mp;
mppom = mppom % ring;
a = 0;
j = 1;
k = num / 4;
for (i = 0; i < (iter - 1); i++) {
if ((mppom & j) != 0)
a = a + k;
j = j * 2;
k = k / 2;
}
arg = a * wpwr;
wr = TMath::Cos(arg);
wi = TMath::Sin(arg);
}
else {
wr = 1;
wi = 0;
}
ib = mp * mnum;
for (mp2 = 0; mp2 < mnum2; mp2++) {
mnum21 = mnum2 + mp2 + ib;
iba = ib + mp2;
if (mp2 % mp2step == 0) {
a0r = a0oldr;
b0r = b0oldr;
a0r = 1 / TMath::Sqrt(2.0);
b0r = 1 / TMath::Sqrt(2.0);
}
else {
a0r = 1;
b0r = 0;
}
val1 = working_space[iba];
val2 = working_space[mnum21];
val3 = working_space[iba + 2 * num];
val4 = working_space[mnum21 + 2 * num];
a = val1;
b = val2;
c = val3;
d = val4;
tr = a * a0r + b * wr * b0r + d * wi * b0r;
val1 = tr;
working_space[num + iba] = val1;
ti = c * a0r + d * wr * b0r - b * wi * b0r;
val1 = ti;
working_space[num + iba + 2 * num] = val1;
tr = a * b0r - b * wr * a0r - d * wi * a0r;
val1 = tr;
working_space[num + mnum21] = val1;
ti = c * b0r - d * wr * a0r + b * wi * a0r;
val1 = ti;
working_space[num + mnum21 + 2 * num] = val1;
}
}
if (m <= iter - degree
&& (type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR
|| type == TRANSFORM2_COS_HAAR
|| type == TRANSFORM2_SIN_HAAR))
mp2step /= 2;
for (i = 0; i < num; i++) {
val1 = working_space[num + i];
working_space[i] = val1;
val1 = working_space[num + i + 2 * num];
working_space[i + 2 * num] = val1;
}
}
return (0);
}
void TSpectrum2::HaarWalsh2(float **working_matrix,
float *working_vector, int numx, int numy,
int direction, int type)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates 2D Haar and Walsh transforms //
// Function parameters: //
// -working_matrix-pointer to matrix of transformed data //
// -working_vector-pointer to vector where the data are processed //
// -numx,numy-lengths of processed data //
// -direction-forward or inverse //
// -type-type of transform (see manual) //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j;
if (direction == TRANSFORM2_FORWARD) {
for (j = 0; j < numy; j++) {
for (i = 0; i < numx; i++) {
working_vector[i] = working_matrix[i][j];
}
switch (type) {
case TRANSFORM2_HAAR:
Haar(working_vector, numx, TRANSFORM2_FORWARD);
break;
case TRANSFORM2_WALSH:
Walsh(working_vector, numx);
BitReverse(working_vector, numx);
break;
}
for (i = 0; i < numx; i++) {
working_matrix[i][j] = working_vector[i];
}
}
for (i = 0; i < numx; i++) {
for (j = 0; j < numy; j++) {
working_vector[j] = working_matrix[i][j];
}
switch (type) {
case TRANSFORM2_HAAR:
Haar(working_vector, numy, TRANSFORM2_FORWARD);
break;
case TRANSFORM2_WALSH:
Walsh(working_vector, numy);
BitReverse(working_vector, numy);
break;
}
for (j = 0; j < numy; j++) {
working_matrix[i][j] = working_vector[j];
}
}
}
else if (direction == TRANSFORM2_INVERSE) {
for (i = 0; i < numx; i++) {
for (j = 0; j < numy; j++) {
working_vector[j] = working_matrix[i][j];
}
switch (type) {
case TRANSFORM2_HAAR:
Haar(working_vector, numy, TRANSFORM2_INVERSE);
break;
case TRANSFORM2_WALSH:
BitReverse(working_vector, numy);
Walsh(working_vector, numy);
break;
}
for (j = 0; j < numy; j++) {
working_matrix[i][j] = working_vector[j];
}
}
for (j = 0; j < numy; j++) {
for (i = 0; i < numx; i++) {
working_vector[i] = working_matrix[i][j];
}
switch (type) {
case TRANSFORM2_HAAR:
Haar(working_vector, numx, TRANSFORM2_INVERSE);
break;
case TRANSFORM2_WALSH:
BitReverse(working_vector, numx);
Walsh(working_vector, numx);
break;
}
for (i = 0; i < numx; i++) {
working_matrix[i][j] = working_vector[i];
}
}
}
return;
}
void TSpectrum2::FourCos2(float **working_matrix, float *working_vector,
int numx, int numy, int direction, int type)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates 2D Fourier based transforms //
// Function parameters: //
// -working_matrix-pointer to matrix of transformed data //
// -working_vector-pointer to vector where the data are processed //
// -numx,numy-lengths of processed data //
// -direction-forward or inverse //
// -type-type of transform (see manual) //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j, iterx, itery, n, size;
double pi = 3.14159265358979323846;
j = 0;
n = 1;
for (; n < numx;) {
j += 1;
n = n * 2;
}
j = 0;
n = 1;
for (; n < numy;) {
j += 1;
n = n * 2;
}
i = numx;
iterx = 0;
for (; i > 1;) {
iterx += 1;
i = i / 2;
}
i = numy;
itery = 0;
for (; i > 1;) {
itery += 1;
i = i / 2;
}
size = numx;
if (size < numy)
size = numy;
if (direction == TRANSFORM2_FORWARD) {
for (j = 0; j < numy; j++) {
for (i = 0; i < numx; i++) {
working_vector[i] = working_matrix[i][j];
}
switch (type) {
case TRANSFORM2_COS:
for (i = 1; i <= numx; i++) {
working_vector[2 * numx - i] = working_vector[i - 1];
}
Fourier(working_vector, 2 * numx, 0, TRANSFORM2_FORWARD, 0);
for (i = 0; i < numx; i++) {
working_vector[i] =
working_vector[i] / TMath::Cos(pi * i / (2 * numx));
}
working_vector[0] = working_vector[0] / TMath::Sqrt(2.);
break;
case TRANSFORM2_SIN:
for (i = 1; i <= numx; i++) {
working_vector[2 * numx - i] = -working_vector[i - 1];
}
Fourier(working_vector, 2 * numx, 0, TRANSFORM2_FORWARD, 0);
for (i = 1; i < numx; i++) {
working_vector[i - 1] =
working_vector[i] / TMath::Sin(pi * i / (2 * numx));
}
working_vector[numx - 1] =
working_vector[numx] / TMath::Sqrt(2.);
break;
case TRANSFORM2_FOURIER:
Fourier(working_vector, numx, 0, TRANSFORM2_FORWARD, 0);
break;
case TRANSFORM2_HARTLEY:
Fourier(working_vector, numx, 1, TRANSFORM2_FORWARD, 0);
break;
}
for (i = 0; i < numx; i++) {
working_matrix[i][j] = working_vector[i];
if (type == TRANSFORM2_FOURIER)
working_matrix[i][j + numy] = working_vector[i + numx];
else
working_matrix[i][j + numy] = working_vector[i + 2 * numx];
}
}
for (i = 0; i < numx; i++) {
for (j = 0; j < numy; j++) {
working_vector[j] = working_matrix[i][j];
if (type == TRANSFORM2_FOURIER)
working_vector[j + numy] = working_matrix[i][j + numy];
else
working_vector[j + 2 * numy] = working_matrix[i][j + numy];
}
switch (type) {
case TRANSFORM2_COS:
for (j = 1; j <= numy; j++) {
working_vector[2 * numy - j] = working_vector[j - 1];
}
Fourier(working_vector, 2 * numy, 0, TRANSFORM2_FORWARD, 0);
for (j = 0; j < numy; j++) {
working_vector[j] =
working_vector[j] / TMath::Cos(pi * j / (2 * numy));
working_vector[j + 2 * numy] = 0;
}
working_vector[0] = working_vector[0] / TMath::Sqrt(2.);
break;
case TRANSFORM2_SIN:
for (j = 1; j <= numy; j++) {
working_vector[2 * numy - j] = -working_vector[j - 1];
}
Fourier(working_vector, 2 * numy, 0, TRANSFORM2_FORWARD, 0);
for (j = 1; j < numy; j++) {
working_vector[j - 1] =
working_vector[j] / TMath::Sin(pi * j / (2 * numy));
working_vector[j + numy] = 0;
}
working_vector[numy - 1] =
working_vector[numy] / TMath::Sqrt(2.);
working_vector[numy] = 0;
break;
case TRANSFORM2_FOURIER:
Fourier(working_vector, numy, 0, TRANSFORM2_FORWARD, 1);
break;
case TRANSFORM2_HARTLEY:
Fourier(working_vector, numy, 1, TRANSFORM2_FORWARD, 0);
break;
}
for (j = 0; j < numy; j++) {
working_matrix[i][j] = working_vector[j];
if (type == TRANSFORM2_FOURIER)
working_matrix[i][j + numy] = working_vector[j + numy];
else
working_matrix[i][j + numy] = working_vector[j + 2 * numy];
}
}
}
else if (direction == TRANSFORM2_INVERSE) {
for (i = 0; i < numx; i++) {
for (j = 0; j < numy; j++) {
working_vector[j] = working_matrix[i][j];
if (type == TRANSFORM2_FOURIER)
working_vector[j + numy] = working_matrix[i][j + numy];
else
working_vector[j + 2 * numy] = working_matrix[i][j + numy];
}
switch (type) {
case TRANSFORM2_COS:
working_vector[0] = working_vector[0] * TMath::Sqrt(2.);
for (j = 0; j < numy; j++) {
working_vector[j + 2 * numy] =
working_vector[j] * TMath::Sin(pi * j / (2 * numy));
working_vector[j] =
working_vector[j] * TMath::Cos(pi * j / (2 * numy));
}
for (j = 1; j < numy; j++) {
working_vector[2 * numy - j] = working_vector[j];
working_vector[2 * numy - j + 2 * numy] =
-working_vector[j + 2 * numy];
}
working_vector[numy] = 0;
working_vector[numy + 2 * numy] = 0;
Fourier(working_vector, 2 * numy, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_SIN:
working_vector[numy] =
working_vector[numy - 1] * TMath::Sqrt(2.);
for (j = numy - 1; j > 0; j--) {
working_vector[j + 2 * numy] =
-working_vector[j -
1] * TMath::Cos(pi * j / (2 * numy));
working_vector[j] =
working_vector[j - 1] * TMath::Sin(pi * j / (2 * numy));
}
for (j = 1; j < numy; j++) {
working_vector[2 * numy - j] = working_vector[j];
working_vector[2 * numy - j + 2 * numy] =
-working_vector[j + 2 * numy];
}
working_vector[0] = 0;
working_vector[0 + 2 * numy] = 0;
working_vector[numy + 2 * numy] = 0;
Fourier(working_vector, 2 * numy, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_FOURIER:
Fourier(working_vector, numy, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_HARTLEY:
Fourier(working_vector, numy, 1, TRANSFORM2_INVERSE, 1);
break;
}
for (j = 0; j < numy; j++) {
working_matrix[i][j] = working_vector[j];
if (type == TRANSFORM2_FOURIER)
working_matrix[i][j + numy] = working_vector[j + numy];
else
working_matrix[i][j + numy] = working_vector[j + 2 * numy];
}
}
for (j = 0; j < numy; j++) {
for (i = 0; i < numx; i++) {
working_vector[i] = working_matrix[i][j];
if (type == TRANSFORM2_FOURIER)
working_vector[i + numx] = working_matrix[i][j + numy];
else
working_vector[i + 2 * numx] = working_matrix[i][j + numy];
}
switch (type) {
case TRANSFORM2_COS:
working_vector[0] = working_vector[0] * TMath::Sqrt(2.);
for (i = 0; i < numx; i++) {
working_vector[i + 2 * numx] =
working_vector[i] * TMath::Sin(pi * i / (2 * numx));
working_vector[i] =
working_vector[i] * TMath::Cos(pi * i / (2 * numx));
}
for (i = 1; i < numx; i++) {
working_vector[2 * numx - i] = working_vector[i];
working_vector[2 * numx - i + 2 * numx] =
-working_vector[i + 2 * numx];
}
working_vector[numx] = 0;
working_vector[numx + 2 * numx] = 0;
Fourier(working_vector, 2 * numx, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_SIN:
working_vector[numx] =
working_vector[numx - 1] * TMath::Sqrt(2.);
for (i = numx - 1; i > 0; i--) {
working_vector[i + 2 * numx] =
-working_vector[i -
1] * TMath::Cos(pi * i / (2 * numx));
working_vector[i] =
working_vector[i - 1] * TMath::Sin(pi * i / (2 * numx));
}
for (i = 1; i < numx; i++) {
working_vector[2 * numx - i] = working_vector[i];
working_vector[2 * numx - i + 2 * numx] =
-working_vector[i + 2 * numx];
}
working_vector[0] = 0;
working_vector[0 + 2 * numx] = 0;
working_vector[numx + 2 * numx] = 0;
Fourier(working_vector, 2 * numx, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_FOURIER:
Fourier(working_vector, numx, 0, TRANSFORM2_INVERSE, 1);
break;
case TRANSFORM2_HARTLEY:
Fourier(working_vector, numx, 1, TRANSFORM2_INVERSE, 1);
break;
}
for (i = 0; i < numx; i++) {
working_matrix[i][j] = working_vector[i];
}
}
}
return;
}
void TSpectrum2::General2(float **working_matrix, float *working_vector,
int numx, int numy, int direction, int type,
int degree)
{
//////////////////////////////////////////////////////////////////////////////////
// AUXILIARY FUNCION //
// //
// This funcion calculates generalized (mixed) 2D transforms //
// Function parameters: //
// -working_matrix-pointer to matrix of transformed data //
// -working_vector-pointer to vector where the data are processed //
// -numx,numy-lengths of processed data //
// -direction-forward or inverse //
// -type-type of transform (see manual) //
// -degree-degree of transform (see manual) //
// //
//////////////////////////////////////////////////////////////////////////////////
int i, j, jstup, kstup, l, m;
float val, valx, valz;
double a, b, pi = 3.14159265358979323846;
if (direction == TRANSFORM2_FORWARD) {
for (j = 0; j < numy; j++) {
kstup = (int) TMath::Power(2, degree);
jstup = numx / kstup;
for (i = 0; i < numx; i++) {
val = working_matrix[i][j];
if (type == TRANSFORM2_COS_WALSH
|| type == TRANSFORM2_COS_HAAR) {
jstup = (int) TMath::Power(2, degree) / 2;
kstup = i / jstup;
kstup = 2 * kstup * jstup;
working_vector[kstup + i % jstup] = val;
working_vector[kstup + 2 * jstup - 1 - i % jstup] = val;
}
else if (type == TRANSFORM2_SIN_WALSH
|| type == TRANSFORM2_SIN_HAAR) {
jstup = (int) TMath::Power(2, degree) / 2;
kstup = i / jstup;
kstup = 2 * kstup * jstup;
working_vector[kstup + i % jstup] = val;
working_vector[kstup + 2 * jstup - 1 - i % jstup] = -val;
}
else
working_vector[i] = val;
}
switch (type) {
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
GeneralExe(working_vector, 0, numx, degree, type);
for (i = 0; i < jstup; i++)
BitReverseHaar(working_vector, numx, kstup, i * kstup);
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
m = (int) TMath::Power(2, degree);
l = 2 * numx / m;
for (i = 0; i < l; i++)
BitReverseHaar(working_vector, 2 * numx, m, i * m);
GeneralExe(working_vector, 0, 2 * numx, degree, type);
for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (i % jstup) / (double) (2 * jstup);
a = TMath::Cos(a);
b = working_vector[kstup + i % jstup];
if (i % jstup == 0)
a = b / TMath::Sqrt(2.0);
else
a = b / a;
working_vector[i] = a;
working_vector[i + 4 * numx] = 0;
}
break;
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
m = (int) TMath::Power(2, degree);
l = 2 * numx / m;
for (i = 0; i < l; i++)
BitReverseHaar(working_vector, 2 * numx, m, i * m);
GeneralExe(working_vector, 0, 2 * numx, degree, type);
for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (i % jstup) / (double) (2 * jstup);
a = TMath::Cos(a);
b = working_vector[jstup + kstup + i % jstup];
if (i % jstup == 0)
a = b / TMath::Sqrt(2.0);
else
a = b / a;
working_vector[jstup + kstup / 2 - i % jstup - 1] = a;
working_vector[i + 4 * numx] = 0;
}
break;
}
if (type > TRANSFORM2_WALSH_HAAR)
kstup = (int) TMath::Power(2, degree - 1);
else
kstup = (int) TMath::Power(2, degree);
jstup = numx / kstup;
for (i = 0, l = 0; i < numx; i++, l = (l + kstup) % numx) {
working_vector[numx + i] = working_vector[l + i / jstup];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[numx + i + 2 * numx] =
working_vector[l + i / jstup + 2 * numx];
else
working_vector[numx + i + 4 * numx] =
working_vector[l + i / jstup + 4 * numx];
}
for (i = 0; i < numx; i++) {
working_vector[i] = working_vector[numx + i];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[i + 2 * numx] =
working_vector[numx + i + 2 * numx];
else
working_vector[i + 4 * numx] =
working_vector[numx + i + 4 * numx];
}
for (i = 0; i < numx; i++) {
working_matrix[i][j] = working_vector[i];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_matrix[i][j + numy] = working_vector[i + 2 * numx];
else
working_matrix[i][j + numy] = working_vector[i + 4 * numx];
}
}
for (i = 0; i < numx; i++) {
kstup = (int) TMath::Power(2, degree);
jstup = numy / kstup;
for (j = 0; j < numy; j++) {
valx = working_matrix[i][j];
valz = working_matrix[i][j + numy];
if (type == TRANSFORM2_COS_WALSH
|| type == TRANSFORM2_COS_HAAR) {
jstup = (int) TMath::Power(2, degree) / 2;
kstup = j / jstup;
kstup = 2 * kstup * jstup;
working_vector[kstup + j % jstup] = valx;
working_vector[kstup + 2 * jstup - 1 - j % jstup] = valx;
working_vector[kstup + j % jstup + 4 * numy] = valz;
working_vector[kstup + 2 * jstup - 1 - j % jstup +
4 * numy] = valz;
}
else if (type == TRANSFORM2_SIN_WALSH
|| type == TRANSFORM2_SIN_HAAR) {
jstup = (int) TMath::Power(2, degree) / 2;
kstup = j / jstup;
kstup = 2 * kstup * jstup;
working_vector[kstup + j % jstup] = valx;
working_vector[kstup + 2 * jstup - 1 - j % jstup] = -valx;
working_vector[kstup + j % jstup + 4 * numy] = valz;
working_vector[kstup + 2 * jstup - 1 - j % jstup +
4 * numy] = -valz;
}
else {
working_vector[j] = valx;
working_vector[j + 2 * numy] = valz;
}
}
switch (type) {
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
GeneralExe(working_vector, 1, numy, degree, type);
for (j = 0; j < jstup; j++)
BitReverseHaar(working_vector, numy, kstup, j * kstup);
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
m = (int) TMath::Power(2, degree);
l = 2 * numy / m;
for (j = 0; j < l; j++)
BitReverseHaar(working_vector, 2 * numy, m, j * m);
GeneralExe(working_vector, 1, 2 * numy, degree, type);
for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (j % jstup) / (double) (2 * jstup);
a = TMath::Cos(a);
b = working_vector[kstup + j % jstup];
if (j % jstup == 0)
a = b / TMath::Sqrt(2.0);
else
a = b / a;
working_vector[j] = a;
working_vector[j + 4 * numy] = 0;
}
break;
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
m = (int) TMath::Power(2, degree);
l = 2 * numy / m;
for (j = 0; j < l; j++)
BitReverseHaar(working_vector, 2 * numy, m, j * m);
GeneralExe(working_vector, 1, 2 * numy, degree, type);
for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (j % jstup) / (double) (2 * jstup);
a = TMath::Cos(a);
b = working_vector[jstup + kstup + j % jstup];
if (j % jstup == 0)
a = b / TMath::Sqrt(2.0);
else
a = b / a;
working_vector[jstup + kstup / 2 - j % jstup - 1] = a;
working_vector[j + 4 * numy] = 0;
}
break;
}
if (type > TRANSFORM2_WALSH_HAAR)
kstup = (int) TMath::Power(2, degree - 1);
else
kstup = (int) TMath::Power(2, degree);
jstup = numy / kstup;
for (j = 0, l = 0; j < numy; j++, l = (l + kstup) % numy) {
working_vector[numy + j] = working_vector[l + j / jstup];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[numy + j + 2 * numy] =
working_vector[l + j / jstup + 2 * numy];
else
working_vector[numy + j + 4 * numy] =
working_vector[l + j / jstup + 4 * numy];
}
for (j = 0; j < numy; j++) {
working_vector[j] = working_vector[numy + j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[j + 2 * numy] =
working_vector[numy + j + 2 * numy];
else
working_vector[j + 4 * numy] =
working_vector[numy + j + 4 * numy];
}
for (j = 0; j < numy; j++) {
working_matrix[i][j] = working_vector[j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_matrix[i][j + numy] = working_vector[j + 2 * numy];
else
working_matrix[i][j + numy] = working_vector[j + 4 * numy];
}
}
}
else if (direction == TRANSFORM2_INVERSE) {
for (i = 0; i < numx; i++) {
kstup = (int) TMath::Power(2, degree);
jstup = numy / kstup;
for (j = 0; j < numy; j++) {
working_vector[j] = working_matrix[i][j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[j + 2 * numy] = working_matrix[i][j + numy];
else
working_vector[j + 4 * numy] = working_matrix[i][j + numy];
}
if (type > TRANSFORM2_WALSH_HAAR)
kstup = (int) TMath::Power(2, degree - 1);
else
kstup = (int) TMath::Power(2, degree);
jstup = numy / kstup;
for (j = 0, l = 0; j < numy; j++, l = (l + kstup) % numy) {
working_vector[numy + l + j / jstup] = working_vector[j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[numy + l + j / jstup + 2 * numy] =
working_vector[j + 2 * numy];
else
working_vector[numy + l + j / jstup + 4 * numy] =
working_vector[j + 4 * numy];
}
for (j = 0; j < numy; j++) {
working_vector[j] = working_vector[numy + j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[j + 2 * numy] =
working_vector[numy + j + 2 * numy];
else
working_vector[j + 4 * numy] =
working_vector[numy + j + 4 * numy];
}
switch (type) {
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
for (j = 0; j < jstup; j++)
BitReverseHaar(working_vector, numy, kstup, j * kstup);
GeneralInv(working_vector, numy, degree, type);
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
jstup = (int) TMath::Power(2, degree) / 2;
m = (int) TMath::Power(2, degree);
l = 2 * numy / m;
for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (j % jstup) / (double) (2 * jstup);
if (j % jstup == 0) {
working_vector[2 * numy + kstup + j % jstup] =
working_vector[j] * TMath::Sqrt(2.0);
working_vector[2 * numy + kstup + j % jstup +
4 * numy] = 0;
}
else {
b = TMath::Sin(a);
a = TMath::Cos(a);
working_vector[2 * numy + kstup + j % jstup +
4 * numy] =
-(double) working_vector[j] * b;
working_vector[2 * numy + kstup + j % jstup] =
(double) working_vector[j] * a;
} } for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
if (j % jstup == 0) {
working_vector[2 * numy + kstup + jstup] = 0;
working_vector[2 * numy + kstup + jstup + 4 * numy] = 0;
}
else {
working_vector[2 * numy + kstup + 2 * jstup -
j % jstup] =
working_vector[2 * numy + kstup + j % jstup];
working_vector[2 * numy + kstup + 2 * jstup -
j % jstup + 4 * numy] =
-working_vector[2 * numy + kstup + j % jstup +
4 * numy];
}
}
for (j = 0; j < 2 * numy; j++) {
working_vector[j] = working_vector[2 * numy + j];
working_vector[j + 4 * numy] =
working_vector[2 * numy + j + 4 * numy];
}
GeneralInv(working_vector, 2 * numy, degree, type);
m = (int) TMath::Power(2, degree);
l = 2 * numy / m;
for (j = 0; j < l; j++)
BitReverseHaar(working_vector, 2 * numy, m, j * m);
break;
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
jstup = (int) TMath::Power(2, degree) / 2;
m = (int) TMath::Power(2, degree);
l = 2 * numy / m;
for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (j % jstup) / (double) (2 * jstup);
if (j % jstup == 0) {
working_vector[2 * numy + kstup + jstup + j % jstup] =
working_vector[jstup + kstup / 2 - j % jstup -
1] * TMath::Sqrt(2.0);
working_vector[2 * numy + kstup + jstup + j % jstup +
4 * numy] = 0;
}
else {
b = TMath::Sin(a);
a = TMath::Cos(a);
working_vector[2 * numy + kstup + jstup + j % jstup +
4 * numy] =
-(double) working_vector[jstup + kstup / 2 -
j % jstup - 1] * b;
working_vector[2 * numy + kstup + jstup + j % jstup] =
(double) working_vector[jstup + kstup / 2 -
j % jstup - 1] * a;
} } for (j = 0; j < numy; j++) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
if (j % jstup == 0) {
working_vector[2 * numy + kstup] = 0;
working_vector[2 * numy + kstup + 4 * numy] = 0;
}
else {
working_vector[2 * numy + kstup + j % jstup] =
working_vector[2 * numy + kstup + 2 * jstup -
j % jstup];
working_vector[2 * numy + kstup + j % jstup +
4 * numy] =
-working_vector[2 * numy + kstup + 2 * jstup -
j % jstup + 4 * numy];
}
}
for (j = 0; j < 2 * numy; j++) {
working_vector[j] = working_vector[2 * numy + j];
working_vector[j + 4 * numy] =
working_vector[2 * numy + j + 4 * numy];
}
GeneralInv(working_vector, 2 * numy, degree, type);
for (j = 0; j < l; j++)
BitReverseHaar(working_vector, 2 * numy, m, j * m);
break;
}
for (j = 0; j < numy; j++) {
if (type > TRANSFORM2_WALSH_HAAR) {
kstup = j / jstup;
kstup = 2 * kstup * jstup;
valx = working_vector[kstup + j % jstup];
valz = working_vector[kstup + j % jstup + 4 * numy];
}
else {
valx = working_vector[j];
valz = working_vector[j + 2 * numy];
}
working_matrix[i][j] = valx;
working_matrix[i][j + numy] = valz;
}
}
for (j = 0; j < numy; j++) {
kstup = (int) TMath::Power(2, degree);
jstup = numy / kstup;
for (i = 0; i < numx; i++) {
working_vector[i] = working_matrix[i][j];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[i + 2 * numx] = working_matrix[i][j + numy];
else
working_vector[i + 4 * numx] = working_matrix[i][j + numy];
}
if (type > TRANSFORM2_WALSH_HAAR)
kstup = (int) TMath::Power(2, degree - 1);
else
kstup = (int) TMath::Power(2, degree);
jstup = numx / kstup;
for (i = 0, l = 0; i < numx; i++, l = (l + kstup) % numx) {
working_vector[numx + l + i / jstup] = working_vector[i];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[numx + l + i / jstup + 2 * numx] =
working_vector[i + 2 * numx];
else
working_vector[numx + l + i / jstup + 4 * numx] =
working_vector[i + 4 * numx];
}
for (i = 0; i < numx; i++) {
working_vector[i] = working_vector[numx + i];
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR
|| type == TRANSFORM2_WALSH_HAAR)
working_vector[i + 2 * numx] =
working_vector[numx + i + 2 * numx];
else
working_vector[i + 4 * numx] =
working_vector[numx + i + 4 * numx];
}
switch (type) {
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
for (i = 0; i < jstup; i++)
BitReverseHaar(working_vector, numx, kstup, i * kstup);
GeneralInv(working_vector, numx, degree, type);
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
jstup = (int) TMath::Power(2, degree) / 2;
m = (int) TMath::Power(2, degree);
l = 2 * numx / m;
for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (i % jstup) / (double) (2 * jstup);
if (i % jstup == 0) {
working_vector[2 * numx + kstup + i % jstup] =
working_vector[i] * TMath::Sqrt(2.0);
working_vector[2 * numx + kstup + i % jstup +
4 * numx] = 0;
}
else {
b = TMath::Sin(a);
a = TMath::Cos(a);
working_vector[2 * numx + kstup + i % jstup +
4 * numx] =
-(double) working_vector[i] * b;
working_vector[2 * numx + kstup + i % jstup] =
(double) working_vector[i] * a;
} } for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
if (i % jstup == 0) {
working_vector[2 * numx + kstup + jstup] = 0;
working_vector[2 * numx + kstup + jstup + 4 * numx] = 0;
}
else {
working_vector[2 * numx + kstup + 2 * jstup -
i % jstup] =
working_vector[2 * numx + kstup + i % jstup];
working_vector[2 * numx + kstup + 2 * jstup -
i % jstup + 4 * numx] =
-working_vector[2 * numx + kstup + i % jstup +
4 * numx];
}
}
for (i = 0; i < 2 * numx; i++) {
working_vector[i] = working_vector[2 * numx + i];
working_vector[i + 4 * numx] =
working_vector[2 * numx + i + 4 * numx];
}
GeneralInv(working_vector, 2 * numx, degree, type);
m = (int) TMath::Power(2, degree);
l = 2 * numx / m;
for (i = 0; i < l; i++)
BitReverseHaar(working_vector, 2 * numx, m, i * m);
break;
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
jstup = (int) TMath::Power(2, degree) / 2;
m = (int) TMath::Power(2, degree);
l = 2 * numx / m;
for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
a = pi * (double) (i % jstup) / (double) (2 * jstup);
if (i % jstup == 0) {
working_vector[2 * numx + kstup + jstup + i % jstup] =
working_vector[jstup + kstup / 2 - i % jstup -
1] * TMath::Sqrt(2.0);
working_vector[2 * numx + kstup + jstup + i % jstup +
4 * numx] = 0;
}
else {
b = TMath::Sin(a);
a = TMath::Cos(a);
working_vector[2 * numx + kstup + jstup + i % jstup +
4 * numx] =
-(double) working_vector[jstup + kstup / 2 -
i % jstup - 1] * b;
working_vector[2 * numx + kstup + jstup + i % jstup] =
(double) working_vector[jstup + kstup / 2 -
i % jstup - 1] * a;
} } for (i = 0; i < numx; i++) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
if (i % jstup == 0) {
working_vector[2 * numx + kstup] = 0;
working_vector[2 * numx + kstup + 4 * numx] = 0;
}
else {
working_vector[2 * numx + kstup + i % jstup] =
working_vector[2 * numx + kstup + 2 * jstup -
i % jstup];
working_vector[2 * numx + kstup + i % jstup +
4 * numx] =
-working_vector[2 * numx + kstup + 2 * jstup -
i % jstup + 4 * numx];
}
}
for (i = 0; i < 2 * numx; i++) {
working_vector[i] = working_vector[2 * numx + i];
working_vector[i + 4 * numx] =
working_vector[2 * numx + i + 4 * numx];
}
GeneralInv(working_vector, 2 * numx, degree, type);
for (i = 0; i < l; i++)
BitReverseHaar(working_vector, 2 * numx, m, i * m);
break;
}
for (i = 0; i < numx; i++) {
if (type > TRANSFORM2_WALSH_HAAR) {
kstup = i / jstup;
kstup = 2 * kstup * jstup;
val = working_vector[kstup + i % jstup];
}
else
val = working_vector[i];
working_matrix[i][j] = val;
}
}
}
return;
}
///////////////////////END OF AUXILIARY TRANSFORM2 FUNCTIONS//////////////////////////////////////////
//////////TRANSFORM2 FUNCTION - CALCULATES DIFFERENT 2-D DIRECT AND INVERSE ORTHOGONAL TRANSFORMS//////
const char *TSpectrum2::Transform2(const float **source, float **dest,
int sizex, int sizey, int type,
int direction, int degree)
{
//////////////////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL TRANSFORM FUNCTION */
/* This function transforms the source spectrum. The calling program */
/* should fill in input parameters. */
/* Transformed data are written into dest spectrum. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum, its size should */
/* be sizex*sizey except for inverse FOURIER, FOUR-WALSH, FOUR-HAAR */
/* transform. These need sizex*2*sizey length to supply real and */
/* imaginary coefficients. */
/* dest-pointer to the matrix of destination data, its size should be */
/* sizex*sizey except for direct FOURIER, FOUR-WALSh, FOUR-HAAR. These */
/* need sizex*2*sizey length to store real and imaginary coefficients */
/* sizex,sizey-basic dimensions of source and dest spectra */
/* type-type of transform */
/* direction-transform direction (forward, inverse) */
/* degree-applied only for mixed transforms */
/* */
//////////////////////////////////////////////////////////////////////////////////////////
int i, j, nx, ny, k, jx, jy;
int size;
float *working_vector = 0, **working_matrix = 0;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
jx = 0;
nx = 1;
for (; nx < sizex;) {
jx += 1;
nx = nx * 2;
}
if (nx != sizex)
return ("LENGTH X MUST BE POWER OF 2");
jy = 0;
ny = 1;
for (; ny < sizey;) {
jy += 1;
ny = ny * 2;
}
if (ny != sizey)
return ("LENGTH Y MUST BE POWER OF 2");
if (type < TRANSFORM2_HAAR || type > TRANSFORM2_SIN_HAAR)
return ("WRONG TRANSFORM TYPE");
if (direction != TRANSFORM2_FORWARD && direction != TRANSFORM2_INVERSE)
return ("WRONG TRANSFORM DIRECTION");
if (type >= TRANSFORM2_FOURIER_WALSH && type <= TRANSFORM2_SIN_HAAR) {
if (degree > jx || degree > jy || degree < 1)
return ("WRONG DEGREE");
if (type >= TRANSFORM2_COS_WALSH)
degree += 1;
k = (int) TMath::Power(2, degree);
jx = sizex / k;
jy = sizey / k;
}
size = (int) TMath::Max(sizex, sizey);
switch (type) {
case TRANSFORM2_HAAR:
case TRANSFORM2_WALSH:
working_vector = new float[2 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[sizey];
break;
case TRANSFORM2_COS:
case TRANSFORM2_SIN:
case TRANSFORM2_FOURIER:
case TRANSFORM2_HARTLEY:
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
working_vector = new float[4 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
working_vector = new float[8 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
}
if (direction == TRANSFORM2_FORWARD) {
switch (type) {
case TRANSFORM2_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
direction, TRANSFORM2_HAAR);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_WALSH:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
direction, TRANSFORM2_WALSH);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_COS:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_COS);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_SIN:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_SIN);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_FOURIER:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_FOURIER);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j + sizey] = working_matrix[i][j + sizey];
}
}
break;
case TRANSFORM2_HARTLEY:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_HARTLEY);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
General2(working_matrix, working_vector, sizex, sizey, direction,
type, degree);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR) {
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j + sizey] = working_matrix[i][j + sizey];
}
}
}
break;
}
}
else if (direction == TRANSFORM2_INVERSE) {
switch (type) {
case TRANSFORM2_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
direction, TRANSFORM2_HAAR);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_WALSH:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
direction, TRANSFORM2_WALSH);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_COS:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_COS);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_SIN:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_SIN);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_FOURIER:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j + sizey] = source[i][j + sizey];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_FOURIER);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_HARTLEY:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey, direction,
TRANSFORM2_HARTLEY);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
}
}
if (type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR) {
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j + sizey] = source[i][j + sizey];
}
}
}
General2(working_matrix, working_vector, sizex, sizey, direction,
type, degree);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j];
}
}
break;
}
}
for (i = 0; i < sizex; i++) {
delete[]working_matrix[i];
}
delete[]working_matrix;
delete[]working_vector;
return 0;
}
//////////END OF TRANSFORM2 FUNCTION/////////////////////////////////
//_______________________________________________________________________________________
//////////FILTER2_ZONAL FUNCTION - CALCULATES DIFFERENT 2-D ORTHOGONAL TRANSFORMS, SETS GIVEN REGION TO FILTER COEFFICIENT AND TRANSFORMS IT BACK//////
const char *TSpectrum2::Filter2Zonal(const float **source, float **dest,
int sizex, int sizey, int type,
int degree, int xmin, int xmax,
int ymin, int ymax,
float filter_coeff)
{
//////////////////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL FILTER ZONAL FUNCTION */
/* This function transforms the source spectrum. The calling program */
/* should fill in input parameters. Then it sets transformed */
/* coefficients in the given region to the given */
/* filter_coeff and transforms it back */
/* Filtered data are written into dest spectrum. */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum, its size should */
/* be sizex*sizey */
/* dest-pointer to the matrix of destination data, its size should be */
/* sizex*sizey */
/* sizex,sizey-basic dimensions of source and dest spectra */
/* type-type of transform */
/* degree-applied only for mixed transforms */
/* xmin-low limit x of filtered region */
/* xmax-high limit x of filtered region */
/* ymin-low limit y of filtered region */
/* ymax-high limit y of filtered region */
/* filter_coeff-value which is set in filtered region */
/* */
//////////////////////////////////////////////////////////////////////////////////////////
int i, j, nx, ny, k, jx, jy;
double a, old_area = 0, new_area = 0;
int size;
float *working_vector = 0, **working_matrix = 0;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
jx = 0;
nx = 1;
for (; nx < sizex;) {
jx += 1;
nx = nx * 2;
}
if (nx != sizex)
return ("LENGTH X MUST BE POWER OF 2");
jy = 0;
ny = 1;
for (; ny < sizey;) {
jy += 1;
ny = ny * 2;
}
if (ny != sizey)
return ("LENGTH Y MUST BE POWER OF 2");
if (type < TRANSFORM2_HAAR || type > TRANSFORM2_SIN_HAAR)
return ("WRONG TRANSFORM TYPE");
if (type >= TRANSFORM2_FOURIER_WALSH && type <= TRANSFORM2_SIN_HAAR) {
if (degree > jx || degree > jy || degree < 1)
return ("WRONG DEGREE");
if (type >= TRANSFORM2_COS_WALSH)
degree += 1;
k = (int) TMath::Power(2, degree);
jx = sizex / k;
jy = sizey / k;
}
if (xmin < 0 || xmin > xmax)
return ("WRONG LOW REGION X LIMIT");
if (xmax < xmin || xmax >= sizex)
return ("WRONG HIGH REGION X LIMIT");
if (ymin < 0 || ymin > ymax)
return ("WRONG LOW REGION Y LIMIT");
if (ymax < ymin || ymax >= sizey)
return ("WRONG HIGH REGION Y LIMIT");
size = (int) TMath::Max(sizex, sizey);
switch (type) {
case TRANSFORM2_HAAR:
case TRANSFORM2_WALSH:
working_vector = new float[2 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[sizey];
break;
case TRANSFORM2_COS:
case TRANSFORM2_SIN:
case TRANSFORM2_FOURIER:
case TRANSFORM2_HARTLEY:
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
working_vector = new float[4 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
working_vector = new float[8 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
}
switch (type) {
case TRANSFORM2_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_HAAR);
break;
case TRANSFORM2_WALSH:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_WALSH);
break;
case TRANSFORM2_COS:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_COS);
break;
case TRANSFORM2_SIN:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_SIN);
break;
case TRANSFORM2_FOURIER:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_FOURIER);
break;
case TRANSFORM2_HARTLEY:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_HARTLEY);
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
General2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, type, degree);
break;
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
if (i >= xmin && i <= xmax && j >= ymin && j <= ymax)
working_matrix[i][j] = filter_coeff;
}
}
if (type == TRANSFORM2_FOURIER || type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR) {
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
if (i >= xmin && i <= xmax && j >= ymin && j <= ymax)
working_matrix[i][j + sizey] = filter_coeff;
}
}
}
switch (type) {
case TRANSFORM2_HAAR:
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_HAAR);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_WALSH:
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_WALSH);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_COS:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_COS);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_SIN:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_SIN);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_FOURIER:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_FOURIER);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_HARTLEY:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_HARTLEY);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
General2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, type, degree);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
}
for (i = 0; i < sizex; i++) {
delete[]working_matrix[i];
}
delete[]working_matrix;
delete[]working_vector;
return 0;
}
////////// END OF FILTER2_ZONAL FUNCTION/////////////////////////////////
//______________________________________________________________________
//////////ENHANCE2 FUNCTION - CALCULATES DIFFERENT 2-D ORTHOGONAL TRANSFORMS, MULTIPLIES GIVEN REGION BY ENHANCE COEFFICIENT AND TRANSFORMS IT BACK//////
const char *TSpectrum2::Enhance2(const float **source, float **dest,
int sizex, int sizey, int type,
int degree, int xmin, int xmax, int ymin,
int ymax, float enhance_coeff)
{
//////////////////////////////////////////////////////////////////////////////////////////
/* TWO-DIMENSIONAL ENHANCE ZONAL FUNCTION */
/* This function transforms the source spectrum. The calling program */
/* should fill in input parameters. Then it multiplies transformed */
/* coefficients in the given region by the given */
/* enhance_coeff and transforms it back */
/* */
/* Function parameters: */
/* source-pointer to the matrix of source spectrum, its size should */
/* be sizex*sizey */
/* dest-pointer to the matrix of destination data, its size should be */
/* sizex*sizey */
/* sizex,sizey-basic dimensions of source and dest spectra */
/* type-type of transform */
/* degree-applied only for mixed transforms */
/* xmin-low limit x of filtered region */
/* xmax-high limit x of filtered region */
/* ymin-low limit y of filtered region */
/* ymax-high limit y of filtered region */
/* enhance_coeff-value which is set in filtered region */
/* */
//////////////////////////////////////////////////////////////////////////////////////////
int i, j, nx, ny, k, jx, jy;
double a, old_area = 0, new_area = 0;
int size;
float *working_vector = 0, **working_matrix = 0;
if (sizex <= 0 || sizey <= 0)
return "Wrong parameters";
jx = 0;
nx = 1;
for (; nx < sizex;) {
jx += 1;
nx = nx * 2;
}
if (nx != sizex)
return ("LENGTH X MUST BE POWER OF 2");
jy = 0;
ny = 1;
for (; ny < sizey;) {
jy += 1;
ny = ny * 2;
}
if (ny != sizey)
return ("LENGTH Y MUST BE POWER OF 2");
if (type < TRANSFORM2_HAAR || type > TRANSFORM2_SIN_HAAR)
return ("WRONG TRANSFORM TYPE");
if (type >= TRANSFORM2_FOURIER_WALSH && type <= TRANSFORM2_SIN_HAAR) {
if (degree > jx || degree > jy || degree < 1)
return ("WRONG DEGREE");
if (type >= TRANSFORM2_COS_WALSH)
degree += 1;
k = (int) TMath::Power(2, degree);
jx = sizex / k;
jy = sizey / k;
}
if (xmin < 0 || xmin > xmax)
return ("WRONG LOW REGION X LIMIT");
if (xmax < xmin || xmax >= sizex)
return ("WRONG HIGH REGION X LIMIT");
if (ymin < 0 || ymin > ymax)
return ("WRONG LOW REGION Y LIMIT");
if (ymax < ymin || ymax >= sizey)
return ("WRONG HIGH REGION Y LIMIT");
size = (int) TMath::Max(sizex, sizey);
switch (type) {
case TRANSFORM2_HAAR:
case TRANSFORM2_WALSH:
working_vector = new float[2 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[sizey];
break;
case TRANSFORM2_COS:
case TRANSFORM2_SIN:
case TRANSFORM2_FOURIER:
case TRANSFORM2_HARTLEY:
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
working_vector = new float[4 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
working_vector = new float[8 * size];
working_matrix = new float *[sizex];
for (i = 0; i < sizex; i++)
working_matrix[i] = new float[2 * sizey];
break;
}
switch (type) {
case TRANSFORM2_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_HAAR);
break;
case TRANSFORM2_WALSH:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_WALSH);
break;
case TRANSFORM2_COS:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_COS);
break;
case TRANSFORM2_SIN:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_SIN);
break;
case TRANSFORM2_FOURIER:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_FOURIER);
break;
case TRANSFORM2_HARTLEY:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, TRANSFORM2_HARTLEY);
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
working_matrix[i][j] = source[i][j];
old_area = old_area + source[i][j];
}
}
General2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_FORWARD, type, degree);
break;
}
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
if (i >= xmin && i <= xmax && j >= ymin && j <= ymax)
working_matrix[i][j] *= enhance_coeff;
}
}
if (type == TRANSFORM2_FOURIER || type == TRANSFORM2_FOURIER_WALSH
|| type == TRANSFORM2_FOURIER_HAAR) {
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
if (i >= xmin && i <= xmax && j >= ymin && j <= ymax)
working_matrix[i][j + sizey] *= enhance_coeff;
}
}
}
switch (type) {
case TRANSFORM2_HAAR:
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_HAAR);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_WALSH:
HaarWalsh2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_WALSH);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_COS:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_COS);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_SIN:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_SIN);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_FOURIER:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_FOURIER);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_HARTLEY:
FourCos2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, TRANSFORM2_HARTLEY);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
case TRANSFORM2_FOURIER_WALSH:
case TRANSFORM2_FOURIER_HAAR:
case TRANSFORM2_WALSH_HAAR:
case TRANSFORM2_COS_WALSH:
case TRANSFORM2_COS_HAAR:
case TRANSFORM2_SIN_WALSH:
case TRANSFORM2_SIN_HAAR:
General2(working_matrix, working_vector, sizex, sizey,
TRANSFORM2_INVERSE, type, degree);
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
new_area = new_area + working_matrix[i][j];
}
}
if (new_area != 0) {
a = old_area / new_area;
for (i = 0; i < sizex; i++) {
for (j = 0; j < sizey; j++) {
dest[i][j] = working_matrix[i][j] * a;
}
}
}
break;
}
for (i = 0; i < sizex; i++) {
delete[]working_matrix[i];
}
delete[]working_matrix;
delete[]working_vector;
return 0;
}
////////// END OF ENHANCE2 FUNCTION/////////////////////////////////
// --------------------------------------------------------------------------------
// ROOT page - Class index - Top of the page
// --------------------------------------------------------------------------------
// This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.
ROOT page - Class index - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.