All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
Public Member Functions
QGpCoreTools::IrregularGrid2DData Class Reference

Brief description of class still missing. More...

#include <IrregularGrid2DData.h>

List of all members.

Public Member Functions

const double * axisData (AxisType axis) const
double bottom (int iy) const
void clear ()
Point2D coordinates (int ix, int iy) const
Curve< Point2DcrossSection (AxisType axis, int ixy) const
Curve< Point2DcrossSection (Segment2D seg, double deltaX=0) const
Curve< Point2DcrossSection (const Curve< Point2D > &path, double deltaX=0) const
void cut (AxisType axis, double min, double max, SamplingOptions options)
template<class CurveClass , class PointClass >
CurveClass followMaximumX () const
template<class CurveClass , class PointClass >
CurveClass followMaximumX (int ixMin, int ixMax, int iyMax) const
template<class CurveClass , class PointClass >
void followMaximumX (CurveClass &curve, double min, double max) const
template<class CurveClass , class PointClass >
CurveClass followMaximumY () const
template<class CurveClass , class PointClass >
CurveClass followMaximumY (int iyMin, int iyMax, int ixMax) const
template<class CurveClass , class PointClass >
void followMaximumY (CurveClass &curve, double min, double max) const
double height (int iy) const
int indexOfX (double x) const
int indexOfY (double y) const
void init (int nx, int ny)
void init (double value=0.0)
void init (int nx, int ny, double value)
Curve< Point2DintegralCrossSection (AxisType axis, int index) const
void inverse (AxisType axis)
 IrregularGrid2DData ()
 IrregularGrid2DData (int nx, int ny)
 IrregularGrid2DData (const IrregularGrid2DData &o)
bool isLike (IrregularGrid2DData &o) const
double * iterator (AxisType along, int index, int &di, int &n) const
double left (int ix) const
void log10 (AxisType axis)
void log10 ()
double maximumAxis (AxisType axis) const
double maximumValue () const
double maximumValue (int &ix, int &iy) const
double mean (AxisType along, int index) const
double median (AxisType along, int index) const
double minimumAxis (AxisType axis) const
double minimumValue () const
double minimumValue (int &ix, int &iy) const
double mode (AxisType along, int index) const
void multiplyCoordinates (AxisType axis, double fac)
void multiplyValues (AxisType along, int index, double fac)
void multiplyValues (double fac)
double normalize (AxisType along, int index)
int nx () const
int ny () const
void operator+= (const IrregularGrid2DData &o)
void operator= (const IrregularGrid2DData &o)
void operator= (const GridSearch &o)
void pow10 (AxisType axis)
void pow10 ()
void printValues (AxisType along, int index)
void resample (AxisType axis, const QVector< double > &xModel, SamplingOptions options)
void resample (AxisType axis, int n, double min, double max, SamplingOptions options)
double right (int ix) const
void setLinear (AxisType axis, double min, double max)
void setLog (AxisType axis, double min, double max)
void setValue (int ix, int iy, double val)
void setX (int ix, double val)
void setY (int iy, double val)
void smooth (AxisType along, int index)
double smoothInvalidCells (AxisType along, int index, double invalidValue, double sigma2, double RVal, bool modify)
double sum (AxisType along, int index) const
double top (int iy) const
double value (int ix, int iy) const
double * valuePointer (int ix, int iy)
const double * valuePointer (int ix, int iy) const
double variance (AxisType along, int index) const
double variance (AxisType along, int index, double average) const
double width (int ix) const
double x (int ix) const
QVector< double > x () const
const double * xPointer () const
double * xPointer ()
double y (int iy) const
QVector< double > y () const
const double * yPointer () const
double * yPointer ()
 ~IrregularGrid2DData ()

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

Description of constructor still missing

References TRACE.

  : QSharedData()
{
  TRACE;
  _x=0;
  _y=0;
  _nx=_ny=0;
  _n2x=_n2y=0;
  _values=0;
}

References nx(), ny(), TRACE, TRACE_BUG, and TRACE_BUG_INT.

  : QSharedData()
{
  TRACE;
  _nx=nx;
  _ny=ny;
  ASSERT(_nx>0 && _ny>0);
  TRACE_BUG;
  TRACE_BUG_INT(nx);
  TRACE_BUG_INT(ny);
  initLookup();
  _x=new double[ nx ];
  _y=new double[ ny ];
  _values=new double[ _nx * _ny ];
}

References TRACE.

  : QSharedData(o)
{
  TRACE;
  _nx=o._nx;
  _ny=o._ny;
  _n2x=o._n2x;
  _n2y=o._n2y;
  _x=new double[ _nx ];
  _y=new double[ _ny ];
  int n=_nx * _ny;
  _values=new double[ n ];
  memcpy(_x, o._x, sizeof(double)*_nx);
  memcpy(_y, o._y, sizeof(double)*_ny);
  memcpy(_values, o._values, sizeof(double)*n);
}

Description of destructor still missing

References clear(), and TRACE.

{
  TRACE;
  clear();
}

Member Function Documentation

const double* QGpCoreTools::IrregularGrid2DData::axisData ( AxisType  axis) const [inline]
{int n; return getAxis(axis,n);}
double QGpCoreTools::IrregularGrid2DData::bottom ( int  iy) const [inline]

Referenced by crossSection().

{return leftOrBottom(_y, _ny,iy);}

References TRACE.

Referenced by operator=(), and ~IrregularGrid2DData().

{
  TRACE;
  delete [] _x;
  delete [] _y;
  delete [] _values;
  _x=0;
  _y=0;
  _values=0;
  _nx=_ny=0;
  _n2x=_n2y=0;
}
Point2D QGpCoreTools::IrregularGrid2DData::coordinates ( int  ix,
int  iy 
) const [inline]
{
  return Point2D(_x[ix],_y[iy]);
}

Returns a cross section along axis at index ixy

References QGpCoreTools::Curve< pointType >::setFunction(), setX(), setY(), value(), and QGpCoreTools::XAxis.

Referenced by crossSection(), cut(), followMaximumX(), followMaximumY(), and resample().

