Brief description of class still missing. More...
#include <IrregularGrid2DData.h>
Public Member Functions | |
const double * | axisData (AxisType axis) const |
double | bottom (int iy) const |
void | clear () |
Point2D | coordinates (int ix, int iy) const |
Curve< Point2D > | crossSection (AxisType axis, int ixy) const |
Curve< Point2D > | crossSection (Segment2D seg, double deltaX=0) const |
Curve< Point2D > | crossSection (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< Point2D > | integralCrossSection (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 () |
Brief description of class still missing.
Full description of class still missing
QGpCoreTools::IrregularGrid2DData::IrregularGrid2DData | ( | int | nx, |
int | ny | ||
) |
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); }
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]);
}
Curve< Point2D > QGpCoreTools::IrregularGrid2DData::crossSection | ( | AxisType | axis, |
int | ixy | ||
) | const |
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().
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; }
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; }
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; }
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); } } }
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; }
CurveClass QGpCoreTools::IrregularGrid2DData::followMaximumY | ( | int | iyMin, |
int | iyMax, | ||
int | ixMax | ||
) | const |
References QGpCoreTools::Curve< pointType >::closestMax(), crossSection(), x(), QGpCoreTools::XAxis, and y().
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 | ||
) |
void QGpCoreTools::IrregularGrid2DData::init | ( | double | value = 0.0 | ) |
void QGpCoreTools::IrregularGrid2DData::init | ( | int | nx, |
int | ny, | ||
double | value | ||
) | [inline] |
Curve< Point2D > QGpCoreTools::IrregularGrid2DData::integralCrossSection | ( | AxisType | along, |
int | index | ||
) | const |
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; }
void QGpCoreTools::IrregularGrid2DData::inverse | ( | AxisType | axis | ) |
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; }
bool QGpCoreTools::IrregularGrid2DData::isLike | ( | IrregularGrid2DData & | o | ) | const |
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().
double QGpCoreTools::IrregularGrid2DData::left | ( | int | ix | ) | const [inline] |
Referenced by crossSection().
{return leftOrBottom(_x, _nx,ix);}
void QGpCoreTools::IrregularGrid2DData::log10 | ( | AxisType | axis | ) |
References TRACE.
Referenced by log10(), and smoothInvalidCells().
double QGpCoreTools::IrregularGrid2DData::maximumAxis | ( | AxisType | axis | ) | const |
double QGpCoreTools::IrregularGrid2DData::maximumValue | ( | ) | const |
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 |
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; }
double QGpCoreTools::IrregularGrid2DData::minimumAxis | ( | AxisType | axis | ) | const |
double QGpCoreTools::IrregularGrid2DData::minimumValue | ( | ) | const |
double QGpCoreTools::IrregularGrid2DData::minimumValue | ( | int & | ix, |
int & | iy | ||
) | const |
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; }
void QGpCoreTools::IrregularGrid2DData::multiplyCoordinates | ( | AxisType | axis, |
double | fac | ||
) |
References TRACE, and QGpCoreTools::XAxis.
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; }
void QGpCoreTools::IrregularGrid2DData::multiplyValues | ( | double | 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 | ) |
void QGpCoreTools::IrregularGrid2DData::operator= | ( | const IrregularGrid2DData & | o | ) |
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); } } }
void QGpCoreTools::IrregularGrid2DData::pow10 | ( | AxisType | axis | ) |
References TRACE, and QGpCoreTools::XAxis.
void QGpCoreTools::IrregularGrid2DData::printValues | ( | AxisType | along, |
int | index | ||
) |
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 | ||
) |
void QGpCoreTools::IrregularGrid2DData::setLog | ( | AxisType | axis, |
double | min, | ||
double | 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];}
QVector< double > QGpCoreTools::IrregularGrid2DData::x | ( | ) | const |
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;}
double* QGpCoreTools::IrregularGrid2DData::xPointer | ( | ) | [inline] |
{return _x;}
double QGpCoreTools::IrregularGrid2DData::y | ( | int | iy | ) | const [inline] |
{return _y[iy];}
QVector< double > QGpCoreTools::IrregularGrid2DData::y | ( | ) | const |
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;}
double* QGpCoreTools::IrregularGrid2DData::yPointer | ( | ) | [inline] |
{return _y;}