/*
* This file is part of JGrasstools (http://www.jgrasstools.org)
* (C) HydroloGIS - www.hydrologis.com
*
* JGrasstools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jgrasstools.gears.utils.math;
import static org.jgrasstools.gears.libs.modules.ModelsEngine.calculateNthMoment;
import static org.jgrasstools.gears.libs.modules.ModelsEngine.split2realvectors;
import static org.jgrasstools.gears.libs.modules.ModelsEngine.vectorizeDoubleMatrix;
import java.awt.image.RenderedImage;
import org.jgrasstools.gears.i18n.GearsMessageHandler;
import org.jgrasstools.gears.libs.modules.SplitVectors;
import org.jgrasstools.gears.libs.monitor.IJGTProgressMonitor;
import org.jgrasstools.gears.utils.sorting.QuickSortAlgorithm;
/**
* <p>
* The cb model (coupledfieldmoments).
*
* <p>It
* calculates the histogram of a set of data contained in a matrix with respect
* to the set of data contained in another matrix. In substance, a map of
* R<SUP>2</SUP> ⇒ R<SUP>2</SUP>, in which each point of a bidimensional
* system (identified by the values contained in a matrix) is mapped in a second
* bidimensional system, is produced. The data of the first set are then grouped
* in a prefixed number of intervals and the mean value of the independent
* variable for each interval is calculated. To every interval corresponds a
* certain set of values of the second set, of which the mean value is
* calculated, and a designate number of moments which can be either centered,
* if the functioning mode is ′histogram′, or non-centered, if the
* mode is ′moments′. If the number of intervals assigned is lesser
* than one, the data are subdivided in classes of data having the same
* abscissa. <BR>
* </p>
* <p>
* <DT><STRONG>Inputs:</STRONG><BR>
* </DT>
* <OL>
* <LI>the file containing the data of the independent variable;</LI>
* <LI>the file containing the data which will be used as dependent variable;</LI>
* <LI>the first moment to calculate;</LI>
* <LI>the last moment to calculate;</LI>
* <LI>the insertion of an optional comment is also requested;</LI>
* </OL>
* <P>
* </DD>
* <DT><STRONG>Returns:</STRONG><BR>
* </DT>
* <DD>
* <OL>
* <LI>file containing: 1) the number of elements in each interval; 2) the mean
* value of the data in abscissa; 3) the mean value of the data in ordinate;
* n+2) the n-esimal moment of the data in ordinate.</LI>
* </OL>
* <P></DD>
* </p>
* <p>
* Note: The program uses the memory intensely. Therefore if we decide to have
* so many intervals as the data in abscissa, the program could not function
* correctly. Moreover the program assumes that the real data are preceded by
* two arrays, like in the files derived from a DEM.
* </p>
*/
public class CoupledFieldsMoments {
public double[][] process( RenderedImage map1RI, RenderedImage map2RI, int pBins, int pFirst, int pLast,
IJGTProgressMonitor pm, int binmode ) {
if (map2RI == null) {
map2RI = map1RI;
}
GearsMessageHandler msg = GearsMessageHandler.getInstance();
pm.message(msg.message("cb.vectorize"));
double[] U = vectorizeDoubleMatrix(map1RI);
double[] T = null;
QuickSortAlgorithm t = new QuickSortAlgorithm(pm);
if (map2RI == null) {
T = U;
t.sort(U, null);
} else {
T = vectorizeDoubleMatrix(map2RI);
t.sort(U, T);
}
SplitVectors theSplit = new SplitVectors();
int num_max = 1000;
/*
* if (bintype == 1) {
*/
pm.message(msg.message("cb.splitvector"));
split2realvectors(U, T, theSplit, pBins, num_max, pm);
/*
* } else { delta = FluidUtils.exponentialsplit2realvectors(U, T,
* theSplit, N, num_max, base); }
*/
pm.message(msg.message("cb.creatematrix"));
double[][] outCb = new double[theSplit.splitIndex.length][pLast - pFirst + 3];
binmode = 1; // kept for future expansion
if (binmode == 1) // always true for now, other modes not implemented yet
{
for( int h = 0; h < theSplit.splitIndex.length; h++ ) {
outCb[h][0] = calculateNthMoment(theSplit.splitValues1[h], (int) theSplit.splitIndex[h], 0.0, 1.0, pm);
outCb[h][1] = theSplit.splitIndex[h];
outCb[h][2] = calculateNthMoment(theSplit.splitValues2[h], (int) theSplit.splitIndex[h], 0.0, 1.0, pm);
if (pFirst == 1)
pFirst++;
for( int k = pFirst; k <= pLast; k++ ) {
outCb[h][k - pFirst + 3] = calculateNthMoment(theSplit.splitValues2[h], (int) theSplit.splitIndex[h], outCb[h][1],
(double) k, pm);
}
}
}
// else if (binmode == 2) // why is this exactly the same as the mode
// // 'H' ???
// {
// for( int h = 0; h < theSplit.splittedindex.length; h++ ) {
// moments[h][0] =
// FluidUtils.double_n_moment(theSplit.splittedvalues1[h],
// (int) theSplit.splittedindex[h], 0.0, 1.0);
// moments[h][1] =
// FluidUtils.double_n_moment(theSplit.splittedvalues2[h],
// (int) theSplit.splittedindex[h], 0.0, 1.0);
//
// if (firstmoment == 1)
// firstmoment++;
// for( int k = firstmoment; k <= secondmoment; k++ ) {
// moments[h][k - firstmoment + 2] = FluidUtils.double_n_moment(
// theSplit.splittedvalues2[h], (int) theSplit.splittedindex[h],
// moments[h][k - firstmoment + 1], (double) k);
// }
// }
// }
return outCb;
}
}