{
  int n;
  double * val=getAxis(axis, n);
  Curve<Point2D> f (n);
  for(int i=0;i < n;i++ ) f[i].setX(val[ i ] );
  if(axis ==XAxis) {
    for(int i=0;i < n;i++ ) f[i].setY(value(i, ixy));
  } else {
    for(int i=0;i < n;i++ ) f[i].setY(value(ixy, i));
  }
  f.setFunction();
  return f;
}
Curve< Point2D > QGpCoreTools::IrregularGrid2DData::crossSection ( Segment2D  seg,
double  deltaX = 0 
) const

Return a cross section through the grid along the segment seg. deltaX is an optional offset on the X values of the produced curve.

References QGpCoreTools::Curve< pointType >::append(), QGpCoreTools::Curve< pointType >::at(), bottom(), QGpCoreTools::Curve< pointType >::count(), QGpCoreTools::Point2D::distanceTo(), indexOfX(), indexOfY(), QGpCoreTools::Segment2D::intersects(), left(), QGpCoreTools::Segment2D::p1(), QGpCoreTools::Segment2D::p2(), right(), QGpCoreTools::Segment2D::set(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), top(), value(), QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().

{
  Curve<Point2D> interX;
  Curve<Point2D> interY;
  Segment2D gseg;
  int i, firstX=-1, firstY=-1;
  double v, l1, l2;
  Point2D p;
  // Looking for X intersections
  l1=bottom(0);
  l2=top(_ny - 1);
  v=left(0);
  gseg.set(v, l1, v, l2);
  if(seg.intersects(gseg, p)) {
    interX.append(p);
    firstX=0;
    //printf("first ix %i inter: %lg %lg\n",firstX,p.x,p.y);
  }
  for(i=0;i < _nx;i++ ) {
    v=right(i);
    gseg.set(v, l1, v, l2);
    if(seg.intersects(gseg, p)) {
      interX.append(p);
      if(firstX==-1) firstX=i + 1;
      //printf("first ix %i inter: %lg %lg\n",firstX,p.x,p.y);
    }
  }
  // Looking for Y intersections
  l1=left(0);
  l2=right(_nx - 1);
  v=bottom(0);
  gseg.set(l1, v, l2, v);
  if(seg.intersects(gseg, p)) {
    interY.append(p);
    firstY=0;
    //printf("first iy %i inter: %lg %lg\n",firstY,p.x,p.y);
  }
  for(i=0;i < _ny;i++ ) {
    v=top(i);
    gseg.set(l1, v, l2, v);
    if(seg.intersects(gseg, p)) {
      interY.append(p);
      if(firstY==-1) firstY=i + 1;
      //printf("first iy %i inter: %lg %lg\n",firstY,p.x,p.y);
    }
  }
  Curve<Point2D> f;
  int iX, iY;
  int incX, incY;
  int endX, endY;
  if(seg.p1().x() <= seg.p2().x()) {
    endX=interX.count();
    iX=0;
    incX=1;
    if(firstX==-1) {
      firstX=indexOfX(seg.p1().x());
      if(firstX==_nx) firstX -= 2;
      else if(firstX==-1) firstX += 2;
      else firstX++;
    }
  } else {
    endX=-1;
    iX=interX.count() - 1;
    incX=-1;
    firstX += iX;
    if(firstX==-1) {
      firstX=indexOfX(seg.p1().x());
      if(firstX==_nx) firstX--;
      else if(firstX==-1) firstX++;
    }
    //printf("Reversing X\n");
  }
  if(seg.p1().y() <= seg.p2().y()) {
    endY=interY.count();
    iY=0;
    incY=1;
    if(firstY==-1) {
      firstY=indexOfY(seg.p1().y());
      if(firstY==_ny) firstY -= 2;
      else if(firstY==-1) firstY += 2;
      else firstY++;
    }
  } else {
    endY=-1;
    iY=interY.count() - 1;
    incY=-1;
    firstY += iY;
    if(firstY==-1) {
      firstY=indexOfY(seg.p1().y());
      if(firstY==_ny) firstY--;
      else if(firstY==-1) firstY++;
   }
    //printf("Reversing Y\n");
  }
  double dX, dY;
  int index;
  //printf("P1 %lg %lf\n",seg.p1().x,seg.p1().y);
  if(iX!=endX)
    dX=seg.p1().distanceTo(interX.at(iX));
  else
    dX=1e99;
  if(iY!=endY)
    dY=seg.p1().distanceTo(interY.at(iY));
  else
    dY=1e99;
  while(iX!=endX || iY!=endY) {
    //printf("Next point on X %lg %lf\n",(*itX).x,(*itX).y);
    //printf("Next point on Y %lg %lf\n",(*itY).x,(*itY).y);
    //printf("dX=%lg dY=%lg\n",dX,dY);
    if(dX < dY) {
      if(incY<0)
        index=firstY < _ny ? firstY : _ny - 1;
      else
        index=firstY > 0 ? firstY - 1 : 0;
      //printf("index=%i\n",index);
      if(firstX==0) {
        p.setX(dX - deltaX);
        p.setY(value(0, index));
        f.append(p);
        //printf("x appending firstX %i : %lg %lg\n",firstX,resX->back(),resY->back());
        firstX += incX;
      } else if(firstX==_nx) {
        p.setX(dX - deltaX);
        p.setY(value(_nx - 1, index));
        f.append(p);
        //printf("x appending firstX %i : %lg %lg\n",firstX,resX->back(),resY->back());
        firstX += incX;
      } else {
        p.setX(dX - deltaX);
        if(incX<0)
          p.setY(value(firstX, index));
        else
          p.setY(value(firstX - 1, index));
        f.append(p);
        //printf("x appending firstX %i : %lg %lg\n",firstX,resX->back(),resY->back());
        if(firstX < _nx) {
          p.setX(dX - deltaX);
          if(incX<0)
            p.setY(value(firstX - 1, index));
          else
            p.setY(value(firstX, index));
          f.append(p);
          //printf("x appending firstX %i : %lg %lg\n",firstX,resX->back(),resY->back());
          firstX += incX;
        }
      }
      iX+=incX;
      if(iX!=endX)
        dX=seg.p1().distanceTo(interX.at(iX));
      else
        dX=1e99;
    } else {
      if(incX<0)
        index=firstX < _ny ? firstX : _nx - 1;
      else
        index=firstX > 0 ? firstX - 1 : 0;
      //printf("index=%i\n",index);
      if(firstY==0) {
        p.setX(dY - deltaX);
        p.setY(value(index, 0));
        f.append(p);
        //printf("y appending firstY %i : %lg %lg\n",firstY,resX->back(),resY->back());
        firstY += incY;
      } else if(firstY==_ny) {
        p.setX(dY - deltaX);
        p.setY(value(index, _ny - 1));
        f.append(p);
        //printf("y appending firstY %i : %lg %lg\n",firstY,resX->back(),resY->back());
        firstY += incY;
      } else {
        p.setX(dY - deltaX);
        if(incY<0)
          p.setY(value(index, firstY));
        else
          p.setY(value(index, firstY - 1));
        f.append(p);
        //printf("y appending firstY %i : %lg %lg\n",firstY,resX->back(),resY->back());
        if(firstY < _ny) {
          p.setX(dY - deltaX);
          if(incY<0)
            p.setY(value(index, firstY - 1));
          else
            p.setY(value(index, firstY));
          f.append(p);
          //printf("y appending firstY %i : %lg %lg\n",firstY,resX->back(),resY->back());
          firstY += incY;
        }
      }
      iY+=incY;
      if(iY!=endY)
        dY=seg.p1().distanceTo(interY.at(iY));
      else
        dY=1e99;
    }
  }
  return f;
}
Curve< Point2D > QGpCoreTools::IrregularGrid2DData::crossSection ( const Curve< Point2D > &  path,
double  deltaX = 0 
) const

