コード例 #1
0
//---------------------------------------------------------
bool CKriging_Simple::Get_Weights(const CSG_Points_Z &Points, CSG_Matrix &W)
{
	int	n	= Points.Get_Count();

	if( n > 0 )
	{
		int	n	= Points.Get_Count();

		W.Create(n, n);

		for(int i=0; i<n; i++)
		{
			W[i][i]	= 0.0;				// diagonal...

			for(int j=i+1; j<n; j++)
			{
				W[i][j]	= W[j][i]	= Get_Weight(Points.Get_X(i), Points.Get_Y(i), Points.Get_X(j), Points.Get_Y(j));
			}
		}

		return( W.Set_Inverse(!m_Search.Do_Use_All(), n) );
	}

	return( false );
}
コード例 #2
0
//---------------------------------------------------------
int CKriging_Universal::Get_Weights(const TSG_Point &p, CSG_Matrix &W, CSG_Points_Z &Points)
{
	//-----------------------------------------------------
	int		n	= m_Search.Get_Nearest_Points(Points, p, m_nPoints_Max, m_Radius, m_Direction);

	if( n >= m_nPoints_Min )
	{
		int		i, j, k;

		int	nCoords	= m_bCoords ? 2 : 0;
		int	nGrids	= m_pGrids->Get_Count();

		W.Create(n + 1 + nGrids + nCoords, n + 1 + nGrids + nCoords);

		//-------------------------------------------------
		for(i=0; i<n; i++)
		{
			W[i][i]	= 0.0;				// diagonal...
			W[i][n]	= W[n][i]	= 1.0;	// edge...

			for(j=i+1; j<n; j++)
			{
				W[i][j]	= W[j][i]	= Get_Weight(Points[i], Points[j]);
			}

			for(k=0, j=n+1; k<nGrids; k++, j++)
			{
				W[i][j]	= W[j][i]	= m_pGrids->asGrid(k)->Get_Value(Points[i].x, Points[i].y, m_Interpolation);
			}

			for(k=0, j=n+nGrids+1; k<nCoords; k++, j++)
			{
				W[i][j]	= W[j][i]	= k == 0 ? Points[i].x : Points[i].y;
			}
		}

		for(i=n; i<=n+nGrids+nCoords; i++)
		{
			for(j=n; j<=n+nGrids+nCoords; j++)
			{
				W[i][j]	= 0.0;
			}
		}

		if( W.Set_Inverse(true, n + 1 + nGrids + nCoords) )
		{
			return( n );
		}
	}	

	return( 0 );
}
コード例 #3
0
//---------------------------------------------------------
int CGW_Multi_Regression_Grid::Get_Variables(int x, int y, CSG_Vector &z, CSG_Vector &w, CSG_Matrix &Y)
{
	TSG_Point	Point	= m_dimModel.Get_Grid_to_World(x, y);
	int			nPoints	= m_Search.is_Okay() ? (int)m_Search.Select_Nearest_Points(Point.x, Point.y, m_nPoints_Max, m_Radius, m_Direction) : m_Points.Get_Count();

	z.Create(nPoints);
	w.Create(nPoints);
	Y.Create(1 + m_nPredictors, nPoints);

	for(int iPoint=0; iPoint<nPoints; iPoint++)
	{
		double	ix, iy, iz;

		CSG_Shape	*pPoint	= m_Search.is_Okay() && m_Search.Get_Selected_Point(iPoint, ix, iy, iz)
			? m_Points.Get_Shape((int)iz)
			: m_Points.Get_Shape(iPoint);

		z[iPoint]		= pPoint->asDouble(0);
		w[iPoint]		= m_Weighting.Get_Weight(SG_Get_Distance(Point, pPoint->Get_Point(0)));
		Y[iPoint][0]	= 1.0;

		for(int iPredictor=1; iPredictor<=m_nPredictors; iPredictor++)
		{
			Y[iPoint][iPredictor]	= pPoint->asDouble(iPredictor);
		}
	}

	return( nPoints );
}
コード例 #4
0
//---------------------------------------------------------
void CWaterRetentionCapacity::Get_WaterRetention(CSG_Matrix &Data, double fC, CSG_Shape *pPoint)
{
	int		i;

	double	fWRC = 0, fPerm = 0, fHe = 0, fK = 0, fCCC = 0, fCIL = 0, fTotalDepth = 0;

	CSG_Vector	CCC (Data.Get_NRows());
	CSG_Vector	CIL (Data.Get_NRows());
	CSG_Vector	K   (Data.Get_NRows());
	CSG_Vector	Perm(Data.Get_NRows());
	CSG_Vector	He  (Data.Get_NRows());
	CSG_Vector	CRA (Data.Get_NRows());

	for(i=0; i<Data.Get_NRows(); i++)
	{
		CCC [i]	= Get_CCC(Data[i]);
		CIL [i]	= Get_CIL(Data[i]);
		He  [i]	= Get_He (Data[i]);

		Perm[i]	= Get_Permeability(CCC[i], CIL[i]);

		if( i > 0 )
		{
			K[i] = Get_K(Perm[i - 1], Perm[i], fC);
		}

		CRA[i]	= (double)((12.5 * He[i] + 12.5 * (50. - He[i]) * K[i] / 2.) * Data[i][1] / 100.);

		fTotalDepth	+= Data[i][0];
	}

	for(i=0; i<Data.Get_NRows(); i++)
	{
		fWRC	+= Data[i][0] / fTotalDepth * CRA [i];
		fCCC	+= Data[i][0] / fTotalDepth * CCC [i];
		fCIL	+= Data[i][0] / fTotalDepth * CIL [i];
		fPerm	+= Data[i][0] / fTotalDepth * Perm[i];
		fHe		+= Data[i][0] / fTotalDepth * He  [i];
		fK		+= Data[i][0] / fTotalDepth * K   [i];
	}

	pPoint->Set_Value(0, fCCC );
	pPoint->Set_Value(1, fCIL );
	pPoint->Set_Value(2, fPerm);
	pPoint->Set_Value(3, fHe  );
	pPoint->Set_Value(4, fWRC );
}
コード例 #5
0
//---------------------------------------------------------
bool CSG_mRMR::Set_Data(CSG_Matrix &Data, int ClassField, double Threshold)
{
    if( !Get_Memory(Data.Get_NCols(), Data.Get_NRows()) )
    {
        return( false );
    }

    //-----------------------------------------------------
    if( ClassField < 0 || ClassField >= m_nVars )
    {
        ClassField	= 0;
    }

    for(int iSample=0; iSample<m_nSamples; iSample++)
    {
        double	*pData	= m_Samples[iSample] = m_Samples[0] + iSample * m_nVars;

        *pData++	= Data[iSample][ClassField];

        for(int iVar=0; iVar<m_nVars; iVar++)
        {
            if( iVar != ClassField )
            {
                *pData++	= Data[iSample][iVar];
            }
        }
    }

    m_VarNames	+= "CLASS";

    for(int iVar=0; iVar<m_nVars; iVar++)
    {
        if( iVar != ClassField )
        {
            m_VarNames	+= CSG_String::Format(SG_T("FEATURE_%02d"), iVar);
        }
    }

    //-----------------------------------------------------
    if( Threshold >= 0.0 )	// discretization
    {
        Discretize(Threshold);
    }

    return( true );
}
コード例 #6
0
//---------------------------------------------------------
int CGWR_Grid_Downscaling::Get_Variables(int x, int y, CSG_Vector &z, CSG_Vector &w, CSG_Matrix &Y)
{
	int		n	= 0;

	z.Create(m_Search.Get_Count());
	w.Create(m_Search.Get_Count());
	Y.Create(1 + m_nPredictors, m_Search.Get_Count());

	//-----------------------------------------------------
	for(int i=0, ix, iy; i<m_Search.Get_Count(); i++)
	{
		double	id, iw;

		if( m_Search.Get_Values(i, ix = x, iy = y, id, iw, true) && m_pDependent->is_InGrid(ix, iy) )
		{
			z[n]	= m_pDependent->asDouble(ix, iy);
			w[n]	= iw;
			Y[n][0]	= 1.0;

			for(int j=0; j<m_nPredictors && iw>0.0; j++)
			{
				if( !m_pPredictors[j]->is_NoData(ix, iy) )
				{
					Y[n][j + 1]	= m_pPredictors[j]->asDouble(ix, iy);
				}
				else
				{
					iw	= 0.0;
				}
			}

			if( iw > 0.0 )
			{
				n++;
			}
		}
	}

	//-----------------------------------------------------
	z.Set_Rows(n);
	w.Set_Rows(n);
	Y.Set_Rows(n);

	return( n );
}
コード例 #7
0
//---------------------------------------------------------
bool CWindeffect_Correction::Fit_Scaling_Factor(int x, int y, double &B, double B_min, double B_max, double B_Step)
{
	CSG_Simple_Statistics	Statistics[3];

	CSG_Matrix	Data;

	if( !Get_Data(x, y, Data, Statistics[OBS]) )
	{
		return( false );
	}

	//-----------------------------------------------------
	double	dMin	= -1.0;

	for(double iB=B_min; iB<=B_max; iB+=B_Step)
	{
		int	i;

		Statistics[COR].Create(true);	// reset

		for(i=0; i<Data.Get_NRows(); i++)
		{
			Statistics[COR]	+= Get_Wind_Corr(iB, Data[i][BND], Data[i][WND]);
		}

		Statistics[VAL].Create(false);	// reset

		for(i=0; i<Data.Get_NRows(); i++)
		{
			Statistics[VAL]	+= Statistics[OBS].Get_Mean() * Statistics[COR].Get_Value(i) / Statistics[COR].Get_Mean();
		}

		double	d	= fabs(Statistics[VAL].Get_StdDev() - Statistics[OBS].Get_StdDev());

		if( dMin < 0.0 || dMin > d )
		{
			B		= iB;
			dMin	= d;
		}
	}

	return( dMin >= 0.0 );
}
コード例 #8
0
ファイル: mat_matrix.cpp プロジェクト: johanvdw/saga-debian
//---------------------------------------------------------
bool CSG_Matrix::Set_Transpose(void)
{
	CSG_Matrix	m;
	
	if( m.Create(*this) && Create(m_ny, m_nx) )
	{
		for(int y=0; y<m_ny; y++)
		{
			for(int x=0; x<m_nx; x++)
			{
				m_z[y][x]	= m.m_z[x][y];
			}
		}

		return( true );
	}

	return( false );
}
コード例 #9
0
ファイル: mat_matrix.cpp プロジェクト: johanvdw/saga-debian
//---------------------------------------------------------
bool		SG_Matrix_Solve(CSG_Matrix &Matrix, CSG_Vector &Vector, bool bSilent)
{
	bool	bResult	= false;
	int		n		= Vector.Get_N();

	if( n > 0 && n == Matrix.Get_NX() && n == Matrix.Get_NY() )
	{
		int	*Permutation	= (int *)SG_Malloc(n * sizeof(int));

		if( SG_Matrix_LU_Decomposition(n, Permutation, Matrix.Get_Data(), bSilent) )
		{
			SG_Matrix_LU_Solve(n, Permutation, Matrix, Vector.Get_Data(), bSilent);

			bResult	= true;
		}

		SG_Free(Permutation);
	}

	return( bResult );
}
コード例 #10
0
//---------------------------------------------------------
Ptr<TrainData> COpenCV_ML_ANN::Get_Training(const CSG_Matrix &Data)
{
	Mat	Samples (Data.Get_NRows(), Data.Get_NCols() - 1 , CV_32F);
	Mat	Response(Data.Get_NRows(), Get_Class_Count()    , CV_32F);

	for(int i=0; i<Data.Get_NRows(); i++)
	{
		int	j, k	= (int)Data[i][Data.Get_NCols() - 1];

		for(j=0; j<Response.cols; j++)
		{
			Response.at<float>(i, j)	= j == k ? 1.f : 0.f;
		}

		for(j=0; j<Samples.cols; j++)
		{
			Samples.at<float>(i, j)	= (float)Data[i][j];
		}
	}

	return( TrainData::create(Samples, ROW_SAMPLE, Response) );
}
コード例 #11
0
ファイル: mat_matrix.cpp プロジェクト: johanvdw/saga-debian
CSG_Matrix CSG_Matrix::Multiply(const CSG_Matrix &Matrix) const
{
	CSG_Matrix	m;

	if( m_nx == Matrix.m_ny && m.Create(Matrix.m_nx, m_ny) )
	{
		for(int y=0; y<m.m_ny; y++)
		{
			for(int x=0; x<m.m_nx; x++)
			{
				double	z	= 0.0;

				for(int n=0; n<m_nx; n++)
				{
					z	+= m_z[y][n] * Matrix.m_z[n][x];
				}

				m.m_z[y][x]	= z;
			}
		}
	}

	return( m );
}
コード例 #12
0
//---------------------------------------------------------
bool CChange_Detection::Get_Changes(CSG_Table &Initial, CSG_Table &Final, CSG_Table *pChanges, CSG_Matrix &Identity)
{
	int		iInitial, iFinal;

	//-----------------------------------------------------
	Identity.Create(Final.Get_Count() + 1, Initial.Get_Count() + 1);

	for(iInitial=0; iInitial<Initial.Get_Count(); iInitial++)
	{
		CSG_String	s	= Initial[iInitial].asString(CLASS_NAM);

		for(iFinal=0; iFinal<Final.Get_Count(); iFinal++)
		{
			Identity[iInitial][iFinal]	= s.Cmp(Final[iFinal].asString(CLASS_NAM)) ? 0 : 1;
		}
	}

	Identity[Initial.Get_Count()][Final.Get_Count()]	= 1;	// unclassified

	//-----------------------------------------------------
	pChanges->Destroy();

	pChanges->Add_Field(_TL("Name"), SG_DATATYPE_String);

	for(iFinal=0; iFinal<Final.Get_Count(); iFinal++)
	{
		pChanges->Add_Field(Final[iFinal].asString(CLASS_NAM), SG_DATATYPE_Double);
	}

	pChanges->Add_Field(_TL("Unclassified"), SG_DATATYPE_Double);

	//-----------------------------------------------------
	for(iInitial=0; iInitial<Initial.Get_Count(); iInitial++)
	{
		pChanges->Add_Record()->Set_Value(0, Initial[iInitial].asString(CLASS_NAM));
	}

	pChanges->Add_Record()->Set_Value(0, _TL("Unclassified"));

	return( true );
}
コード例 #13
0
//---------------------------------------------------------
bool CWindeffect_Correction::Get_Data(int x, int y, CSG_Matrix &Data, CSG_Simple_Statistics &statsObserved)
{
	for(int i=0; i<m_Kernel.Get_Count(); i++)
	{
		int	ix	= m_Kernel.Get_X(i, x);
		int	iy	= m_Kernel.Get_Y(i, y);

		if( m_pBoundary->is_InGrid(ix, iy) && m_pWind->is_InGrid(ix, iy) && m_pObserved->is_InGrid(ix, iy) )
		{
			CSG_Vector	d(2);

			d[BND]	= m_pBoundary->asDouble(ix, iy);
			d[WND]	= m_pWind    ->asDouble(ix, iy);

			Data.Add_Row(d);

			statsObserved  += m_pObserved->asDouble(ix, iy);
		}
	}

	return( statsObserved.Get_Count() >= 5 );
}
コード例 #14
0
//---------------------------------------------------------
bool CTable_PCA::Get_Matrix(CSG_Matrix &Matrix)
{
    int		i, j1, j2;

    Matrix.Create(m_nFeatures, m_nFeatures);
    Matrix.Set_Zero();

    switch( m_Method )
    {
    //-----------------------------------------------------
    default:
    case 0:	// Correlation matrix: Center and reduce the column vectors.
        for(j1=0; j1<m_nFeatures; j1++)
        {
            Matrix[j1][j1] = 1.0;
        }

        for(i=0; i<m_pTable->Get_Count() && Set_Progress(i, m_pTable->Get_Count()); i++)
        {
            if( !is_NoData(i) )
            {
                for(j1=0; j1<m_nFeatures-1; j1++)
                {
                    for(j2=j1+1; j2<m_nFeatures; j2++)
                    {
                        Matrix[j1][j2]	+= Get_Value(j1, i) * Get_Value(j2, i);
                    }
                }
            }
        }
        break;

    //-----------------------------------------------------
    case 1:	// Variance-covariance matrix: Center the column vectors.
    case 2:	// Sums-of-squares-and-cross-products matrix
        for(i=0; i<m_pTable->Get_Count() && Set_Progress(i, m_pTable->Get_Count()); i++)
        {
            if( !is_NoData(i) )
            {
                for(j1=0; j1<m_nFeatures; j1++)
                {
                    for(j2=j1; j2<m_nFeatures; j2++)
                    {
                        Matrix[j1][j2]	+= Get_Value(j1, i) * Get_Value(j2, i);
                    }
                }
            }
        }
        break;
    }

    //-----------------------------------------------------
    for(j1=0; j1<m_nFeatures; j1++)
    {
        for(j2=j1; j2<m_nFeatures; j2++)
        {
            Matrix[j2][j1] = Matrix[j1][j2];
        }
    }

    return( true );
}
コード例 #15
0
//---------------------------------------------------------
bool CFilter_3x3::On_Execute(void)
{
	bool		bAbsolute;
	CSG_Matrix	Filter;
	CSG_Grid	*pInput, *pResult;
	CSG_Table	*pFilter;

	//-----------------------------------------------------
	pInput		= Parameters("INPUT"     )->asGrid();
	pResult		= Parameters("RESULT"    )->asGrid();

	bAbsolute	= Parameters("ABSOLUTE"  )->asBool();

	pFilter		= Parameters("FILTER"    )->asTable()
				? Parameters("FILTER"    )->asTable()
				: Parameters("FILTER_3X3")->asTable();

	if( pFilter->Get_Count() < 1 || pFilter->Get_Field_Count() < 1 )
	{
		Error_Set(_TL("invalid filter matrix"));

		return( false );
	}

	//-----------------------------------------------------
	Filter.Create(pFilter->Get_Field_Count(), pFilter->Get_Count());

	{
		for(int iy=0; iy<Filter.Get_NY(); iy++)
		{
			CSG_Table_Record	*pRecord	= pFilter->Get_Record(iy);

			for(int ix=0; ix<Filter.Get_NX(); ix++)
			{
				Filter[iy][ix]	= pRecord->asDouble(ix);
			}
		}
	}

	int	dx	= (Filter.Get_NX() - 1) / 2;
	int	dy	= (Filter.Get_NY() - 1) / 2;

	//-----------------------------------------------------
	if( !pResult || pResult == pInput )
	{
		pResult	= SG_Create_Grid(pInput);
	}
	else
	{
		pResult->Set_Name(CSG_String::Format(SG_T("%s [%s]"), pInput->Get_Name(), _TL("Filter")));

		pResult->Set_NoData_Value(pInput->Get_NoData_Value());
	}

	//-----------------------------------------------------
	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		#pragma omp parallel for
		for(int x=0; x<Get_NX(); x++)
		{
			double	s	= 0.0;
			double	n	= 0.0;

			if( pInput->is_InGrid(x, y) )
			{
				for(int iy=0, jy=y-dy; iy<Filter.Get_NY(); iy++, jy++)
				{
					for(int ix=0, jx=x-dx; ix<Filter.Get_NX(); ix++, jx++)
					{
						if( pInput->is_InGrid(jx, jy) )
						{
							s	+= Filter[iy][ix] * pInput->asDouble(jx, jy);
							n	+= fabs(Filter[iy][ix]);
						}
					}
				}
			}

			if( n > 0.0 )
			{
				pResult->Set_Value(x, y, bAbsolute ? s : s / n);
			}
			else
			{
				pResult->Set_NoData(x, y);
			}
		}
	}

	//-----------------------------------------------------
	if( !Parameters("RESULT")->asGrid() || Parameters("RESULT")->asGrid() == pInput )
	{
		pInput->Assign(pResult);

		delete(pResult);

		DataObject_Update(pInput);
	}

	return( true );
}
コード例 #16
0
//---------------------------------------------------------
bool CParam_Scale::On_Execute(void)
{
	//-----------------------------------------------------
	bool		bConstrain;
	int			Index[6];
	double		zScale, Tol_Slope, Tol_Curve;
	CSG_Matrix	Normal;

	//-----------------------------------------------------
	bConstrain	= Parameters("CONSTRAIN")->asBool();
	zScale		= Parameters("ZSCALE"   )->asDouble();	if( zScale <= 0.0 )	{	zScale	= 1.0;	}
	Tol_Slope	= Parameters("TOL_SLOPE")->asDouble();
	Tol_Curve	= Parameters("TOL_CURVE")->asDouble();

	m_pDEM		= Parameters("DEM"      )->asGrid();

	//-----------------------------------------------------
	CSG_Grid	*pFeature	= Parameters("FEATURES" )->asGrid();
	CSG_Grid	*pElevation	= Parameters("ELEVATION")->asGrid();
	CSG_Grid	*pSlope		= Parameters("SLOPE"    )->asGrid();
	CSG_Grid	*pAspect	= Parameters("ASPECT"   )->asGrid();
	CSG_Grid	*pProfC		= Parameters("PROFC"    )->asGrid();
	CSG_Grid	*pPlanC		= Parameters("PLANC"    )->asGrid();
	CSG_Grid	*pLongC		= Parameters("LONGC"    )->asGrid();
	CSG_Grid	*pCrosC		= Parameters("CROSC"    )->asGrid();
	CSG_Grid	*pMiniC		= Parameters("MINIC"    )->asGrid();
	CSG_Grid	*pMaxiC		= Parameters("MAXIC"    )->asGrid();

	//-----------------------------------------------------
	if( !Get_Weights() )
	{
		return( false );
	}

	if( !Get_Normal(Normal) )
	{
		return( false );
	}

	// To constrain the quadtratic through the central cell, ignore the calculations involving the
	// coefficient f. Since these are all in the last row and column of the matrix, simply redimension.
	if( !SG_Matrix_LU_Decomposition(bConstrain ? 5 : 6, Index, Normal.Get_Data()) )
	{
		return( false );
	}

	//-----------------------------------------------------
	for(int y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		#pragma omp parallel for
		for(int x=0; x<Get_NX(); x++)
		{
			CSG_Vector	Observed;

			double	elevation, slope, aspect, profc, planc, longc, crosc, minic, maxic;

			if( Get_Observed(x, y, Observed, bConstrain)
			&&  SG_Matrix_LU_Solve(bConstrain ? 5 : 6, Index, Normal, Observed.Get_Data()) )
			{
				Get_Parameters(zScale, Observed.Get_Data(), elevation, slope, aspect, profc, planc, longc, crosc, minic, maxic);

				GRID_SET_VALUE(pFeature  , Get_Feature(slope, minic, maxic, crosc, Tol_Slope, Tol_Curve));
				GRID_SET_VALUE(pElevation, elevation + m_pDEM->asDouble(x, y));	// Add central elevation back
				GRID_SET_VALUE(pSlope    , slope);
				GRID_SET_VALUE(pAspect   , aspect);
				GRID_SET_VALUE(pProfC    , profc);
				GRID_SET_VALUE(pPlanC    , planc);
				GRID_SET_VALUE(pLongC    , longc);
				GRID_SET_VALUE(pCrosC    , crosc);
				GRID_SET_VALUE(pMiniC    , minic);
				GRID_SET_VALUE(pMaxiC    , maxic);
			}
			else
			{
				GRID_SET_NODATA(pFeature);
				GRID_SET_NODATA(pElevation);
				GRID_SET_NODATA(pSlope);
				GRID_SET_NODATA(pAspect);
				GRID_SET_NODATA(pProfC);
				GRID_SET_NODATA(pPlanC);
				GRID_SET_NODATA(pLongC);
				GRID_SET_NODATA(pCrosC);
				GRID_SET_NODATA(pMiniC);
				GRID_SET_NODATA(pMaxiC);
			}
		}
	}

	//-----------------------------------------------------
	CSG_Parameter	*pLUT	= DataObject_Get_Parameter(pFeature, "LUT");

	if( pLUT && pLUT->asTable() )
	{
		pLUT->asTable()->Del_Records();

		LUT_SET_CLASS(FLAT   , _TL("Planar"       ), SG_GET_RGB(180, 180, 180));
		LUT_SET_CLASS(PIT    , _TL("Pit"          ), SG_GET_RGB(  0,   0,   0));
		LUT_SET_CLASS(CHANNEL, _TL("Channel"      ), SG_GET_RGB(  0,   0, 255));
		LUT_SET_CLASS(PASS   , _TL("Pass (saddle)"), SG_GET_RGB(  0, 255,   0));
		LUT_SET_CLASS(RIDGE  , _TL("Ridge"        ), SG_GET_RGB(255, 255,   0));
		LUT_SET_CLASS(PEAK   , _TL("Peak"         ), SG_GET_RGB(255,   0,   0));

		DataObject_Set_Parameter(pFeature, pLUT);

		DataObject_Set_Parameter(pFeature, "COLORS_TYPE", 1);	// Color Classification Type: Lookup Table
	}

	//-----------------------------------------------------
	DataObject_Set_Colors(pSlope , 11, SG_COLORS_YELLOW_RED);
	DataObject_Set_Colors(pAspect, 11, SG_COLORS_ASPECT_3);
	DataObject_Set_Colors(pProfC , 11, SG_COLORS_RED_GREY_BLUE, true);
	DataObject_Set_Colors(pPlanC , 11, SG_COLORS_RED_GREY_BLUE, false);
	DataObject_Set_Colors(pLongC , 11, SG_COLORS_RED_GREY_BLUE, true);
	DataObject_Set_Colors(pCrosC , 11, SG_COLORS_RED_GREY_BLUE, true);
	DataObject_Set_Colors(pMiniC , 11, SG_COLORS_RED_GREY_BLUE, true);
	DataObject_Set_Colors(pMaxiC , 11, SG_COLORS_RED_GREY_BLUE, true);

	//-----------------------------------------------------
	return( true );
}
コード例 #17
0
//---------------------------------------------------------
// find_normal() - Function to find the set of normal equations
//                 that allow a quadratic trend surface to be
//                 fitted through N  points using least squares
//                 V.1.0, Jo Wood, 27th November, 1994.
//---------------------------------------------------------
bool CParam_Scale::Get_Normal(CSG_Matrix &Normal)
{
	double	x1, y1,	x2, y2, x3, y3, x4, y4, xy2, x2y, xy3, x3y, x2y2, xy, N;	// coefficients of X-products.

	x1 = y1 = x2 = y2 = x3 = y3 = x4 = y4 = xy2 = x2y = xy3 = x3y = x2y2 = xy = N = 0.0;

	// Calculate matrix of sums of squares and cross products
	for(int y=0; y<m_Weights.Get_NY(); y++)
	{
		double	dy	= Get_Cellsize() * (y - m_Radius);

		for(int x=0; x<m_Weights.Get_NX(); x++)
		{
			double	dw	= m_Weights[y][x];

			double	dx	= Get_Cellsize() * (x - m_Radius);

			x4		+= dw * dx * dx * dx * dx;
			x2y2	+= dw * dx * dx * dy * dy;
			x3y		+= dw * dx * dx * dx * dy;
			x3		+= dw * dx * dx * dx;
			x2y		+= dw * dx * dx * dy;
			x2		+= dw * dx * dx;

			y4		+= dw * dy * dy * dy * dy;
			xy3		+= dw * dx * dy * dy * dy;
			xy2		+= dw * dx * dy * dy;
			y3		+= dw * dy * dy * dy;
			y2		+= dw * dy * dy;

			xy		+= dw * dx * dy;

			x1		+= dw * dx;

			y1		+= dw * dy;

			N		+= dw;
		}
	}

	// Store cross-product matrix elements.
	Normal.Create(6, 6);

	Normal[0][0] = x4;
	Normal[0][1] = Normal[1][0] = x2y2;
	Normal[0][2] = Normal[2][0] = x3y;
	Normal[0][3] = Normal[3][0] = x3;
	Normal[0][4] = Normal[4][0] = x2y;
	Normal[0][5] = Normal[5][0] = x2;

	Normal[1][1] = y4;
	Normal[1][2] = Normal[2][1] = xy3;
	Normal[1][3] = Normal[3][1] = xy2;
	Normal[1][4] = Normal[4][1] = y3;
	Normal[1][5] = Normal[5][1] = y2;

	Normal[2][2] = x2y2;
	Normal[2][3] = Normal[3][2] = x2y;
	Normal[2][4] = Normal[4][2] = xy2;
	Normal[2][5] = Normal[5][2] = xy;

	Normal[3][3] = x2;
	Normal[3][4] = Normal[4][3] = xy;
	Normal[3][5] = Normal[5][3] = x1;

	Normal[4][4] = y2;
	Normal[4][5] = Normal[5][4] = y1;

	Normal[5][5] = N;

	return( true );
}
コード例 #18
0
ファイル: Resection.cpp プロジェクト: johanvdw/saga-debian
//---------------------------------------------------------
bool CResection::On_Execute(void)
{

	CSG_PointCloud			*pPoints;									// Input Point Cloud
	CSG_String				fileName;
	CSG_File				*pTabStream = NULL;
	int n					= 6;										// Number of unknowns
	CSG_Vector center(3);
	CSG_Vector target(3);

	double c			= Parameters("F")			->asDouble();		// Focal Length (mm)
	double pixWmm		= Parameters("W")			->asDouble() / 1000;// Pixel Width (mm)
	double ppOffsetX	= Parameters("ppX")			->asDouble();		// Principal Point Offset X (pixels)
	double ppOffsetY	= Parameters("ppY")			->asDouble();		// Principal Point Offset Y (pixels)
	pPoints				= Parameters("POINTS")		->asPointCloud();
	fileName			= Parameters("OUTPUT FILE")	->asString();
	center[0]			= Parameters("Xc")			->asDouble();
	center[1]			= Parameters("Yc")			->asDouble();
	center[2]			= Parameters("Zc")			->asDouble();
	target[0]			= Parameters("Xt")			->asDouble();
	target[1]			= Parameters("Yt")			->asDouble();
	target[2]			= Parameters("Zt")			->asDouble();

	int pointCount = pPoints->Get_Point_Count();

	bool estPPOffsets = false;

	if ( Parameters("EST_OFFSETS")->asBool() ) {

		estPPOffsets = true;
		n = 8;															// Increase number of unknowns by 2
	}

	bool applyDistortions = false;
	CSG_Vector K(3);

	if ( Parameters("GIVE_DISTORTIONS")->asBool() ) {

		applyDistortions = true;
		K[0]			= Parameters("K1")			->asDouble();
		K[1]			= Parameters("K2")			->asDouble();
		K[2]			= Parameters("K3")			->asDouble();

	}

	double dxapp = center [0] - target [0];
	double dyapp = center [1] - target [1];
	double dzapp = center [2] - target [2];
	double h_d	= sqrt (dxapp * dxapp + dyapp * dyapp + dzapp * dzapp);	// Distance between Proj. Center & Target (m)
	double h_dmm = h_d * 1000;											// Convert to mm

	if( fileName.Length() == 0 )
	{
		SG_UI_Msg_Add_Error(_TL("Please provide an output file name!"));
		return( false );
	}

	pTabStream = new CSG_File();

	if( !pTabStream->Open(fileName, SG_FILE_W, false) )
	{
		SG_UI_Msg_Add_Error(CSG_String::Format(_TL("Unable to open output file %s!"), fileName.c_str()));
		delete (pTabStream);
		return (false);
	}


	CSG_Vector rotns = methods::calcRotations(center,target);			// Approx. rotations omega, kappa, alpha

	CSG_String msg = "********* Initial Approximate Values *********";
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Rotation Angles:");
	pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Omega:\t") + SG_Get_String(rotns[0],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Kappa:\t") + SG_Get_String(rotns[1],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Alpha:\t") + SG_Get_String(rotns[2],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Projection Center:");
	pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Xc:\t") + SG_Get_String(center[0],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Yc:\t") + SG_Get_String(center[1],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Zc:\t") + SG_Get_String(center[2],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	
	if (estPPOffsets) {

		msg = SG_T("Principal Point Offsets:");
		pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);

		msg = SG_T("ppX:\t") + SG_Get_String(ppOffsetX,5,false);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);
		msg = SG_T("ppY:\t") + SG_Get_String(ppOffsetY,5,false);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);

	}

	double itrNo = 0;
	CSG_Matrix invN;
	
	while (true) {													// Begin Iterations

		itrNo++;
		
		double omega = rotns[0];
		double kappa = rotns[1];
		double alpha = rotns[2];

		CSG_Matrix R = methods::calcRotnMatrix(rotns);				// Rotation Matrix from approximate values
		CSG_Matrix E(3,3);											// [w1;w2;w3] = E * [dw;dk;da]

		E[0][0] = -1;
		E[0][1] = E[1][0] = E[2][0] = 0;
		E[0][2] = sin(kappa);
		E[1][1] = -cos(omega);
		E[1][2] = -sin(omega) * cos(kappa);
		E[2][1] = sin(omega);
		E[2][2] = -cos(omega) * cos(kappa);

		CSG_Matrix N(n,n);											// Transpose(Design Matrix) * I * Design Matrix
		CSG_Vector ATL(n);											// Transpose(Design Matrix) * I * Shortened obs. vector

		double SS = 0;
		double sigma_naught = 0;
		
		for (int i = 0; i < pointCount; i++) {
			
			CSG_Vector pqs(3);										// Approx. pi, qi, si

			for (int j = 0; j < 3; j++) {
				pqs[j] = R[j][0] * (pPoints->Get_X(i) - center[0]) +
						 R[j][1] * (pPoints->Get_Y(i) - center[1]) +
						 R[j][2] * (pPoints->Get_Z(i) - center[2]);
			}

			double p_i = pqs[0];
			double q_i = pqs[1];
			double s_i = pqs[2];

			double dR =  0;
			
			// Undistorted
			double x_u = c * p_i / q_i;
			double y_u = c * s_i / q_i;
			
			double c_hat = c;
			
			if (applyDistortions) {
				double r2 = x_u * x_u + y_u * y_u;
				dR =  K[0] * r2 + K[1] * r2 * r2 + K[2] * r2 * r2 * r2;
				c_hat = c * (1 - dR);
			}

			// Approx. image coordinates (with distortions)
			double x_i = (1 - dR) * x_u + ppOffsetX * pixWmm;
			double z_i = (1 - dR) * y_u + ppOffsetY * pixWmm;

			// Shortened obervation vector: dxi & dzi
			double dx_i = pPoints->Get_Attribute(i,0) * pixWmm - x_i;
			double dz_i = pPoints->Get_Attribute(i,1) * pixWmm - z_i;
			SS += pow(dx_i,2) + pow(dz_i,2);

			/*
				x_i, z_i in [mm]
				p_i,q_i,s_i in [m]
				h_d in [m]
				c, c_hat in [mm]
				h_dmm in [mm]
			*/
			CSG_Matrix L(3,2);										// CSG_Matrix takes columns first and rows second
			CSG_Matrix V(3,3);
			CSG_Matrix LR(3,2);
			CSG_Matrix LVE(3,2);

			L[0][0] = L[1][2] = c_hat / (1000 * q_i);
			L[0][2] = L[1][0] = 0;
			L[0][1] = -x_u * (1 - dR) / (1000 * q_i);
			L[1][1] = -y_u * (1 - dR) / (1000 * q_i);

			V[0][0] = V[1][1] = V[2][2] = 0;
			V[0][1] =  s_i / h_d;
			V[0][2] = -q_i / h_d;
			V[1][0] = -s_i / h_d;
			V[1][2] =  p_i / h_d;
			V[2][0] =  q_i / h_d;
			V[2][1] = -p_i / h_d;

			LVE = ( L * V ) * E;
			LR = L * R;

			// Design Matrix (J)
			CSG_Matrix design(n,2);

			for(int j = 0; j < 2; j++) {
				for(int k = 0; k < 3; k++) {
					design[j][k] = LVE[j][k];
					design[j][k+3] = -LR[j][k];
				}
			}

			if ( estPPOffsets ) {
				design[0][6] = design[1][7] = 1.0;
			}

			// Build Normal Matrix
			for(int j = 0; j < n; j++) {
				for(int k = 0; k < n; k++) {
					N[j][k] += (design[0][j] * design[0][k] + design[1][j] * design[1][k]);
				}
			}

			// Build Tranpose (J) * I * (Shortened obs. vector)
			for (int m=0; m < n; m++) {
				ATL[m] += design[0][m] * dx_i + design[1][m] * dz_i;
			}

			L.Destroy();
			V.Destroy();
			LR.Destroy();
			LVE.Destroy();
			pqs.Destroy();
			design.Destroy();

		} // end looping over observations

		// Eigen values and Eigen Vectors
		CSG_Vector eigenVals(n);
		CSG_Matrix eigenVecs(n,n);
		SG_Matrix_Eigen_Reduction(N, eigenVecs, eigenVals, true);

		// One of the Eigen Values is 0
		if (std::any_of(eigenVals.cbegin(),
		                eigenVals.cend(),
		                [] (double i) { return i == 0; })) {
			msg = "The Normal Matrix has a rank defect. Please measure more points.";
			pTabStream->Write(msg + SG_T("\n"));
			SG_UI_Msg_Add(msg, true);
			break;
		}

		double mx = *std::max_element(eigenVals.cbegin(), eigenVals.cend());
		double mn = *std::min_element(eigenVals.cbegin(), eigenVals.cend());

		// Ratio of Smallest to the Biggest Eigen value is too small
		if ((mn / mx) < pow(10,-12.0)) {
			msg = SG_T("Condition of the Matrix of Normal Equations:\t") + CSG_String::Format(SG_T("  %13.5e"), mn/mx);
			pTabStream->Write(msg + SG_T("\n"));
			SG_UI_Msg_Add(msg, true);
			msg = "The Normal Matrix is weakly conditioned. Please measure more points.";
			pTabStream->Write(msg + SG_T("\n"));
			SG_UI_Msg_Add(msg, true);
			break;
		}

		// Calculate the adjustments
		double absMax = 0;
		invN = N.Get_Inverse();
		CSG_Vector est_param_incs = invN * ATL;

		for (int i = 0; i < n; i++) {
			if (abs(est_param_incs[i]) > absMax) {
				absMax = abs(est_param_incs[i]);
			}
		}

		if (absMax < thresh) {
			msg = "Solution has converged.";
			pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
			SG_UI_Msg_Add(msg, true);
			break;
		}

		for (int a = 0; a < 3; a++) {
			rotns[a] += est_param_incs[a] / h_dmm;								// New Approx. rotations omega, kappa, alpha
			center[a] += est_param_incs[a+3] / 1000;							// New Approx. Projection Center
		}

		if ( estPPOffsets ) {
			ppOffsetX += (est_param_incs[6] / pixWmm);							// New Approx. Principal Point
			ppOffsetY += (est_param_incs[7] / pixWmm);
		}

		sigma_naught = sqrt(SS / (2 * pointCount - n));

		// Writing To Output File & SAGA Console
		msg = "********* Iteration: " + SG_Get_String(itrNo,0,false) + " *********";
		pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);

		msg = "Sum of Squared Residuals:\t" + SG_Get_String(SS,5,false);
		pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);
		
		msg = "Sigma Naught:\t" + SG_Get_String(sigma_naught,5,false);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);
		
		msg = SG_T("Condition of the Matrix of Normal Equations:\t") + CSG_String::Format(SG_T("  %13.5e"), mn/mx);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);
		
		R.Destroy();
		E.Destroy();
		N.Destroy();
		ATL.Destroy();
		invN.Destroy();
		eigenVals.Destroy();
		eigenVecs.Destroy();
		est_param_incs.Destroy();

	} // end of iterations

	msg = "********* Final Estimated Parameters *********";
	pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Rotation Angles:");
	pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Omega:\t") + SG_Get_String(rotns[0],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Kappa:\t") + SG_Get_String(rotns[1],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Alpha:\t") + SG_Get_String(rotns[2],6,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Projection Center:");
	pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	msg = SG_T("Xc:\t") + SG_Get_String(center[0],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Yc:\t") + SG_Get_String(center[1],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);
	msg = SG_T("Zc:\t") + SG_Get_String(center[2],4,false);
	pTabStream->Write(msg + SG_T("\n"));
	SG_UI_Msg_Add(msg, true);

	if (estPPOffsets) {

		msg = SG_T("Principal Point Offsets:");
		pTabStream->Write(SG_T("\n") + msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);

		msg = SG_T("ppX:\t") + SG_Get_String(ppOffsetX,5,false);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);
		msg = SG_T("ppY:\t") + SG_Get_String(ppOffsetY,5,false);
		pTabStream->Write(msg + SG_T("\n"));
		SG_UI_Msg_Add(msg, true);

	}


	K.Destroy();
	rotns.Destroy();
	center.Destroy();
	target.Destroy();

	pTabStream->Close();
	
	return true;
}
コード例 #19
0
ファイル: mat_matrix.cpp プロジェクト: johanvdw/saga-debian
bool SG_Matrix_Triangular_Decomposition(CSG_Matrix &A, CSG_Vector &d, CSG_Vector &e)
{
	if( A.Get_NX() != A.Get_NY() )
	{
		return( false );
	}

	int		l, k, j, i, n;
	double	scale, hh, h, g, f;

	n	= A.Get_NX();

	d.Create(n);
	e.Create(n);

	for(i=n-1; i>=1; i--)
	{
		l	= i - 1;
		h	= scale = 0.0;

		if( l > 0 )
		{
			for(k=0; k<=l; k++)
			{
				scale	+= fabs(A[i][k]);
			}

			if( scale == 0.0 )
			{
				e[i]	= A[i][l];
			}
			else
			{
				for(k=0; k<=l; k++)
				{
					A[i][k]	/= scale;
					h		+= A[i][k] * A[i][k];
				}

				f		= A[i][l];
				g		= f > 0.0 ? -sqrt(h) : sqrt(h);
				e[i]	= scale * g;
				h		-= f * g;
				A[i][l]	= f - g;
				f		= 0.0;

				for(j=0; j<=l; j++)
				{
					A[j][i]	= A[i][j]/h;
					g		= 0.0;

					for(k=0; k<=j; k++)
					{
						g	+= A[j][k] * A[i][k];
					}

					for(k=j+1; k<=l; k++)
					{
						g	+= A[k][j] * A[i][k];
					}

					e[j]	= g / h;
					f		+= e[j] * A[i][j];
				}

				hh	= f / (h + h);

				for(j=0; j<=l; j++)
				{
					f		= A[i][j];
					e[j]	= g = e[j] - hh * f;

					for(k=0; k<=j; k++)
					{
						A[j][k]	-= (f * e[k] + g * A[i][k]);
					}
				}
			}
		}
		else
		{
			e[i]	= A[i][l];
		}

		d[i]	= h;
	}

	d[0]	= 0.0;
	e[0]	= 0.0;

	for(i=0; i<n; i++)
	{
		l	= i - 1;

		if( d[i] )
		{	
			for(j=0; j<=l; j++)
			{
				g	= 0.0;

				for(k=0; k<=l; k++)
				{
					g		+= A[i][k] * A[k][j];
				}

				for(k=0; k<=l; k++)
				{
					A[k][j]	-= g * A[k][i];
				}
			}
		}

		d[i]	= A[i][i];
		A[i][i]	= 1.0;

		for(j=0; j<=l; j++)
		{
			A[j][i]	= A[i][j] = 0.0;
		}
	}

	return( true );
}
コード例 #20
0
ファイル: mat_matrix.cpp プロジェクト: johanvdw/saga-debian
bool SG_Matrix_Tridiagonal_QL(CSG_Matrix &Q, CSG_Vector &d, CSG_Vector &e)
{
	if( Q.Get_NX() != Q.Get_NY() || Q.Get_NX() != d.Get_N() || Q.Get_NX() != e.Get_N() )
	{
		return( false );
	}

	int		m, l, iter, i, k, n;
	double	s, r, p, g, f, dd, c, b;

	n	= d.Get_N();

	for(i=1; i<n; i++)
	{
		e[i - 1]	= e[i];
	}

	e[n - 1]	= 0.0;

	for(l=0; l<n; l++)
	{
		iter	= 0;

		do
		{
			for(m=l; m<n-1; m++)
			{
				dd	= fabs(d[m]) + fabs(d[m + 1]);

				if( fabs(e[m]) + dd == dd )
				{
					break;
				}
			}

			if( m != l )
			{
				if( iter++ == 30 )
				{
					return( false );	// erhand("No convergence in TLQI.");
				}

				g	= (d[l+1] - d[l]) / (2.0 * e[l]);
				r	= sqrt((g * g) + 1.0);
				g	= d[m] - d[l] + e[l] / (g + M_SET_SIGN(r, g));
				s	= c = 1.0;
				p	= 0.0;

				for(i = m-1; i >= l; i--)
				{
					f = s * e[i];
					b = c * e[i];

					if (fabs(f) >= fabs(g))
					{
						c = g / f;
						r = sqrt((c * c) + 1.0);
						e[i+1] = f * r;
						c *= (s = 1.0/r);
					}
					else
					{
						s = f / g;
						r = sqrt((s * s) + 1.0);
						e[i+1] = g * r;
						s *= (c = 1.0/r);
					}

					g		= d[i+1] - p;
					r		= (d[i] - g) * s + 2.0 * c * b;
					p		= s * r;
					d[i+1]	= g + p;
					g		= c * r - b;

					for(k=0; k<n; k++)
					{
						f			= Q[k][i+1];
						Q[k][i+1]	= s * Q[k][i] + c * f;
						Q[k][i]		= c * Q[k][i] - s * f;
					}
				}

				d[l] = d[l] - p;
				e[l] = g;
				e[m] = 0.0;
			}
		}
		while( m != l );
	}

	return( true );
}
コード例 #21
0
//---------------------------------------------------------
bool CPoint_Trend_Surface::Get_Regression(CSG_Shapes *pPoints, int iAttribute)
{
	//-----------------------------------------------------
	int		i, j, Field;

	m_Names.Clear();

	m_Names	+= pPoints->Get_Name();

	for(i=1; i<=m_xOrder; i++)
	{
		m_Names	+= Get_Power(SG_T("x"), i);
	}

	for(i=1; i<=m_yOrder; i++)
	{
		m_Names	+= Get_Power(SG_T("y"), i);

		for(j=1; j<=m_xOrder && i<m_tOrder && j<m_tOrder; j++)
		{
			m_Names	+= Get_Power(SG_T("x"), j) + Get_Power(SG_T("y"), i);
		}
	}

	//-----------------------------------------------------
	CSG_Vector	Y, xPow, yPow;
	CSG_Matrix	X;

	Y.Create(pPoints->Get_Count());
	X.Create(m_Names.Get_Count(), pPoints->Get_Count());
	
	xPow.Create(m_xOrder + 1);
	yPow.Create(m_yOrder + 1);

	xPow[0]	= 1.0;
	yPow[0]	= 1.0;

	//-----------------------------------------------------
	for(int iShape=0; iShape<pPoints->Get_Count() && Set_Progress(iShape, pPoints->Get_Count()); iShape++)
	{
		CSG_Shape	*pShape	= pPoints->Get_Shape(iShape);

		if( !pShape->is_NoData(iAttribute) )
		{
			double		zShape	= pShape->asDouble(iAttribute);
			TSG_Point	Point	= pShape->Get_Point(0);

			Y[iShape]		= zShape;
			X[iShape][0]	= 1.0;

			for(i=1, Field=1; i<=m_xOrder; i++)
			{
				X[iShape][Field++]	= xPow[i]	= xPow[i - 1] * Point.x;
			}

			for(i=1; i<=m_yOrder; i++)
			{
				X[iShape][Field++]	= yPow[i]	= yPow[i - 1] * Point.y;

				for(j=1; j<=m_xOrder && i<m_tOrder && j<m_tOrder; j++)
				{
					X[iShape][Field++]	= xPow[j] * yPow[i];
				}
			}
		}
	}

	//-----------------------------------------------------
	CSG_Matrix	Xt, XtXinv;

	Xt		= X;
	Xt		.Set_Transpose();

	XtXinv	= Xt * X;
	XtXinv	.Set_Inverse();

	m_Coefficients	= XtXinv * Xt * Y;

	return( true );
}