Return a cross section through the grid along the curve path. deltaX is an optional offset on the X values of the produced curve.

References QGpCoreTools::Curve< pointType >::append(), QGpCoreTools::Curve< pointType >::at(), QGpCoreTools::Curve< pointType >::count(), crossSection(), QGpCoreTools::Curve< pointType >::last(), QGpCoreTools::Segment2D::set(), and QGpCoreTools::Point2D::x().

{
  Segment2D seg;
  int n=path.count();
  Curve<Point2D> curve;
  for(int i=1; i<n; i++) {
    seg.set(path.at(i-1), path.at(i));
    if(curve.count()==0) {
      curve.append(crossSection(seg, deltaX));
    } else {
      curve.append(crossSection(seg, -curve.last().x()));
    }
  }
  return curve;
}
void QGpCoreTools::IrregularGrid2DData::cut ( AxisType  axis,
double  min,
double  max,
SamplingOptions  options 
)

References QGpCoreTools::Curve< pointType >::count(), crossSection(), QGpCoreTools::Curve< pointType >::cut(), QGpCoreTools::Function, QGpCoreTools::Interpole, TRACE, x(), QGpCoreTools::XAxis, and y().

{
  TRACE;
  if(_ny < 2 || _nx < 2) return ;
  options |=Function; // curves returned by crossSection are always functions
  double * values=0, *x, *y, *val=0;
  int n=0;
  Curve<Point2D> valuesF;
  if(axis ==XAxis) {
    for(int iy=0;iy < _ny;iy++ ) {
      valuesF=crossSection(axis, iy);
      valuesF.cut(min, max, options | Interpole);
      if(iy==0) {
        n=valuesF.count();
        values=new double[ n * _ny ];
        val=values;
      }
      for(int ix=0;ix < n;ix++ ) val[ ix ]=valuesF[ ix ].y();
      val += n;
    }
    x=new double[ n ];
    delete [] _x;
    _x=x;
    for(int ix=0;ix < n;ix++ ) x[ ix ]=valuesF[ ix ].x();
    _nx=n;
  } else {
    for(int ix=0;ix < _nx;ix++ ) {
      valuesF=crossSection(axis, ix);
      valuesF.cut(min, max, options | Interpole);
      if(ix==0) {
        n=valuesF.count();
        values=new double[ _nx * n ];
        val=values;
      }
      int offY=0;
      for(int iy=0;iy < n;iy++, offY += _nx) val[ offY ]=valuesF[ iy ].y();
      val++;
    }
    y=new double[ n ];
    delete [] _y;
    _y=y;
    for(int iy=0;iy < n;iy++ ) y[ iy ]=valuesF[ iy ].x();
    _ny=n;
  }
  delete [] _values;
  _values=values;
}
template<class CurveClass , class PointClass >
CurveClass QGpCoreTools::IrregularGrid2DData::followMaximumX ( ) const

References maximumValue(), and TRACE.

{
  TRACE;
  CurveClass curve;
  if(_nx==0 || _ny==0) return curve;
  // Search the maximum value of grid
  int ix, iy;
  maximumValue(ix, iy);
  curve.append(followMaximumX<CurveClass,PointClass>(ix, _nx-1, iy));
  curve.append(followMaximumX<CurveClass,PointClass>(ix, 0, iy));
  curve.setFunction();
  return curve;
}
template<class CurveClass , class PointClass >
CurveClass QGpCoreTools::IrregularGrid2DData::followMaximumX ( int  ixMin,
int  ixMax,
int  iyMax 
) const

References QGpCoreTools::Curve< pointType >::closestMax(), crossSection(), TRACE, x(), y(), and QGpCoreTools::YAxis.

{
  TRACE;
  CurveClass curve;
  curve.append(PointClass(x(ixMin), y(iyMax)));
  int dx=ixMin<ixMax ? 1 : -1;
  ixMax+=dx;
  for(int i=ixMin;i!=ixMax;i+=dx) {
    Curve<Point2D> cs=crossSection(YAxis, i);
    iyMax=cs.closestMax(iyMax);
    curve.append(PointClass(x(i), y(iyMax)));
    curve.last().setValid(true);
  }
  return curve;
}
template<class CurveClass , class PointClass >
void QGpCoreTools::IrregularGrid2DData::followMaximumX ( CurveClass &  curve,
double  min,
double  max 
) const

References QGpCoreTools::Curve< pointType >::closestMax(), crossSection(), QGpCoreTools::Function, QGpCoreTools::Curve< pointType >::indexAfter(), nx(), ny(), TRACE, x(), y(), and QGpCoreTools::YAxis.

{
  TRACE;
  ASSERT(nx()>1); // Needed by Curve::indexAfter()
  ASSERT(ny()>1); // Needed by Curve::indexAfter()
  curve.resample(x(), Function);
  for(int i=0;i<_nx;i++ ) {
    if(min<=x(i) && x(i)<=max) {
      int curveIndex=curve.indexAfter(x(i));
      PointClass& p=curve[curveIndex];
      Curve<Point2D> cs=crossSection(YAxis, i);
      int iMax=cs.closestMax(cs.indexAfter(p.y()));
      p.setY(y(iMax));
      p.setValid(true);
    }
  }
}
template<class CurveClass , class PointClass >
CurveClass QGpCoreTools::IrregularGrid2DData::followMaximumY ( ) const

References maximumValue().

{
  CurveClass curve;
  if(_nx==0 || _ny==0) return curve;
  // Search the maximum value of grid
  int ix, iy;
  maximumValue(ix, iy);
  curve.append(followMaximumY<CurveClass,PointClass>(iy, _ny-1, ix));
  curve.append(followMaximumY<CurveClass,PointClass>(iy, 0, ix));
  curve.setFunction();
  return curve;
}
template<class CurveClass , class PointClass >
CurveClass QGpCoreTools::IrregularGrid2DData::followMaximumY ( int  iyMin,
int  iyMax,
int  ixMax 
) const

References QGpCoreTools::Curve< pointType >::closestMax(), crossSection(), x(), QGpCoreTools::XAxis, and y().

{
  CurveClass curve;
  curve.append(PointClass(y(iyMin), x(ixMax)));
  int dy=iyMin<iyMax ? 1 : -1;
  iyMax+=dy;
  for(int i=iyMin;i!=iyMax;i+=dy) {
    Curve<Point2D> cs=crossSection(XAxis, i);
    ixMax=cs.closestMax(ixMax);
    curve.append(PointClass(y(i), x(ixMax)));
    curve.last().setValid(true);
  }
  return curve;
}
template<class CurveClass , class PointClass >
void QGpCoreTools::IrregularGrid2DData::followMaximumY ( CurveClass &  curve,
double  min,
double  max 
) const

References QGpCoreTools::Curve< pointType >::closestMax(), crossSection(), QGpCoreTools::Function, QGpCoreTools::Curve< pointType >::indexAfter(), nx(), ny(), x(), QGpCoreTools::XAxis, and y().

{
  ASSERT(nx()>1); // Needed by Curve::indexAfter()
  ASSERT(ny()>1); // Needed by Curve::indexAfter()
  curve.resample(y(), Function);
  for(int i=0;i<_ny;i++ ) {
    if(min<=y(i) && y(i)<=max) {
      int curveIndex=curve.indexAfter(y(i));
      PointClass& p=curve[curveIndex];
      Curve<Point2D> cs=crossSection(XAxis, i);
      int iMax=cs.closestMax(cs.indexAfter(p.y()));
      p.setY(x(iMax));
      p.setValid(true);
    }
  }
}
double QGpCoreTools::IrregularGrid2DData::height ( int  iy) const [inline]
{return widthOrHeight(_y, _ny,iy);}
int QGpCoreTools::IrregularGrid2DData::indexOfX ( double  x) const [inline]

Referenced by crossSection().

{return indexOf(_x, _nx, _n2x, x);}
int QGpCoreTools::IrregularGrid2DData::indexOfY ( double  y) const [inline]

Referenced by crossSection().

{return indexOf(_y, _ny, _n2y, y);}
void QGpCoreTools::IrregularGrid2DData::init ( int  nx,
int  ny 
)

References nx(), ny(), and TRACE.

Referenced by init().

{
  TRACE;
  if(nx!=_nx) {
    _nx=nx;
    delete [] _x;
    _x=new double[ nx ];
  } else if(ny==_ny) return;
  if(ny!=_ny) {
    _ny=ny;
    delete [] _y;
    _y=new double[ ny ];
  }
  initLookup();
  delete [] _values;
  _values=new double[ _nx * _ny ];
}
void QGpCoreTools::IrregularGrid2DData::init ( double  value = 0.0)

References TRACE.

{
  TRACE;
  int n=_nx * _ny;
  for(int i=0; i < n; i++ ) _values[ i ]=value;
}
void QGpCoreTools::IrregularGrid2DData::init ( int  nx,
int  ny,
double  value 
) [inline]

References init().

{
  init(nx, ny);
  init(value);
}

Returns the integral of the grid at index along axis as a curve For correctness, normalize() must have been called before

References QGpCoreTools::Curve< pointType >::append(), iterator(), QGpCoreTools::Curve< pointType >::setFunction(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), and sum().

{
  Curve<Point2D> f;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  double sum=0, dsum;
  bool continuous=true;
  Point2D p;
  for(int ia=0, i=0;ia < na;i += di, ia++ ) {
    dsum=val[ i ] * widthOrHeight(vala, na, ia);
    if(dsum > 1e-15) {
      if( !continuous) {
        p.setX(sum + 1e-15);
        p.setY(rightOrTop(vala, na, ia - 1));
        f.append(p);
      }
      sum += dsum;
      p.setX(sum);
      p.setY(rightOrTop(vala, na, ia));
      f.append(p);
      continuous=true;
    } else continuous=false;
  }
  f.setFunction();
  return f;
}

References TRACE, and QGpCoreTools::XAxis.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  // As val must always increase, we must re-order the _values
  double * newValues=new double[ _nx * _ny ];
  if(axis==XAxis) {
    double * newAxis=new double[ _nx ];
    for(int ix=0;ix < _nx;ix++ ) {
      int index=ix;
      int new_index=_nx - ix - 1;
      newAxis[ new_index ]=1.0/_x[ index ];
      for(int iy=_nx * (_ny - 1);iy >= 0;iy -= _nx) {
        newValues[ iy + new_index ]=_values[ iy + index ];
      }
    }
    delete [] _x;
    _x=newAxis;
  } else {
    double * newAxis=new double[ _ny ];
    for(int iy=0;iy < _ny;iy++ ) {
      int index=iy;
      int new_index=_ny - iy - 1;
      newAxis[ new_index ]=1.0/_y[ index ];
      index *= _nx;
      new_index *= _nx;
      for(int ix=_nx - 1;ix >= 0;ix-- ) {
        newValues[ ix + new_index ]=_values[ ix + index ];
      }
    }
    delete [] _y;
    _y=newAxis;
  }
  delete [] _values;
  _values=newValues;
}

References TRACE.

{
  TRACE;
  if(_nx!=o._nx || _ny!=o._ny) return false;
  int i;
  for(i=0;i < _nx;i++ ) {
    if(fabs(_x[ i ] - o._x[ i ] ) > 1e-10) return false;
  }
  for(i=0;i < _ny;i++ ) {
    if(fabs(_y[ i ] - o._y[ i ] ) > 1e-10) return false;
  }
  return true;
}
double * QGpCoreTools::IrregularGrid2DData::iterator ( AxisType  along,
int  index,
int &  di,
int &  n 
) const

References TRACE, and QGpCoreTools::XAxis.

Referenced by integralCrossSection(), mean(), median(), mode(), multiplyValues(), normalize(), printValues(), smoothInvalidCells(), sum(), and variance().

{
  TRACE;
  double * val;
  if(along ==XAxis) {
    n=_nx;
    di=1;
    val=_values + index * _nx;
  } else {
    n=_ny * _nx;
    di=_nx;
    val=_values + index;
  }
  return val;
}
double QGpCoreTools::IrregularGrid2DData::left ( int  ix) const [inline]

Referenced by crossSection().

{return leftOrBottom(_x, _nx,ix);}

References log10(), TRACE, and QGpCoreTools::XAxis.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  if(axis==XAxis) {
    for(int ix=0;ix < _nx;ix++ ) _x[ ix ]=::log10(_x[ ix ] );
  } else {
    for(int iy=0;iy < _ny;iy++ ) _y[ iy ]=::log10(_y[ iy ] );
  }
}

References TRACE.

Referenced by log10(), and smoothInvalidCells().

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  int n=_nx * _ny;
  for(int i=0;i < n;i++ ) _values[ i ]=::log10(_values[ i ] );
}

Return the maximum coordinate along axis (coordinate vectors are always sorted and increasing).

References TRACE.

{
  TRACE;
  // _x or _y is always strictly increasing
  int n;
  double * val=getAxis(axis, n);
  return val[ n -1 ];
}

Return the maximum value of the grid

References TRACE.

Referenced by followMaximumX(), and followMaximumY().

{
  TRACE;
  double val=-1e99;
  int n=_nx * _ny;
  for(int i=0;i < n;i++ ) {
    if(_values[ i ] > val) val=_values[ i ];
  }
  return val;
}
double QGpCoreTools::IrregularGrid2DData::maximumValue ( int &  ix,
int &  iy 
) const

Return the maximum value of the grid and also the coordinates of the minimum

References TRACE.

{
  TRACE;
  double val=-1e99;
  int n=_nx * _ny;
  int iMax=0;
  for(int i=0;i < n;i++ ) {
    if(_values[ i ] > val) {
      iMax=i;
      val=_values[ i ];
    }
  }
  iy=iMax/_nx;
  ix=iMax - iy*_nx;
  return val;
}
double QGpCoreTools::IrregularGrid2DData::mean ( AxisType  along,
int  index 
) const

Return the mean of values along axis along at index count on the other axis

References iterator(), and TRACE.

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  // Calculate the total area below the curve
  double p, sumP=0, sumX=0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) {
    p=val[ i ] * widthOrHeight(vala, na, ia);
    sumP += p;
    sumX += p * vala[ ia ];
  }
  return sumX/sumP;
}
double QGpCoreTools::IrregularGrid2DData::median ( AxisType  along,
int  index 
) const

Return the median of values along axis along at index count on the other axis

References QGpCoreTools::endl(), iterator(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na*di==n);
  // Calculate the total area below the curve
  double p, sumP=0;
  int i=0;
  for(int ia=0; ia<na; i+=di, ia++) {
    p=val[i]*widthOrHeight(vala, na, ia);
    sumP+=p;
    if(sumP>0.5) {
      // interpolation to find the exact median
      return vala[ia-1]+(1.0-(sumP-0.5)/p)*(vala[ia]-vala[ia-1]);
    }
  }
  App::stream() << tr("Error in median(), grid not normalized (sum=%1)").arg(sumP) << endl;
  return 0;
}

Return the minimum coordinate along axis (coordinate vectors are always sorted and increasing).

References TRACE.

{
  TRACE;
  // _x or _y is always strictly increasing
  int n;
  double * val=getAxis(axis, n);
  return val[ 0 ];
}

Return the minimum value of the grid

References TRACE.

{
  TRACE;
  double val=1e99;
  int n=_nx * _ny;
  for(int i=0;i < n;i++ ) {
    if(_values[ i ] < val) val=_values[ i ];
  }
  return val;
}
double QGpCoreTools::IrregularGrid2DData::minimumValue ( int &  ix,
int &  iy 
) const

Return the minimum value of the grid and also the coordinates of the minimum

References TRACE.

{
  TRACE;
  double val=-1e99;
  int n=_nx * _ny;
  int iMin=0;
  for(int i=0;i < n;i++ ) {
    if(_values[ i ] < val) {
      iMin=i;
      val=_values[ i ];
    }
  }
  iy=iMin/_nx;
  ix=iMin - iy*_nx;
  return val;
}
double QGpCoreTools::IrregularGrid2DData::mode ( AxisType  along,
int  index 
) const

Return the mode of values along axis along at index count on the other axis

References iterator(), TRACE, and x().

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  // Calculate the total area below the curve
  double p, pmax=0, x=0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) {
    p=val[ i ] * widthOrHeight(vala, na, ia);
    if(p > pmax) {
      pmax=p;
      x=vala[ ia ];
    }
  }
  return x;
}

References TRACE, and QGpCoreTools::XAxis.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  if(axis==XAxis) {
    for(int ix=0;ix < _nx;ix++ ) _x[ ix ] *= fac;
  } else {
    for(int iy=0;iy < _ny;iy++ ) _y[ iy ] *= fac;
  }
}
void QGpCoreTools::IrregularGrid2DData::multiplyValues ( AxisType  along,
int  index,
double  fac 
)

References iterator(), and TRACE.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  getAxis(along, na);
  ASSERT(na * di==n);
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) val[ i ] *= fac;
}

References TRACE.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  int n=_nx * _ny;
  for(int i=0;i < n;i++ ) _values[ i ] *= fac;
}
double QGpCoreTools::IrregularGrid2DData::normalize ( AxisType  along,
int  index 
)

Normalize area below curve along an axis at index, returns the normalizing factor

References iterator(), sum(), and TRACE.

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  // Calculate the total area below the curve
  double sum=0.0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ )
    sum += val[ i ] * widthOrHeight(vala, na, ia);
  // Divide all value by this sum
  if(sum > 0.0) {
    sum=1.0/sum;
    for(i=0;i < n;i += di) val[ i ] *= sum;
    return 1.0/sum;
  } else {
    // All values are zero, thus set a uniform distribution over the grid range
    for(i=0;i < n;i += di) val[ i ]=1.0;
    // Normalize it again
    return normalize(along, index);
  }
}
int QGpCoreTools::IrregularGrid2DData::nx ( ) const [inline]

Referenced by followMaximumX(), followMaximumY(), init(), and IrregularGrid2DData().

{return _nx;}
int QGpCoreTools::IrregularGrid2DData::ny ( ) const [inline]

Referenced by followMaximumX(), followMaximumY(), init(), and IrregularGrid2DData().

{return _ny;}
void QGpCoreTools::IrregularGrid2DData::operator+= ( const IrregularGrid2DData o)

References TRACE.

{
  TRACE;
  if(_nx!=o._nx || _ny!=o._ny) return ;
  int n=_nx * _ny;
  for(int i=0; i < n; i++ ) _values[ i ] += o._values[ i ];
}
void QGpCoreTools::IrregularGrid2DData::operator= ( const IrregularGrid2DData o)

References clear(), and TRACE.

{
  TRACE;
  clear();
  _nx=o._nx;
  _ny=o._ny;
  _n2x=o._n2x;
  _n2y=o._n2y;
  _x=new double[ _nx ];
  _y=new double[ _ny ];
  int n=_nx * _ny;
  _values=new double[ n ];
  memcpy(_x, o._x, sizeof(double)*_nx);
  memcpy(_y, o._y, sizeof(double)*_ny);
  memcpy(_values, o._values, sizeof(double)*n);
}
void QGpCoreTools::IrregularGrid2DData::operator= ( const GridSearch o)

References clear(), QGpCoreTools::GridSearch::nx(), QGpCoreTools::GridSearch::ny(), TRACE, QGpCoreTools::Function2Search::value(), QGpCoreTools::GridSearch::x(), and QGpCoreTools::GridSearch::y().

{
  TRACE;
  clear();
  _nx=o.nx();
  _ny=o.ny();
  initLookup();
  _x=new double[ _nx ];
  _y=new double[ _ny ];
  int n=_nx * _ny;
  _values=new double[ n ];
  int i;
  for(i=0; i < _nx; i++ ) _x[ i ]=o.x(i);
  for(i=0; i < _ny; i++ ) _y[ i ]=o.y(i);
  for(int iy=0; iy < _ny; iy++ ) {
    int offset=iy * _nx;
    for(int ix=0;ix < _nx;ix++ ) {
      _values[ ix + offset ]=o.value(_x[ix], _y[iy], ix + offset);
    }
  }
}

References TRACE, and QGpCoreTools::XAxis.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  if(axis==XAxis) {
    for(int ix=0;ix < _nx;ix++ ) _x[ ix ]=pow(10.0, _x[ ix ] );
  } else {
    for(int iy=0;iy < _ny;iy++ ) _y[ iy ]=pow(10.0, _y[ iy ] );
  }
}

References TRACE.

{
  TRACE;
  ASSERT(_nx > 0 && _ny > 0);
  int n=_nx * _ny;
  for(int i=0;i < n;i++ ) _values[ i ]=pow(10.0, _values[ i ] );
}

References iterator(), TRACE, and QGpCoreTools::YAxis.

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  char buf[ 2 ]={'y', '\0'};
  if(along==YAxis) printf( "x=%lf\n", _x[ index ] );
  else {
    printf( "y=%lf\n", _y[ index ] );
    buf[ 0 ]='x';
  }
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) printf( "%lf %lf\n",
        vala[ ia ], val[ i ] );
}
void QGpCoreTools::IrregularGrid2DData::resample ( AxisType  axis,
const QVector< double > &  xModel,
SamplingOptions  options 
)

References crossSection(), QGpCoreTools::Function, QGpCoreTools::Curve< pointType >::resample(), TRACE, x(), QGpCoreTools::XAxis, and y().

{
  TRACE;
  if(_ny < 2 || _nx < 2) return ;
  options |= Function; // curves returned by crossSection are always functions
  double * values, *x, *y, *val;
  int n=xModel.count();
  Curve<Point2D> valuesF;
  if(axis ==XAxis) {
    values=new double[ n * _ny ];
    val=values;
    for(int iy=0;iy < _ny;iy++ ) {
      valuesF=crossSection(axis, iy);
      // This is the only difference with precedding function
      valuesF.resample(xModel, options);
      for(int ix=0;ix < n;ix++ ) val[ ix ]=valuesF[ ix ].y();
      val += n;
    }
    x=new double[ n ];
    delete [] _x;
    _x=x;
    for(int ix=0;ix < n;ix++ ) x[ ix ]=valuesF[ ix ].x();
    _nx=n;
  } else {
    values=new double[ _nx * n ];
    val=values;
    for(int ix=0;ix < _nx;ix++ ) {
      valuesF=crossSection(axis, ix);
      // This is the only difference with precedding function
      valuesF.resample(xModel, options);
      int offY=0;
      for(int iy=0;iy < n;iy++, offY += _nx) val[ offY ]=valuesF[ iy ].y();
      val++;
    }
    y=new double[ n ];
    delete [] _y;
    _y=y;
    for(int iy=0;iy < n;iy++ ) y[ iy ]=valuesF[ iy ].x();
    _ny=n;
  }
  delete [] _values;
  _values=values;
}
void QGpCoreTools::IrregularGrid2DData::resample ( AxisType  axis,
int  n,
double  min,
double  max,
SamplingOptions  options 
)

References crossSection(), QGpCoreTools::Function, QGpCoreTools::Curve< pointType >::resample(), TRACE, x(), QGpCoreTools::XAxis, and y().

{
  TRACE;
  if(_ny < 2 || _nx < 2) return ;
  options |= Function; // curves returned by crossSection are always functions
  double * values, *x, *y, *val;
  Curve<Point2D> valuesF;
  if(axis ==XAxis) {
    values=new double [ n * _ny ];
    val=values;
    for(int iy=0;iy < _ny;iy++ ) {
      valuesF=crossSection(axis, iy);
      valuesF.resample(n, min, max, options);
      for(int ix=0;ix < n;ix++ ) val[ ix ]=valuesF[ ix ].y();
      val += n;
    }
    x=new double[ n ];
    delete [] _x;
    _x=x;
    for(int ix=0;ix < n;ix++ ) x[ ix ]=valuesF[ ix ].x();
    _nx=n;
  } else {
    values=new double[ _nx * n ];
    val=values;
    for(int ix=0;ix < _nx;ix++ ) {
      valuesF=crossSection(axis, ix);
      valuesF.resample(n, min, max, options);
      int offY=0;
      for(int iy=0;iy < n;iy++, offY += _nx) val[ offY ]=valuesF[ iy ].y();
      val++;
    }
    y=new double[ n ];
    delete [] _y;
    _y=y;
    for(int iy=0;iy < n;iy++ ) y[ iy ]=valuesF[ iy ].x();
    _ny=n;
  }
  delete [] _values;
  _values=values;
}
double QGpCoreTools::IrregularGrid2DData::right ( int  ix) const [inline]

Referenced by crossSection().

{return rightOrTop(_x, _nx,ix);}
void QGpCoreTools::IrregularGrid2DData::setLinear ( AxisType  axis,
double  min,
double  max 
)

References TRACE.

{
  TRACE;
  ASSERT(max > min);
  int n;
  double * val=getAxis(axis, n);
  int n1=n-1;
  double factor=(max - min)/(double) n1;
  val[ 0 ]=min;
  for(int i=1;i < n1;i++ ) val[ i ]=min + factor * i;
  val[ n1 ]=max;
}
void QGpCoreTools::IrregularGrid2DData::setLog ( AxisType  axis,
double  min,
double  max 
)

References TRACE.

{
  TRACE;
  ASSERT(max > min && min > 0);
  double factor=max/min;
  int n;
  double * val=getAxis(axis, n);
  int n1=n-1;
  val[ 0 ]=min;
  for(int i=1;i < n1;i++ ) val[ i ]=min * pow(factor, (double) i/(double) n1);
  val[ n1 ]=max;
}
void QGpCoreTools::IrregularGrid2DData::setValue ( int  ix,
int  iy,
double  val 
) [inline]
{
  _values[iy*_nx+ix]=val;
}
void QGpCoreTools::IrregularGrid2DData::setX ( int  ix,
double  val 
) [inline]

Referenced by crossSection().

{_x[ix]=val;}
void QGpCoreTools::IrregularGrid2DData::setY ( int  iy,
double  val 
) [inline]

Referenced by crossSection().

{_y[iy]=val;}
void QGpCoreTools::IrregularGrid2DData::smooth ( AxisType  along,
int  index 
)

References TRACE, value(), valuePointer(), and QGpCoreTools::XAxis.

{
  TRACE;
  int n;
  if(along ==XAxis) {
     n=_nx - 1;
    double * newValues=new double[n];
    for(int ix=1;ix < n;ix++ ) {
      newValues[ix]=0.333333333333*(value(ix-1, index) + value(ix, index) + value(ix+1, index));
    }
    for(int ix=1;ix < n;ix++ ) {
      *valuePointer(ix, index)=newValues[ix];
    }
    if(_nx>1) {
      *valuePointer(0, index)=0.5*(value(0, index) + value(1, index));
      *valuePointer(n, index)=0.5*(value(n, index) + value(n-1, index));
    }
    delete [] newValues;
  } else {
    n=_ny - 1;
    double * newValues=new double[n];
    for(int iy=1;iy < n;iy++ ) {
      newValues[iy]=value(index, iy-1) + value(index, iy) + value(index, iy+1);
    }
    for(int iy=1;iy < n;iy++ ) {
      *valuePointer(index, iy)=newValues[iy];
    }
    if(_ny>1) {
      *valuePointer(index, 0)=0.5*(value(index, 0) + value(index, 1));
      *valuePointer(index, n)=0.5*(value(index, n) + value(index, n-1));
    }
    delete [] newValues;
  }
}
double QGpCoreTools::IrregularGrid2DData::smoothInvalidCells ( AxisType  along,
int  index,
double  invalidValue,
double  sigma2,
double  RVal,
bool  modify 
)

References QGpCoreTools::exp(), iterator(), log10(), RRatio, TRACE, and x().

{
  TRACE;
#define RRatio 0.01
  double logE=::log10( ::exp(1.0));
  double proba=0;
  double cellWidth;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  // Estimate the standard deviation of the current curve
  double logR=::log10(RVal);
  // Recalculate a pseudo value for invalid cells
  int i=0;
  int iis, iisa;
  for(int ia=0;ia < na;i += di, ia++ ) {
    if(val[ i ]==invalidValue) {
      iis=i;
      iisa=ia;
      while(ia < na && val[ i ]==invalidValue) {
        i += di;
        ia++;
      }
      ASSERT (iisa > 0 || ia < na);
      if(iisa==0) {
        // Invalid values at the beginning of the histogram
        int j=iis;
        double x1=vala[ ia - 1 ], d;
        for(int ja=iisa;ja < ia;j += di, ja++ ) {
          d=vala[ ja ] - x1;
          if(modify) val[ j ]=d * d/sigma2 * logE - logR;
          else {
            if(ja > 0) cellWidth=vala[ ja ] - vala[ ja - 1 ];
            else cellWidth=vala[ 1 ] - vala[ 0 ];
            double t=-d * d/sigma2;
            if(t > -50) proba += cellWidth * RVal * ::exp(t);
          }
        }
      } else if(ia==na) {
        // Invalid values at the end of the histogram
        int j=iis;
        double x1=vala[ iisa ], d;
        for(int ja=iisa;ja < ia;j += di, ja++ ) {
          d=vala[ ja ] - x1;
          if(modify) val[ j ]=d * d/sigma2 * logE - logR;
          else {
            cellWidth=vala[ ja ] - vala[ ja - 1 ];
            double t=-d * d/sigma2;
            if(t > -50) proba += cellWidth * RVal * ::exp(t);
          }
        }

      } else {
        // Invalid value inside the histogram range
        if(iisa==ia - 1) {
          if(modify) val[ iis ]=-::log10(RVal);
          else {
            cellWidth=vala[ iisa ] - vala[ iisa - 1 ];
            proba += cellWidth * RVal;
          }
        } else if(iisa==ia - 2) {
          if(modify) {
            val[ iis ]=-::log10(RVal);
            val[ iis + di ]=val[ iis ];
          } else {
            cellWidth=vala[ iisa ] - vala[ iisa - 1 ];
            proba += cellWidth * RVal;
            cellWidth=vala[ iisa + 1 ] - vala[ iisa ];
            proba += cellWidth * RVal;
          }
        } else {
          double x1=vala[ iisa ], x2=vala[ ia - 1 ];
          double s=x1 + x2;
          double p=x1 * x2;
          double alpha=0.25 * (x1 * x1 + x2 * x2 + 2 * p);
          double c=(RVal * RRatio * p - alpha * RVal)/(p - alpha);
          double a=(c - RVal)/p;
          double b=-s * a;
          int j=iis;
          double x;
          for(int ja=iisa;ja < ia;j += di, ja++ ) {
            x=vala[ ja ];
            if(modify) val[ j ]=-::log10(a * x * x + b * x + c);
            else {
              cellWidth=vala[ ja ] - vala[ ja - 1 ];
              proba += cellWidth * (a * x * x + b * x + c);
            }
          }
        }
      }
    }
  }
  return proba;
}
double QGpCoreTools::IrregularGrid2DData::sum ( AxisType  along,
int  index 
) const

Return the sum of values along axis along at index count on the other axis

References iterator(), and TRACE.

Referenced by integralCrossSection(), and normalize().

{
  TRACE;
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  getAxis(along, na);
  ASSERT(na * di==n);
  double sum=0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) sum += val[ i ];
  return sum;
}
double QGpCoreTools::IrregularGrid2DData::top ( int  iy) const [inline]

Referenced by crossSection().

{return rightOrTop(_y, _ny,iy);}
double QGpCoreTools::IrregularGrid2DData::value ( int  ix,
int  iy 
) const [inline]

Referenced by crossSection(), and smooth().

{
  return(_values[iy*_nx+ix]);
}
double * QGpCoreTools::IrregularGrid2DData::valuePointer ( int  ix,
int  iy 
) [inline]

Referenced by smooth().

{
  return _values+(iy*_nx+ix);
}
const double * QGpCoreTools::IrregularGrid2DData::valuePointer ( int  ix,
int  iy 
) const [inline]
{
  return _values+(iy*_nx+ix);
}
double QGpCoreTools::IrregularGrid2DData::variance ( AxisType  along,
int  index 
) const

Return the variance of values along axis along at index count on the other axis

References QGpCoreTools::endl(), iterator(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.

{
  TRACE;
  // Grid is assumed to be correctly normalized, using function normalize(...)
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  int hitCount=na;
  double p, cellWidth=1, sumX=0, sumX2=0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) {
    if(val[ i ] > 0) {
      cellWidth=widthOrHeight(vala, na, ia);
      p=val[ i ] * cellWidth;
      sumX += p * vala[ ia ];
      sumX2 += p * vala[ ia ] * vala[ ia ];
    } else hitCount--;
  }
  if(hitCount > 1) {
    double average=sumX;
    return sumX2 -average*average;
  } else if(hitCount==1) {
    // cellWidth contains the only one cellWidth, assumed to be 4*sigma (95% on a gaussian);
    return cellWidth * cellWidth/16;
  }
  App::stream() << tr( "### ERROR ### : The grid is certainly not normalized, you must call normalize() "
                "                before calling variance()." ) << endl;
  return 0;
}
double QGpCoreTools::IrregularGrid2DData::variance ( AxisType  along,
int  index,
double  average 
) const

Return the variance of values along axis along at index count on the other axis. The variance is computed relative to average that can be any of mean, median or mode. If average is the median, the median deviation is returned.

References QGpCoreTools::endl(), iterator(), QGpCoreTools::App::stream(), QGpCoreTools::tr(), and TRACE.

{
  TRACE;
  // Grid is assumed to be correctly normalized, using function normalize(...)
  // Construct an iterator on grid values
  int di=0, n;
  double * val=iterator(along, index, di, n);
  // Construct an iterator on grid axis values to calculate the grid spacing
  int na;
  double * vala=getAxis(along, na);
  ASSERT(na * di==n);
  int hitCount=na;
  double p, cellWidth=1, sumX=0, sumX2=0;
  int i=0;
  for(int ia=0;ia < na;i += di, ia++ ) {
    if(val[ i ] > 0) {
      cellWidth=widthOrHeight(vala, na, ia);
      p=val[ i ] * cellWidth;
      sumX += p * vala[ ia ];
      sumX2 += p * vala[ ia ] * vala[ ia ];
    } else hitCount--;
  }
  if(hitCount > 1) {
    return sumX2 + (average - 2*sumX) * average;
  } else if(hitCount==1) {
    // cellWidth contains the only one cellWidth, assumed to be 4*sigma (95% on a gaussian);
    return cellWidth * cellWidth/16;
  }
  App::stream() << tr( "### ERROR ### : The grid is certainly not normalized, you must call normalize() "
                   "                before calling variance()." ) << endl;
  return 0;
}
double QGpCoreTools::IrregularGrid2DData::width ( int  ix) const [inline]
{return widthOrHeight(_x, _nx,ix);}
double QGpCoreTools::IrregularGrid2DData::x ( int  ix) const [inline]
{return _x[ix];}

Referenced by cut(), followMaximumX(), followMaximumY(), mode(), resample(), and smoothInvalidCells().

{
  QVector<double> v;
  for(int i=0; i < _nx; i++ ) v << _x[i];
  return v;
}
const double* QGpCoreTools::IrregularGrid2DData::xPointer ( ) const [inline]
{return _x;}
{return _x;}
double QGpCoreTools::IrregularGrid2DData::y ( int  iy) const [inline]
{return _y[iy];}

Referenced by cut(), followMaximumX(), followMaximumY(), and resample().

{
  QVector<double> v;
  for(int i=0; i < _ny; i++ ) v << _y[i];
  return v;
}
const double* QGpCoreTools::IrregularGrid2DData::yPointer ( ) const [inline]
{return _y;}
{return _y;}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines