
uk.ac.leeds.ccg.grids.process.Grids_ProcessorGWS Maven / Gradle / Ivy
/*
* Copyright 2019 Andy Turner, University of Leeds.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.ac.leeds.ccg.grids.process;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import uk.ac.leeds.ccg.generic.io.Generic_Path;
import uk.ac.leeds.ccg.grids.d2.grid.Grids_Dimensions;
import uk.ac.leeds.ccg.grids.d2.grid.Grids_GridNumber;
import uk.ac.leeds.ccg.grids.d2.grid.d.Grids_GridDouble;
import uk.ac.leeds.ccg.grids.d2.grid.d.Grids_GridFactoryDouble;
import uk.ac.leeds.ccg.grids.core.Grids_Environment;
import uk.ac.leeds.ccg.grids.d2.util.Grids_Kernel;
import uk.ac.leeds.ccg.grids.d2.util.Grids_Utilities;
import java.math.BigInteger;
import java.math.RoundingMode;
import uk.ac.leeds.ccg.math.Math_BigDecimal;
/**
* Class of methods for processing and generating geographically weighted
* Grids_GridDouble statistics.
*
* @author Andy Turner
* @version 1.0.0
*/
public class Grids_ProcessorGWS extends Grids_Processor {
private static final long serialVersionUID = 1L;
public Grids_ProcessorGWS(Grids_Environment e) throws IOException,
ClassNotFoundException, Exception {
super(e);
}
/**
* For getting region uni-variate statistics.
*
* @param grid The grid to be processed
* @param statistics A list of the statistics to generate.
* @param distance The distance defining the region within which values will
* be used.
* @param weightIntersect Typically a number between 0 and 1 which controls
* the weight applied at the centre of the kernel
* @param weightFactor
*
* - {@code 0.0d} all values within distance will be equally weighted
* - {@code > 0.0d} means the edge of the kernel has a zero weight
* - {@code < 0.0d} means that the edge of the kernel has a weight of
* 1
* - {@code > -1.0d && < 1.0d} provides an inverse decay
*
* @param gf The grid facory for creating result grids.
* @param dp Decimal places.
* @param rm The Rounding Mode
* @return A set of grid based region univariate statistics.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
* @throws java.lang.Exception If encountered.
*/
public List regionUnivariateStatistics(
Grids_GridDouble grid, List statistics, BigDecimal distance,
BigDecimal weightIntersect, int weightFactor,
Grids_GridFactoryDouble gf, int dp, RoundingMode rm) throws
IOException, ClassNotFoundException, Exception {
List r = new ArrayList<>();
long ncols = grid.getNCols();
long nrows = grid.getNRows();
Grids_Dimensions dimensions = grid.getDimensions();
BigDecimal ndv = grid.ndv;
double ndvd = grid.getNoDataValue();
int cellDistance = grid.getCellDistance(distance).intValue();
// @HACK If cellDistance is so great that data for a single kernel is
// unlikely to fit in memory
if (cellDistance > 1024) {
return regionUnivariateStatisticsSlow(
grid,
statistics,
distance,
weightIntersect,
weightFactor,
gf, dp, rm);
}
boolean doSum = false;
boolean doWSum = false;
boolean doNWSum = false;
boolean doWSumN = false;
boolean doMean = false;
boolean doWMean1 = false;
boolean doWMean2 = false;
boolean doNWMean = false;
boolean doWMeanN = false;
boolean doProp = false;
boolean doWProp = false;
boolean doVar = false;
boolean doWVar = false;
boolean doSkew = false;
boolean doWSkew = false;
boolean doCVar = false;
boolean doWCVar = false;
boolean doCSkew = false;
boolean doWCSkew = false;
//boolean doZscore = false;
//boolean doWZscore = false;
for (int i = 0; i < statistics.size(); i++) {
//if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "FirstOrder" ) ) { doMean = true; doWMean = true; doNWMean = true; doWMeanN = true; doSum = true; doNWSum = true; doWSumN = true; }
//if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "WeightedFirstOrder" ) ) { doWMean = true; doNWMean = true; doWMeanN = true; doNWSum = true; doWSumN = true; }
if (((String) statistics.get(i)).equalsIgnoreCase("Sum")) {
doSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WSum")) {
doWSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("NWSum")) {
doNWSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WSumN")) {
doWSumN = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Mean")) {
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WMean1")) {
doWMean1 = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WMean2")) {
doWMean2 = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("NWMean")) {
doNWMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WMeanN")) {
doWMeanN = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("SecondOrder")) {
doMean = true;
doNWMean = true;
doProp = true;
doWProp = true;
doVar = true;
doWVar = true;
doSkew = true;
doWSkew = true;
doCVar = true;
doWCVar = true;
doCSkew = true;
doWCSkew = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WeightedSecondOrder")) {
doNWMean = true;
doWProp = true;
doWVar = true;
doWSkew = true;
doWCVar = true;
doWCSkew = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Prop")) {
doProp = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WProp")) {
doWProp = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Var")) {
doVar = true;
doMean = true;
}
// if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "WVar" ) ) { doWVar = true; doWMean = true; }
if (((String) statistics.get(i)).equalsIgnoreCase("Skew")) {
doSkew = true;
doMean = true;
}
// if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "WSkew" ) ) { doWSkew = true; doWMean = true; }
if (((String) statistics.get(i)).equalsIgnoreCase("CVar")) {
doCVar = true;
doVar = true;
doMean = true;
}
// if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "WCVar" ) ) { doWCVar = true; doWVar = true; doWMean = true; }
if (((String) statistics.get(i)).equalsIgnoreCase("CSkew")) {
doCSkew = true;
doSkew = true;
doVar = true;
doMean = true;
}
// if ( ( ( String ) statistics.elementAt( i ) ).equalsIgnoreCase( "WCSkew" ) ) { doWCSkew = true; doWSkew = true; doWVar = true; doWMean = true; }
}
Grids_GridDouble sumWeightGrid = null;
Grids_GridDouble sumGrid = null;
Grids_GridDouble wSumGrid = null;
Grids_GridDouble nWSumGrid = null;
Grids_GridDouble wSumNGrid = null;
Grids_GridDouble meanGrid = null;
Grids_GridDouble wMean1Grid = null;
Grids_GridDouble wMean2Grid = null;
Grids_GridDouble nWMeanGrid = null;
Grids_GridDouble wMeanNGrid = null;
Grids_GridDouble propGrid = null;
Grids_GridDouble wPropGrid = null;
Grids_GridDouble varGrid = null;
Grids_GridDouble wVarGrid = null;
Grids_GridDouble skewGrid = null;
Grids_GridDouble wSkewGrid = null;
Grids_GridDouble cVarGrid = null;
Grids_GridDouble wCVarGrid = null;
Grids_GridDouble cSkewGrid = null;
Grids_GridDouble wCSkewGrid = null;
//Grid2DSquareCellDouble zscoreGrid = null;
//Grid2DSquareCellDouble weightedZscoreGrid = null;
gf.setNoDataValue(ndvd);
// First order stats ( Mean WMean Sum WSum Density WDensity )
if (doSum || doWSum || doNWSum || doWSumN || doMean || doWMean1
|| doWMean2 || doNWMean || doWMeanN) {
sumWeightGrid = gf.create(nrows, ncols, dimensions);
if (doSum) {
sumGrid = gf.create(nrows, ncols, dimensions);
}
if (doWSum) {
wSumGrid = gf.create(nrows, ncols, dimensions);
}
if (doNWSum) {
nWSumGrid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doWSumN) {
wSumNGrid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doMean) {
meanGrid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doWMean1) {
wMean1Grid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doWMean2) {
wMean2Grid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doNWMean) {
nWMeanGrid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
if (doWMeanN) {
wMeanNGrid = (Grids_GridDouble) gf.create(nrows, ncols,
dimensions);
}
BigDecimal[] kernelParameters = Grids_Kernel.getKernelParameters(grid,
cellDistance, distance, weightIntersect, weightFactor, dp, rm);
BigDecimal totalSumWeight = kernelParameters[0];
BigDecimal totalCells = kernelParameters[1];
long row;
long col;
int p;
int q;
BigDecimal[][] kernel = Grids_Kernel.getKernelWeights(grid,
distance, weightIntersect, weightFactor, dp, rm);
double[][] data = getRowProcessInitialData(grid, cellDistance, 0);
for (row = 0; row < nrows; row++) {
// //debug
// System.out.println("row " + row);
for (col = 0; col < ncols; col++) {
// //debug
// if (row == 21) {
// System.out.println("col " + col);
// }
if (!(row == 0 && col == 0)) {
data = getRowProcessData(grid, data, cellDistance, row,
col);
}
BigDecimal sumCells = BigDecimal.ZERO;
BigDecimal sumWeight = BigDecimal.ZERO;
BigDecimal sum = BigDecimal.ZERO;
BigDecimal wSum = BigDecimal.ZERO;
BigDecimal nWSum = BigDecimal.ZERO;
BigDecimal wSumN = BigDecimal.ZERO;
BigDecimal wMean = BigDecimal.ZERO;
BigDecimal nWMean = BigDecimal.ZERO;
//wMeanN = 0.0d;
// Error thrown from here!
// GC overhead limit exceeded
// java.lang.OutOfMemoryError: GC overhead limit exceeded
// There is probably a better doing way?
BigDecimal cellX = grid.getCellX(col);
BigDecimal cellY = grid.getCellY(row);
// Calculate sumWeights and non-weighted stats
for (p = 0; p <= cellDistance * 2; p++) {
for (q = 0; q <= cellDistance * 2; q++) {
double v = data[p][q];
BigDecimal weight = kernel[p][q];
if ((weight.compareTo(ndv) != 0) && v != ndvd) {
sumWeight = sumWeight.add(weight);
sumCells = sumCells.add(BigDecimal.ONE);
sum = sum.add(BigDecimal.valueOf(v));
}
}
}
// Calculate weighted stats and store results
if ((sumCells.compareTo(BigDecimal.ZERO) == 1)
&& (sumWeight.compareTo(BigDecimal.ZERO) == 1)) {
for (p = 0; p <= cellDistance * 2; p++) {
for (q = 0; q <= cellDistance * 2; q++) {
double v = data[p][q];
BigDecimal weight = kernel[p][q];
if ((weight.compareTo(ndv) != 0) && v != ndvd) {
BigDecimal vbd = BigDecimal.valueOf(v);
sumWeight = sumWeight.add(weight);
sumCells = sumCells.add(BigDecimal.ONE);
sum = sum.add(vbd);
nWSum = nWSum.add(vbd.multiply(
Math_BigDecimal
.divideRoundIfNecessary(
sumWeight, totalSumWeight, dp, rm)).multiply(weight));
wSum = wSum.add(vbd.multiply(weight));
wMean = wMean.add(Math_BigDecimal
.divideRoundIfNecessary(vbd,
sumWeight, dp, rm).multiply(weight));
}
}
}
sumWeightGrid.setCell(row, col,
sumWeight.doubleValue() / totalSumWeight.doubleValue());
//if ( doSum ) { sumGrid.setCell( row, col, sum ); }
if (doSum) {
sumGrid.setCell(row, col,
sum.multiply(sumCells).doubleValue() / totalCells.doubleValue());
}
if (doWSum) {
wSumGrid.setCell(row, col, wSum.doubleValue());
}
if (doNWSum) {
nWSumGrid.setCell(row, col, nWSum.doubleValue());
}
if (doWSumN) {
wSumNGrid.setCell(row, col,
wSum.multiply(sumWeight).doubleValue() / totalSumWeight.doubleValue());
}
if (doMean) {
meanGrid.setCell(row, col, sum.doubleValue() / sumCells.doubleValue());
}
if (doWMean1) {
wMean1Grid.setCell(row, col, wSum.doubleValue() / sumWeight.doubleValue());
}
if (doWMean2) {
wMean2Grid.setCell(row, col, wMean.doubleValue());
}
if (doNWMean) {
nWMeanGrid.setCell(row, col, nWSum.doubleValue() / sumWeight.doubleValue());
}
if (doWMeanN) {
wMeanNGrid.setCell(row, col,
(wMean.multiply(sumWeight)).doubleValue() / totalSumWeight.doubleValue());
}
}
}
}
}
// Second order statistics ( coefficient of variation, skewness, kurtosis, zscore)
if (doProp || doWProp || doVar || doWVar || doSkew || doWSkew || doWCVar || doCSkew || doWCSkew) {
Generic_Path dir;
if (doProp) {
propGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWProp) {
wPropGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doVar) {
varGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWVar) {
wVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doSkew) {
skewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWSkew) {
wSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doCVar) {
cVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWCVar) {
wCVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doCSkew) {
cSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWCSkew) {
wCSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
BigDecimal[] kernelParameters = Grids_Kernel.getKernelParameters(grid,
cellDistance, distance, weightIntersect, weightFactor, dp, rm);
BigDecimal totalSumWeight = kernelParameters[0];
BigDecimal totalCells = kernelParameters[1];
double numerator;
double denominator;
long row;
long col;
int p;
int q;
BigDecimal[][] kernel = Grids_Kernel.getKernelWeights(grid, distance, weightIntersect, weightFactor, dp, rm);
double[][] data = getRowProcessInitialData(grid, cellDistance, 0);
//double[][] meanData = getRowProcessInitialData( meanGrid, cellDistance, 0 );
double[][] wMeanData = getRowProcessInitialData(wMean1Grid, cellDistance, 0);
for (row = 0; row < nrows; row++) {
for (col = 0; col < ncols; col++) {
if (row != 0 && col != 0) {
data = getRowProcessData(
grid, data, cellDistance, row, col);
wMeanData = getRowProcessData(
wMean1Grid, wMeanData, cellDistance, row, col);
//meanData = getRowProcessData( meanGrid, meanData, cellDistance, row, col );
}
//sDMean = 0.0d;
//sDMeanPow2 = 0.0d;
//sDMeanPow3 = 0.0d;
//sDMeanPow4 = 0.0d;
//sumCells = 0.0d;
BigDecimal sDWMean = BigDecimal.ZERO;
BigDecimal sDWMeanPow2 = BigDecimal.ZERO;
BigDecimal sDWMeanPow3 = BigDecimal.ZERO;
BigDecimal sDWMeanPow4 = BigDecimal.ZERO;
BigDecimal sumWeight = BigDecimal.ZERO;
BigDecimal cellX = grid.getCellX(col);
BigDecimal cellY = grid.getCellY(row);
// Take moments
for (p = 0; p <= cellDistance * 2; p++) {
for (q = 0; q <= cellDistance * 2; q++) {
double v = data[p][q];
BigDecimal wMean = BigDecimal.valueOf(wMeanData[p][q]);
BigDecimal weight = kernel[p][q];
if (v != ndvd && (weight.compareTo(ndv) != 0)) {
BigDecimal vbd = BigDecimal.valueOf(v);
sumWeight = sumWeight.add(weight);
sDWMean = sDWMean.add((vbd.subtract(wMean)).multiply(weight));
sDWMeanPow2 = sDWMeanPow2.add((vbd.subtract(wMean)).pow(2).multiply(weight));
sDWMeanPow3 = sDWMeanPow3.add((vbd.subtract(wMean)).pow(3).multiply(weight));
sDWMeanPow4 = sDWMeanPow4.add((vbd.subtract(wMean)).pow(4).multiply(weight));
//sumCells += 1.0d;
//if ( doMean ) {
// sDMean += ( value - mean );
// sDMeanPow2 += Math.pow( ( value - mean ), 2.0d );
// sDMeanPow3 += Math.pow( ( value - mean ), 3.0d );
// sDMeanPow4 += Math.pow( ( value - mean ), 4.0d );
//}
}
}
}
//if ( sumCells > 0.0d && sumWeight > 0.0d ) {
if (sumWeight.compareTo(BigDecimal.ZERO) == 1) {
//if ( doProp ) {
// propGrid.setCell( row, col, ( sDMean / sumCells ) );
//}
if (doWProp) {
wPropGrid.setCell(row, col, sDWMean.doubleValue() / sumWeight.doubleValue());
}
//if ( doVar ) {
// varGrid.setCell( row, col, ( sDMeanPow2 / sumCells ) );
//}
if (doWVar) {
wVarGrid.setCell(row, col, sDWMeanPow2.doubleValue() / sumWeight.doubleValue());
}
//if ( doSkew ) {
// // Need to control for Math.pow as it does not do roots of negative numbers at all well!
// numerator = sDMeanPow3 / sumCells;
// if ( numerator > 0.0d ) {
// skewGrid.setCell(row, col, ( Math.pow( numerator, 1.0d / 3.0d ) ) );
// }
// if ( numerator == 0.0d ) {
// skewGrid.setCell( row, col, numerator );
// }
// if ( numerator < 0.0d ) {
// skewGrid.setCell( row, col, -1.0d * ( Math.pow( Math.abs( numerator ), 1.0d / 3.0d ) ) );
// }
//}
if (doWSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
numerator = sDWMeanPow3.doubleValue() / sumWeight.doubleValue();
if (numerator > 0.0d) {
wSkewGrid.setCell(row, col,
(Math.pow(numerator, 1.0d / 3.0d)));
}
if (numerator == 0.0d) {
wSkewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
wSkewGrid.setCell(row, col,
-1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d)));
}
}
//if ( doCVar ) {
// denominator = varGrid.getCell( row, col );
// if ( denominator > 0.0d && denominator != noDataValue) {
// numerator = propGrid.getCell( row, col );
// if ( numerator != noDataValue ) {
// cVarGrid.setCell( row, col, ( numerator / denominator ) );
// }
// }
//}
if (doWCVar) {
denominator = wVarGrid.getCell(row, col);
if (denominator > 0.0d && denominator != ndvd) {
numerator = wPropGrid.getCell(row, col);
if (numerator != ndvd) {
wCVarGrid.setCell(row, col,
(numerator / denominator));
}
}
}
//if ( doCSkew ) {
// // Need to control for Math.pow as it does not do roots of negative numbers at all well!
// denominator = varGrid.getCell( row, col );
// if ( denominator > 0.0d && denominator != noDataValue ) {
// numerator = sDMeanPow3 / sumCells;
// if ( numerator > 0.0d ) {
// cSkewGrid.setCell( row, col, ( Math.pow( numerator, 1.0d / 3.0d ) ) / denominator );
// }
// if ( numerator == 0.0d ) {
// cSkewGrid.setCell( row, col, numerator );
// }
// if ( numerator < 0.0d ) {
// cSkewGrid.setCell( row, col, ( -1.0d * ( Math.pow( Math.abs( numerator ), 1.0d / 3.0d ) ) ) / denominator );
// }
// }
//}
if (doWCSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
denominator = wVarGrid.getCell(row, col);
if (denominator > 0.0d && denominator != ndvd) {
numerator = sDWMeanPow3.doubleValue() / sumWeight.doubleValue();
if (numerator > 0.0d) {
wCSkewGrid.setCell(row, col,
(Math.pow(numerator, 1.0d / 3.0d)) / denominator);
}
if (numerator == 0.0d) {
wCSkewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
wCSkewGrid.setCell(row, col,
(-1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d))) / denominator);
}
}
}
}
}
}
}
/*
* if ( doZscore || doWZscore ) { if ( doZscore ) { zscoreGrid =
* gridFactory.createGrid2DSquareCellDouble( nrows, ncols, xllcorner,
* yllcorner, cellsize, noDataValue ); } if ( doWZscore ) {
* weightedZscoreGrid = gridFactory.createGrid2DSquareCellDouble( nrows,
* ncols, xllcorner, yllcorner, cellsize, noDataValue ); } double
* weightedMean; double standardDeviation; double
* weightedStandardDeviation; for ( int i = 0; i < nrows; i ++ ) { for (
* int j = 0; j < ncols; j ++ ) { value = grid.getCell( i, j ); if (
* value != noDataValue ) { standardDeviation =
* standardDeviationGrid.getCell( i, j ); if ( standardDeviation !=
* noDataValue && standardDeviation > 0.0d ) { zscoreGrid.setCell( i, j,
* ( value - meanGrid.getCell( i, j ) ) / standardDeviation ); }
* weightedStandardDeviation = weightedStandardDeviationGrid.getCell( i,
* j ); if ( weightedStandardDeviation != noDataValue &&
* weightedStandardDeviation > 0.0d ) { weightedZscoreGrid.setCell( i,
* j, ( value - weightedMeanGrid.getCell( i, j ) ) /
* weightedStandardDeviation ); } } } } Vector secondOrderStatistics =
* new Vector( 1 ); secondOrderStatistics.add( new String( "Mean" ) );
* Grids_GridDouble[] meanWeightedZscoreGrid =
* regionUnivariateStatistics( weightedZscoreGrid,
* secondOrderStatistics, distance, weightIntersect, weightFactor,
* gridFactory ); Grids_GridDouble[] meanZscoreGrid =
* regionUnivariateStatistics( zscoreGrid, secondOrderStatistics,
* distance, weightIntersect, weightFactor, gridFactory );
* weightedZscoreGrid = meanWeightedZscoreGrid[ 0 ]; zscoreGrid =
* meanZscoreGrid[ 0 ]; }
*/
sumWeightGrid.setName("SumWeight_" + grid.getName());
r.add(sumWeightGrid);
if (doSum) {
sumGrid.setName("Sum_" + grid.getName());
r.add(sumGrid);
}
if (doWSum) {
wSumGrid.setName("WSum_" + grid.getName());
r.add(wSumGrid);
}
if (doNWSum) {
nWSumGrid.setName("NWSum_" + grid.getName());
r.add(nWSumGrid);
}
if (doWSumN) {
wSumNGrid.setName("WSumN_" + grid.getName());
r.add(wSumNGrid);
}
if (doMean) {
meanGrid.setName("Mean_" + grid.getName());
r.add(meanGrid);
}
if (doWMean1) {
wMean1Grid.setName("WMean1_" + grid.getName());
r.add(wMean1Grid);
}
if (doWMean2) {
wMean2Grid.setName("WMean2_" + grid.getName());
r.add(wMean2Grid);
}
if (doNWMean) {
nWMeanGrid.setName("NWMean_" + grid.getName());
r.add(nWMeanGrid);
}
if (doWMeanN) {
wMeanNGrid.setName("WMeanN_" + grid.getName());
r.add(wMeanNGrid);
}
if (doProp) {
propGrid.setName("Prop_" + grid.getName());
r.add(propGrid);
}
if (doWProp) {
wPropGrid.setName("WProp_" + grid.getName());
r.add(wPropGrid);
}
if (doVar) {
varGrid.setName("Var_" + grid.getName());
r.add(varGrid);
}
if (doWVar) {
wVarGrid.setName("WVar_" + grid.getName());
r.add(wVarGrid);
}
if (doSkew) {
skewGrid.setName("Skew_" + grid.getName());
r.add(skewGrid);
}
if (doWSkew) {
wSkewGrid.setName("WSkew_" + grid.getName());
r.add(wSkewGrid);
}
if (doCVar) {
cVarGrid.setName("CVar_" + grid.getName());
r.add(cVarGrid);
}
if (doWCVar) {
wCVarGrid.setName("WCVar_" + grid.getName());
r.add(wCVarGrid);
}
if (doCSkew) {
cSkewGrid.setName("CSkew" + grid.getName());
r.add(cSkewGrid);
}
if (doWCSkew) {
wCSkewGrid.setName("WCSkew_" + grid.getName());
r.add(wCSkewGrid);
}
return r;
}
/**
* Get region uni-variate statistics.
*
* @param g The grid to be processed.
* @param statistics The statistics to generate.
* @param d The distance defining the region within which values will be
* used. At distances weights if applied are zero
* @param wi The weight intersect - typically a number between 0 and 1 which
* controls the weight applied at the centre of the kernel
* @param wf The weight factor.
* @param gf The factory used to create grids.
* @param dp The number of decimal places for BigDecimal arithmetic..
* @param rm The {@link RoundingMode} to use for BigDecimal arithmetic.
* @return Region uni-variate statistics.
* @throws java.io.IOException If encountered.
* @throws java.lang.ClassNotFoundException If encountered.
*/
public List regionUnivariateStatisticsSlow(
Grids_GridDouble g, List statistics, BigDecimal d,
BigDecimal wi, int wf, Grids_GridFactoryDouble gf, int dp,
RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
List result = new ArrayList<>();
long ncols = g.getNCols();
long nrows = g.getNRows();
Grids_Dimensions dimensions = g.getDimensions();
double noDataValue = g.getNoDataValue();
int cellDistance = g.getCellDistance(d).intValue();
boolean doMean = false;
boolean doWMean = false;
boolean doSum = false;
boolean doWSum = false;
boolean doProp = false;
boolean doWProp = false;
boolean doVar = false;
boolean doWVar = false;
boolean doSkew = false;
boolean doWSkew = false;
boolean doCVar = false;
boolean doWCVar = false;
boolean doCSkew = false;
boolean doWCSkew = false;
//boolean doZscore = false;
//boolean doWZscore = false;
long row;
long col;
for (int i = 0; i < statistics.size(); i++) {
if (((String) statistics.get(i)).equalsIgnoreCase("FirstOrder")) {
doMean = true;
doWMean = true;
doSum = true;
doWSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WeightedFirstOrder")) {
doWMean = true;
doWSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Mean")) {
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WMean")) {
doWMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Sum")) {
doSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WSum")) {
doWSum = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("SecondOrder")) {
doMean = true;
doWMean = true;
doProp = true;
doWProp = true;
doVar = true;
doWVar = true;
doSkew = true;
doWSkew = true;
doCVar = true;
doWCVar = true;
doCSkew = true;
doWCSkew = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WeightedSecondOrder")) {
doWMean = true;
doWProp = true;
doWVar = true;
doWSkew = true;
doWCVar = true;
doWCSkew = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Prop")) {
doProp = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WProp")) {
doWProp = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Var")) {
doVar = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WVar")) {
doWVar = true;
doWMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("Skew")) {
doSkew = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WSkew")) {
doWSkew = true;
doWMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("CVar")) {
doCVar = true;
doVar = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WCVar")) {
doWCVar = true;
doWVar = true;
doWMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("CSkew")) {
doCSkew = true;
doSkew = true;
doVar = true;
doMean = true;
}
if (((String) statistics.get(i)).equalsIgnoreCase("WCSkew")) {
doWCSkew = true;
doWSkew = true;
doWVar = true;
doWMean = true;
}
}
Grids_GridDouble meanGrid = null;
Grids_GridDouble wMeanGrid = null;
Grids_GridDouble sumGrid = null;
Grids_GridDouble wSumGrid = null;
Grids_GridDouble propGrid = null;
Grids_GridDouble wPropGrid = null;
Grids_GridDouble varGrid = null;
Grids_GridDouble wVarGrid = null;
Grids_GridDouble skewGrid = null;
Grids_GridDouble wSkewGrid = null;
Grids_GridDouble cVarGrid = null;
Grids_GridDouble wCVarGrid = null;
Grids_GridDouble cSkewGrid = null;
Grids_GridDouble wCSkewGrid = null;
gf.setNoDataValue(noDataValue);
// First order stats ( Mean WMean Sum WSum Density WDensity )
if (doMean || doWMean || doSum || doWSum) {
Generic_Path dir;
if (doMean) {
meanGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWMean) {
wMeanGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doSum) {
sumGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWSum) {
wSumGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
BigDecimal[] kernelParameters = Grids_Kernel.getKernelParameters(g, cellDistance, d, wi, wf, dp, rm);
BigDecimal totalSumWeight = kernelParameters[0];
BigDecimal totalCells = kernelParameters[1];
for (row = 0; row < nrows; row++) {
//debug
System.out.println("processing row " + row + " out of " + nrows);
for (col = 0; col < ncols; col++) {
BigDecimal sumWeight = BigDecimal.ZERO;
BigDecimal wMean = BigDecimal.ZERO;
BigDecimal sumCells = BigDecimal.ZERO;
BigDecimal wSum = BigDecimal.ZERO;
BigDecimal sum = BigDecimal.ZERO;
BigDecimal cellX = g.getCellX(col);
BigDecimal cellY = g.getCellY(row);
// Calculate sumWeights and non-weighted stats
for (int p = -cellDistance; p <= cellDistance; p++) {
for (int q = -cellDistance; q <= cellDistance; q++) {
double v = g.getCell(row + p, col + q);
if (v != noDataValue) {
BigDecimal thisCellX = g.getCellX(col + q);
BigDecimal thisCellY = g.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(cellX, cellY, thisCellX, thisCellY, dp, rm);
if (thisDistance.compareTo(d) == -1) {
sumWeight = sumWeight.add(Grids_Kernel.getKernelWeight(d, wi, wf, thisDistance, dp, rm));
sumCells = sumCells.add(BigDecimal.ONE);
sum = sum.add(BigDecimal.valueOf(v));
}
}
}
}
//sumWeightGrid.setCell( i, j, sumWeight );
//sumCellGrid.setCell( i, j, sumCells );
// Calculate weighted stats and store results
if (sumCells.compareTo(BigDecimal.ZERO) == 1 && sumWeight.compareTo(BigDecimal.ZERO) == 1) {
for (int p = -cellDistance; p <= cellDistance; p++) {
for (int q = -cellDistance; q <= cellDistance; q++) {
double v = g.getCell(row + p, col + q);
if (v != noDataValue) {
BigDecimal thisCellX = g.getCellX(col + q);
BigDecimal thisCellY = g.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(cellX, cellY, thisCellX, thisCellY, dp, rm);
if (thisDistance.compareTo(d) == -1) {
BigDecimal weight = Grids_Kernel.getKernelWeight(d, wi, wf, thisDistance, dp, rm);
//wMean += ( value / sumWeight ) * weight;
//wMean += ( value / sumCells ) * weight;
wSum = wSum.add(BigDecimal.valueOf(v).multiply(weight));
}
}
}
}
if (doMean) {
meanGrid.setCell(row, col, sum.doubleValue() / sumCells.doubleValue());
}
if (doWMean) {
wMeanGrid.setCell(row, col, wSum.doubleValue() / sumWeight.doubleValue());
}
//if ( doSum ) { sumGrid.setCell( row, col, sum ); }
//if ( doWSum ) { wSumGrid.setCell( row, col, wSum ); }
if (doSum) {
sumGrid.setCell(row, col, (sum.multiply(sumCells)).doubleValue() / totalCells.doubleValue());
}
if (doWSum) {
wSumGrid.setCell(row, col, (wSum.multiply(sumWeight)).doubleValue() / totalSumWeight.doubleValue());
}
}
}
}
}
// Second order statistics ( coefficient of variation, skewness, kurtosis, zscore)
if (doProp || doWProp || doVar || doWVar || doSkew || doWSkew || doWCVar || doCSkew || doWCSkew) {
Generic_Path dir;
if (doProp) {
propGrid = gf.create(nrows, ncols, dimensions);
}
if (doWProp) {
wPropGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doVar) {
varGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWVar) {
wVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doSkew) {
skewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWSkew) {
wSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doCVar) {
cVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWCVar) {
wCVarGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doCSkew) {
cSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
if (doWCSkew) {
wCSkewGrid = (Grids_GridDouble) gf.create(nrows, ncols, dimensions);
}
BigDecimal[] kernelParameters = Grids_Kernel.getKernelParameters(g, cellDistance, d, wi, wf, dp, rm);
BigDecimal totalSumWeight = kernelParameters[0];
BigDecimal totalCells = kernelParameters[1];
BigDecimal mean = BigDecimal.ZERO;
for (row = 0; row < nrows; row++) {
//debug
System.out.println("processing row " + row + " out of " + nrows);
for (col = 0; col < ncols; col++) {
BigDecimal sDMean = BigDecimal.ZERO;
BigDecimal sDMeanPow2 = BigDecimal.ZERO;
BigDecimal sDMeanPow3 = BigDecimal.ZERO;
BigDecimal sDMeanPow4 = BigDecimal.ZERO;
BigDecimal sumCells = BigDecimal.ZERO;
BigDecimal sDWMean = BigDecimal.ZERO;
BigDecimal sDWMeanPow2 = BigDecimal.ZERO;
BigDecimal sDWMeanPow3 = BigDecimal.ZERO;
BigDecimal sDWMeanPow4 = BigDecimal.ZERO;
BigDecimal sumWeight = BigDecimal.ZERO;
BigDecimal cellX = g.getCellX(col);
BigDecimal cellY = g.getCellY(row);
// Take moments
for (int p = -cellDistance; p <= cellDistance; p++) {
for (int q = -cellDistance; q <= cellDistance; q++) {
double v = g.getCell(row + p, col + q);
if (v != noDataValue) {
BigDecimal thisCellX = g.getCellX(col + q);
BigDecimal thisCellY = g.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(cellX, cellY, thisCellX, thisCellY, dp, rm);
if (thisDistance.compareTo(d) == -1) {
BigDecimal vbd = BigDecimal.valueOf(v);
BigDecimal wMean = BigDecimal.valueOf(wMeanGrid.getCell(row + p, col + q));
BigDecimal weight = Grids_Kernel.getKernelWeight(d, wi, wf, thisDistance, dp, rm);
sumWeight = sumWeight.add(weight);
BigDecimal delta = vbd.subtract(wMean);
sDWMean = sDWMean.add(delta.multiply(weight));
sDWMeanPow2 = sDWMeanPow2.add(delta.pow(2).multiply(weight));
sDWMeanPow3 = sDWMeanPow3.add(delta.pow(3).multiply(weight));
sDWMeanPow4 = sDWMeanPow4.add(delta.pow(4).multiply(weight));
sumCells = sumCells.add(BigDecimal.ONE);
if (doMean) {
sDMean = sDMean.add((vbd.subtract(mean)));
sDMeanPow2 = sDMeanPow2.add(delta.pow(2));
sDMeanPow3 = sDMeanPow3.add(delta.pow(3));
sDMeanPow4 = sDMeanPow4.add(delta.pow(4));
}
}
}
}
}
if (sumCells.compareTo(BigDecimal.ZERO) == 1 && sumWeight.compareTo(BigDecimal.ZERO) == 1) {
if (doProp) {
propGrid.setCell(row, col, (sDMean.doubleValue() / sumCells.doubleValue()));
}
if (doWProp) {
wPropGrid.setCell(row, col, (sDWMean.doubleValue() / sumWeight.doubleValue()));
}
if (doVar) {
varGrid.setCell(row, col, (sDMeanPow2.doubleValue() / sumCells.doubleValue()));
}
if (doWVar) {
wVarGrid.setCell(row, col, (sDWMeanPow2.doubleValue() / sumWeight.doubleValue()));
}
if (doSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
double numerator = sDMeanPow3.doubleValue() / sumCells.doubleValue();
if (numerator > 0.0d) {
skewGrid.setCell(row, col, (Math.pow(numerator, 1.0d / 3.0d)));
}
if (numerator == 0.0d) {
skewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
skewGrid.setCell(row, col, -1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d)));
}
}
if (doWSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
double numerator = sDWMeanPow3.doubleValue() / sumWeight.doubleValue();
if (numerator > 0.0d) {
wSkewGrid.setCell(row, col, (Math.pow(numerator, 1.0d / 3.0d)));
}
if (numerator == 0.0d) {
wSkewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
wSkewGrid.setCell(row, col, -1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d)));
}
}
if (doCVar) {
double denominator = varGrid.getCell(row, col);
if (denominator > 0.0d && denominator != noDataValue) {
double numerator = propGrid.getCell(row, col);
if (numerator != noDataValue) {
cVarGrid.setCell(row, col, (numerator / denominator));
}
}
}
if (doWCVar) {
double denominator = wVarGrid.getCell(row, col);
if (denominator > 0.0d && denominator != noDataValue) {
double numerator = wPropGrid.getCell(row, col);
if (numerator != noDataValue) {
wCVarGrid.setCell(row, col, (numerator / denominator));
}
}
}
if (doCSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
double denominator = varGrid.getCell(row, col);
if (denominator > 0.0d && denominator != noDataValue) {
double numerator = sDMeanPow3.doubleValue() / sumCells.doubleValue();
if (numerator > 0.0d) {
cSkewGrid.setCell(row, col, (Math.pow(numerator, 1.0d / 3.0d)) / denominator);
}
if (numerator == 0.0d) {
cSkewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
cSkewGrid.setCell(row, col, (-1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d))) / denominator);
}
}
}
if (doWCSkew) {
// Need to control for Math.pow as it does not do roots of negative numbers at all well!
double denominator = wVarGrid.getCell(row, col);
if (denominator > 0.0d && denominator != noDataValue) {
double numerator = sDWMeanPow3.doubleValue() / sumWeight.doubleValue();
if (numerator > 0.0d) {
wCSkewGrid.setCell(row, col, (Math.pow(numerator, 1.0d / 3.0d)) / denominator);
}
if (numerator == 0.0d) {
wCSkewGrid.setCell(row, col, numerator);
}
if (numerator < 0.0d) {
wCSkewGrid.setCell(row, col, (-1.0d * (Math.pow(Math.abs(numerator), 1.0d / 3.0d))) / denominator);
}
}
}
}
}
}
}
/*
* if ( doZscore || doWZscore ) { if ( doZscore ) { zscoreGrid =
* gridFactory.createGrid2DSquareCellDouble( nrows, ncols, xllcorner,
* yllcorner, cellsize, noDataValue ); } if ( doWZscore ) {
* weightedZscoreGrid = gridFactory.createGrid2DSquareCellDouble( nrows,
* ncols, xllcorner, yllcorner, cellsize, noDataValue ); } double
* weightedMean; double standardDeviation; double
* weightedStandardDeviation; for ( int i = 0; i < nrows; i ++ ) { for (
* int j = 0; j < ncols; j ++ ) { value = grid.getCell( i, j ); if (
* value != noDataValue ) { standardDeviation =
* standardDeviationGrid.getCell( i, j ); if ( standardDeviation !=
* noDataValue && standardDeviation > 0.0d ) { zscoreGrid.setCell( i, j,
* ( value - meanGrid.getCell( i, j ) ) / standardDeviation ); }
* weightedStandardDeviation = weightedStandardDeviationGrid.getCell( i,
* j ); if ( weightedStandardDeviation != noDataValue &&
* weightedStandardDeviation > 0.0d ) { weightedZscoreGrid.setCell( i,
* j, ( value - weightedMeanGrid.getCell( i, j ) ) /
* weightedStandardDeviation ); } } } } Vector secondOrderStatistics =
* new Vector( 1 ); secondOrderStatistics.add( new String( "Mean" ) );
* Grids_GridDouble[] meanWeightedZscoreGrid =
* regionUnivariateStatistics( weightedZscoreGrid,
* secondOrderStatistics, distance, weightIntersect, weightFactor,
* gridFactory ); Grids_GridDouble[] meanZscoreGrid =
* regionUnivariateStatistics( zscoreGrid, secondOrderStatistics,
* distance, weightIntersect, weightFactor, gridFactory );
* weightedZscoreGrid = meanWeightedZscoreGrid[ 0 ]; zscoreGrid =
* meanZscoreGrid[ 0 ]; }
*/
if (doSum) {
sumGrid.setName("Sum");
result.add(sumGrid);
}
if (doWSum) {
wSumGrid.setName("WSum");
result.add(wSumGrid);
}
if (doMean) {
meanGrid.setName("Mean");
result.add(meanGrid);
}
if (doWMean) {
wMeanGrid.setName("WMean");
result.add(wMeanGrid);
}
if (doProp) {
propGrid.setName("Prop");
result.add(propGrid);
}
if (doWProp) {
wPropGrid.setName("WProp");
result.add(wPropGrid);
}
if (doVar) {
varGrid.setName("Var");
result.add(varGrid);
}
if (doWVar) {
wVarGrid.setName("WVar");
result.add(wVarGrid);
}
if (doSkew) {
skewGrid.setName("Skew");
result.add(skewGrid);
}
if (doWSkew) {
wSkewGrid.setName("WSkew");
result.add(wSkewGrid);
}
if (doCVar) {
cVarGrid.setName("CVar");
result.add(cVarGrid);
}
if (doWCVar) {
wCVarGrid.setName("WCVar");
result.add(wCVarGrid);
}
if (doCSkew) {
cSkewGrid.setName("CSkew");
result.add(cSkewGrid);
}
if (doWCSkew) {
wCSkewGrid.setName("WCSkew");
result.add(wCSkewGrid);
}
return result;
}
/**
* Returns an Grid2DSquareCellDouble[] containing geometric density
* surfaces. The algorithm used for generating a geometric density surfaces
* is described in: Turner A (2000) Density Data Generation for Spatial Data
* Mining Applications.
* http://www.geog.leeds.ac.uk/people/a.turner/papers/geocomp00/gc_017.htm
*
* @param grid - the input Grid2DSquareCellDouble used
* @param distance - the distance limiting the maximum scale density surface
*/
/*
* public Grids_GridDouble[] geometricDensity( Grids_GridDouble
* grid, double distance ) { int nrows = grid.getNRows(); int ncols =
* grid.getNCols(); double cellsize = grid.getCellsize(); double
* noDataValue = grid.getNoDataValue(); Grids_GridDouble[] result =
* null; try { result = ( new Grids_GridFactoryDouble()
* ).createGrid2DSquareCellDouble( nrows, ncols, grid.getXllcorner(),
* grid.getYllcorner(), cellsize, noDataValue ); } catch (
* java.lang.OutOfMemoryError e0 ) { try { if ( grid instanceof
* Grid2DSquareCellDoubleFile ) { result = ( new
* Grid2DSquareCellDoubleFileFactory( ( ( Grid2DSquareCellDoubleFile ) grid
* ).getDataDirectory() ) ).createGrid2DSquareCellDouble( nrows, ncols,
* grid.getXllcorner(), cellsize, grid.getYllcorner(), noDataValue ); } else
* { result = ( new Grid2DSquareCellDoubleFileFactory()
* ).createGrid2DSquareCellDouble( nrows, ncols, grid.getXllcorner(),
* cellsize, grid.getYllcorner(), noDataValue ); } //} catch (
* java.io.IOException e1 ) { } catch ( java.lang.Exception e1 ) {
* System.out.println( e1 ); boolean set = false; while ( ! set ) { try {
* System.out.println( "Please try setting a different directory for storing
* the data." ); result = ( new Grid2DSquareCellDoubleFileFactory(
* Grids_Utilities.setDirectory() ) ).createGrid2DSquareCellDouble( nrows, ncols,
* grid.getXllcorner(), cellsize, grid.getYllcorner(), noDataValue ); set =
* true; //} catch ( java.io.IOException e2 ) { } catch (
* java.lang.Exception e2 ) { System.out.println( e1 ); } } } } int
* cellDistance = ( int ) Math.ceil( distance / cellsize ); double weight =
* 1.0d; double d1; boolean chunkProcess = false; try { densityArray =
* geometricDensity( grid, distance, new Grids_GridFactoryDouble() ) ;
* } catch ( java.lang.OutOfMemoryError e ) { if ( cellDistance < (
* Math.max( nrows, ncols ) / 2 ) ) { System.out.println( e.toString() +
* "... Attempting to process in chunks..." ); int chunkSize = cellDistance;
* density = geometricDensity( grid, distance, chunkSize ); for ( int cellID
* = 0; cellID < nrows * ncols; cellID ++ ) { result.setCell( cellID,
* density.getCell( cellID ) ); } chunkProcess = true; } else {
* System.out.println( e.toString() + "... Processing using available
* filespace..." ); try { if ( grid instanceof Grid2DSquareCellDoubleFile )
* { densityArray = geometricDensity( grid, distance, new
* Grid2DSquareCellDoubleFileFactory( ( ( Grid2DSquareCellDoubleFile ) grid
* ).getDataDirectory() ) ); } else { densityArray = geometricDensity( grid,
* distance, new Grid2DSquareCellDoubleFileFactory() ); } //} catch (
* java.io.IOException e1 ) { } catch ( java.lang.Exception e1 ) {
* System.out.println( e1 ); boolean set = false; while ( ! set ) { try {
* System.out.println( "Please try setting a different directory for storing
* the data." ); densityArray = geometricDensity( grid, distance, new
* Grid2DSquareCellDoubleFileFactory( Grids_Utilities.setDirectory() ) ); set =
* true; //} catch ( java.io.IOException e2 ) { } catch (
* java.lang.Exception e2 ) { System.out.println( e1 ); } } } } } if ( !
* chunkProcess ) { double thisDistance = cellsize; for ( int i = 0; i <
* densityArray.length; i ++ ) { for ( int cellID = 0; cellID < nrows *
* ncols; cellID ++ ) { d1 = densityArray[ i ].getCell( cellID ); if (
* grid.getCell( cellID ) != noDataValue ) { result.addToCell( cellID, d1 *
* weight ); } } thisDistance *= 2.0d; } } return result; }
*/
/**
* Returns an Grids_GridDouble[] containing geometric density surfaces at a
* range of scales: result[ 0 ] - is the result at the first scale ( double
* the cellsize of grid ) result[ 1 ] - if it exists is the result at the
* second scale ( double the cellsize of result[ 0 ] ) result[ n ] - if it
* exists is the result at the ( n + 1 )th scale ( double the cellsize of
* result[ n - 1 ] ) The algorithm used for generating a geometric density
* surface is described in: Turner A (2000) Density Data Generation for
* Spatial Data Mining Applications.
* http://www.geog.leeds.ac.uk/people/a.turner/papers/geocomp00/gc_017.htm
*
* @param grid - the input Grids_GridDouble
* @param distance - the distance limiting the maximum scale of geometric
* density surface produced
* @param gridFactory - the Grids_GridFactoryDouble to be used in processing
* @return geometric density.
* @throws Exception If encountered.
* @throws IOException If encountered.
* @throws ClassNotFoundException If encountered.
*/
public Grids_GridDouble[] geometricDensity(Grids_GridDouble grid,
BigDecimal distance, Grids_GridFactoryDouble gridFactory)
throws IOException, ClassNotFoundException, Exception {
BigInteger n = grid.getStats().getN();
long nrows = grid.getNRows();
long ncols = grid.getNCols();
Grids_Dimensions dimensions = grid.getDimensions();
double ndv = grid.getNoDataValue();
int cellDistance = grid.getCellDistance(distance).intValue();
double d1;
double d2;
double d3;
long height = nrows;
long width = ncols;
int i1;
int numberOfIterations;
int doubler = 1;
int growth = 1;
long row;
long col;
// Calculate number of iterations and initialise result.
numberOfIterations = 0;
i1 = Math.min(cellDistance, (int) Math.floor(Math.max(nrows, ncols) / 2));
for (int i = 0; i < cellDistance; i++) {
if (i1 > 1) {
i1 = i1 / 2;
numberOfIterations++;
} else {
break;
}
}
Grids_GridDouble[] result = new Grids_GridDouble[numberOfIterations];
Generic_Path dir;
// If all values are noDataValues return noDataValue density results
if (n.compareTo(BigInteger.ZERO) == 0) {
for (int i = 0; i < numberOfIterations; i++) {
result[i] = (Grids_GridDouble) gridFactory.create(grid);
}
return result;
}
// Initialise temporary numerator and normaliser grids
Grids_GridDouble g2 = (Grids_GridDouble) gridFactory.create(nrows, ncols);
Grids_GridDouble g3 = (Grids_GridDouble) gridFactory.create(nrows, ncols);
for (row = 0; row < nrows; row++) {
for (col = 0; col < ncols; col++) {
d1 = grid.getCell(row, col);
if (d1 != ndv) {
//g2.initCell( row, col, d1 );
//g3.initCell( row, col, 1.0d );
g2.setCell(row, col, d1);
g3.setCell(row, col, 1.0d);
}
}
}
// Densification
Grids_GridDouble g4;
Grids_GridDouble g5;
Grids_GridDouble g6;
Grids_GridDouble g7;
Grids_GridDouble density;
for (int iteration = 0; iteration < numberOfIterations; iteration++) {
//System.out.println( "Iteration " + ( iteration + 1 ) + " out of " + numberOfIterations );
height += doubler;
width += doubler;
growth *= 2;
// Step 1: Aggregate
g4 = (Grids_GridDouble) gridFactory.create(nrows, ncols);
g5 = (Grids_GridDouble) gridFactory.create(nrows, ncols);
g6 = (Grids_GridDouble) gridFactory.create(nrows, ncols);
for (int p = 0; p < doubler; p++) {
for (int q = 0; q < doubler; q++) {
for (row = 0; row < height; row += doubler) {
for (col = 0; col < width; col += doubler) {
d1 = g2.getCell((row + p),
(col + q))
+ g2.getCell((row + p),
(col + q - doubler))
+ g2.getCell((row + p - doubler),
(col + q))
+ g2.getCell((row + p - doubler),
(col + q - doubler));
//g4.initCell( ( row + p ), ( col + q ), d1 );
g4.setCell((row + p),
(col + q),
d1);
d2 = g3.getCell((row + p),
(col + q))
+ g3.getCell((row + p),
(col + q - doubler))
+ g3.getCell((row + p - doubler),
(col + q))
+ g3.getCell((row + p - doubler),
(col + q - doubler));
//g5.initCell( ( row + p ), ( col + q ), d2 );
g5.setCell((row + p), (col + q), d2);
if (d2 != 0.0d) {
//g6.initCell( ( row + p ), ( col + q ), ( d1 / d2 ) );
g6.setCell((row + p),
(col + q),
(d1 / d2));
}
}
}
}
}
// g2.clear();
// g3.clear();
// Step 2: Average over output region.
// 1. This is probably the slowest part of the algorithm and gets slower
// with each iteration. Using alternative data structures and
// processing strategies this step can probably be speeded up a lot.
//density = gridFactory.createGrid2DSquareCellDouble( nrows, ncols, 0.0d, 0.0d, cellsize, 0.0d );
gridFactory.setNoDataValue(ndv);
density = (Grids_GridDouble) gridFactory.create(nrows, ncols, dimensions);
for (row = 0; row < nrows; row += doubler) {
for (int p = 0; p < doubler; p++) {
for (col = 0; col < ncols; col += doubler) {
for (int q = 0; q < doubler; q++) {
d1 = 0.0d;
d2 = 0.0d;
for (int a = 0; a < growth; a++) {
for (int b = 0; b < growth; b++) {
if (g6.isInGrid((row + p + a), (col + q + b))) {
d1 += g6.getCell((row + p + a),
(col + q + b));
d2 += 1.0d;
}
}
}
if (d2 != 0.0d) {
//density.addToCell( ( row + p ), ( col + q ), ( d1 / d2 ) );
//density.initCell( ( row + p ), ( col + q ), ( d1 / d2 ) );
density.setCell((row + p), (col + q), (d1 / d2));
} else {
//density.initCell( ( row + p ), ( col + q ), 0.0d );
density.setCell((row + p), (col + q), 0.0d);
}
}
}
}
}
// g6.clear();
result[iteration] = density;
doubler *= 2;
g2 = g4;
g3 = g5;
}
return result;
}
// /**
// * Returns an Grids_GridDouble[] containing geometric density surfaces at a range of
// * scales:
// * result[ 0 ] - is the result at the first scale ( double the cellsize of grid )
// * result[ 1 ] - if it exists is the result at the second scale ( double the cellsize of result[ 0 ] )
// * result[ n ] - if it exists is the result at the ( n + 1 )th scale ( double the cellsize of result[ n - 1 ] )
// * The algorithm used for generating a geometric density surface is described in:
// * Turner A (2000) Density Data Generation for Spatial Data Mining Applications.
// * http://www.geog.leeds.ac.uk/people/a.turner/papers/geocomp00/gc_017.htm
// * @param grid - the input Grids_GridDouble
// * @param distance - the distance limiting the maximum scale of geometric density surface produced
// * @param ff - an Grid2DSquareCellDoubleFileFactory to be used in the event of running out of memory
// * @param chunksize - the number of rows/columns in largest chunks processed
// */
// public Grids_GridDouble[] geometricDensity( Grids_GridDouble grid, double distance, Grid2DSquareCellDoubleFileFactory ff, int chunkSize ) {
// // Allocate some memory for management
// int[] memoryGrab = Grids_Utilities.memoryAllocation( 10000 );
// boolean outOfMemoryTrigger0 = false;
// Grids_GridDouble[] result = null;
// Grid2DSquareCellDoubleJAIFactory jf = new Grid2DSquareCellDoubleJAIFactory();
// int nrows = grid.getNRows();
// int ncols = grid.getNCols();
// double xllcorner = grid.getXllcorner();
// double yllcorner = grid.getYllcorner();
// double cellsize = grid.getCellsize();
// double noDataValue = grid.getNoDataValue();
// int cellDistance = ( int ) Math.ceil( distance / cellsize );
// // Check chunkSize
// if ( chunkSize < ( cellDistance * 3 ) ) {
// chunkSize = cellDistance * 3;
// }
// // Calculate number of iterations and initialise result.
// int numberOfIterations = 0;
// int i1 = cellDistance;
// for ( int i = 0; i < cellDistance; i ++ ) {
// if ( i1 > 1 ) {
// i1 = i1 / 2;
// numberOfIterations ++;
// } else {
// break;
// }
// }
// result = new Grids_GridDouble[ numberOfIterations ];
// for ( int i = 0; i < numberOfIterations; i ++ ) {
// result[ i ] = ff.createGrid2DSquareCellDouble( nrows, ncols, xllcorner, yllcorner, cellsize, noDataValue, 1 );
// //System.out.println( result[ i ].toString() );
// }
// int colChunks = ( int ) Math.ceil( ( double ) ncols / ( double ) chunkSize );
// int rowChunks = ( int ) Math.ceil( ( double ) nrows / ( double ) chunkSize );
// int startRowIndex = 0 - cellDistance;
// int endRowIndex = chunkSize - 1 + cellDistance;
// int startColIndex = 0 - cellDistance;
// int endColIndex = chunkSize - 1 + cellDistance;
// Grids_GridDouble chunk;
// Grids_GridDouble chunkDensity[];
// boolean outOfMemoryTrigger1 = false;
// for ( int rowChunk = 0; rowChunk < rowChunks; rowChunk ++ ) {
// if ( endRowIndex > nrows - 1 + cellDistance ) {
// endRowIndex = nrows - 1 + cellDistance;
// }
// for ( int colChunk = 0; colChunk < colChunks; colChunk ++ ) {
// System.out.println( "Processing chunk " + ( ( rowChunk * colChunks ) + colChunk + 1 ) + " out of " + ( ( rowChunks * colChunks ) - 1 ) + "..." );
// if ( endColIndex > ncols - 1 + cellDistance ) {
// endColIndex = ncols - 1 + cellDistance;
// }
// if ( ! outOfMemoryTrigger0 ) {
// try {
// chunk = jf.createGrid2DSquareCellDouble( grid, startRowIndex, startColIndex, endRowIndex, endColIndex, noDataValue, 1 );
// } catch ( java.lang.OutOfMemoryError e ) {
// outOfMemoryTrigger0 = true;
// chunk = ff.createGrid2DSquareCellDouble( grid, startRowIndex, startColIndex, endRowIndex, endColIndex, noDataValue, 1 );
// }
// } else {
// chunk = ff.createGrid2DSquareCellDouble( grid, startRowIndex, startColIndex, endRowIndex, endColIndex, noDataValue, 1 );
// }
// //System.out.println( "chunk" );
// //System.out.println( chunk.toString() );
// // Process chunk
// if ( ! outOfMemoryTrigger1 ) {
// try {
// chunkDensity = geometricDensity( chunk, distance, jf );
// } catch ( java.lang.OutOfMemoryError e ) {
// memoryGrab = null;
// System.gc();
// outOfMemoryTrigger1 = true;
// chunkDensity = geometricDensity( chunk, distance, ff );
// }
// } else {
// chunkDensity = geometricDensity( chunk, distance, ff );
// }
// // Tidy
// chunk.clear();
// // Add central part of chunkDensity to result
// for ( int i = 0; i < numberOfIterations; i ++ ) {
// //System.out.println( "chunkDensity[ " + i + " ] nrows( " + chunkDensity[ i ].getNRows() + " ), ncols( " + chunkDensity[ i ].getNCols() + " )" );
// //System.out.println( "Scale " + i + " GeometricDensity " + chunkDensity[ i ].toString() );
// addToGrid( result[ i ], chunkDensity[ i ], cellDistance, cellDistance, chunkDensity[ i ].getNRows() - 1 - cellDistance, chunkDensity[ i ].getNCols() - 1 - cellDistance, 1.0d );
// //System.out.println( "result[ " + i + " ]" );
// //System.out.println( result[ i ].toString() );
// // Tidy
// chunkDensity[ i ].clear();
// }
// startColIndex += chunkSize;
// endColIndex += chunkSize;
// }
// startColIndex = 0 - cellDistance;
// endColIndex = chunkSize - 1 + cellDistance;
// startRowIndex += chunkSize;
// endRowIndex += chunkSize;
// }
// return result;
// }
// /**
// * Returns an Grids_GridDouble[] result with elements based on
// * statistics and values based on bivariate comparison of grid0 and grid1,
// * distance, weightIntersect and weightFactor.
// * @param grid0 the Grids_GridDouble to be regionBivariateStatisticsd with grid1
// * @param grid1 the Grids_GridDouble to be regionBivariateStatisticsd with grid0
// * @param statistics a String[] whose elements may be "diff", "correlation",
// * "zdiff", "density". If they are then the respective
// * Geographically Weighted Statistics (GWS) are returned
// * in the result array
// * @param distance the distance defining the region within which values will
// * be used
// * @param weightIntersect typically a number between 0 and 1 which controls
// * the weight applied at the centre of the kernel
// * @param weightFactor = 0.0d all values within distance will be equally weighted
// * > 0.0d means the edge of the kernel has a zero weight
// * < 0.0d means that the edage of the kernel has a weight of 1
// * > -1.0d && < 1.0d provides an inverse decay
// * TODO:
// * 1. Check and ensure that reasonable answers are returned for grids with different spatial frames.
// */
// public Grids_GridDouble[] regionBivariateStatistics( Grids_GridDouble grid0, Grids_GridDouble grid1, Vector statistics ) {
// double distance = grid0.getCellsize() * 5.0d;
// double weightIntercept = 1.0d;
// double weightFactor = 2.0d;
// try {
// return regionBivariateStatistics( grid0, grid1, statistics, distance, weightIntercept, weightFactor, new Grids_GridFactoryDouble() );
// } catch ( OutOfMemoryError _OutOfMemoryError1 ) {
// String dataDirectory = System.getProperty( "java.io.tmpdir" );
// if ( grid1 instanceof Grid2DSquareCellDoubleFile ) {
// dataDirectory = ( ( Grid2DSquareCellDoubleFile ) grid1 ).getDataDirectory();
// }
// System.out.println( "Run out of memory! Attempting to reprocess using filespace in directory " + dataDirectory );
// return regionBivariateStatistics( grid0, grid1, statistics, distance, weightIntercept, weightFactor, new Grid2DSquareCellDoubleFileFactory( dataDirectory ) );
// }
// }
/**
* Returns an Grids_GridDouble[] result with elements based on statistics
* and values based on bivariate comparison of grid0 and grid1, distance,
* weightIntersect and weightFactor.
*
* @param grid0 the Grids_GridDouble to be regionBivariateStatisticsd with
* grid1
* @param grid1 the Grids_GridDouble to be regionBivariateStatisticsd with
* grid0
* @param statistics a String[] whose elements may be "diff", "abs", "corr1"
* , "corr2", "zscore". If they are then the respective Geographically
* Weighted Statistics (GWS) are returned in the result array
* @param distance the distance defining the region within which values will
* be used
* @param weightIntersect typically a number between 0 and 1 which controls
* the weight applied at the centre of the kernel
* @param weightFactor {@code = 0.0d all values within distance will be equally
* weighted > 0.0d means the edge of the kernel has a zero weight < 0.0d
* means that the edage of the kernel has a weight of 1 > -1.0d && < 1.0d
* provides an inverse decay @param gridFactory the Abstract
* 2DSquareCellDoubleFactory used to create grids TODO: Check and ensure
* that reasonable answers are returned for grids with different spatial
* frames. (NB. Sensibly the two grids being correlated should have the same
* no data space.)}
* @param gf Grid fatory.
* @param dp The number of decimal places for BigDecimal arithmetic..
* @param rm The {@link RoundingMode} to use for BigDecimal arithmetic.
* @return Grids_GridDouble[]
* @throws Exception If encountered.
* @throws IOException If encountered.
* @throws ClassNotFoundException If encountered.
*/
public Grids_GridDouble[] regionBivariateStatistics(Grids_GridDouble grid0,
Grids_GridDouble grid1, ArrayList statistics, BigDecimal distance,
BigDecimal weightIntersect, int weightFactor,
Grids_GridFactoryDouble gf, int dp, RoundingMode rm)
throws IOException, ClassNotFoundException, Exception {
boolean hoome = true;
// Initialisation
boolean dodiff = false;
boolean doabs = false;
boolean docorr = false;
boolean dozdiff = false;
int allStatistics = 0;
for (int i = 0; i < statistics.size(); i++) {
if (((String) statistics.get(i)).equalsIgnoreCase("diff")) {
if (!dodiff) {
dodiff = true;
allStatistics += 4;
}
}
if (((String) statistics.get(i)).equalsIgnoreCase("corr")) {
if (!docorr) {
docorr = true;
allStatistics += 2;
}
}
if (((String) statistics.get(i)).equalsIgnoreCase("zdiff")) {
if (!dozdiff) {
dozdiff = true;
allStatistics += 2;
}
}
}
Grids_GridDouble[] result = new Grids_GridDouble[allStatistics];
Grids_GridDouble diffGrid = null;
Grids_GridDouble weightedDiffGrid = null;
Grids_GridDouble normalisedDiffGrid = null;
Grids_GridDouble weightedNormalisedDiffGrid = null;
Grids_GridDouble weightedCorrelationGrid = null;
Grids_GridDouble correlationGrid = null;
Grids_GridDouble weightedZdiffGrid = null;
Grids_GridDouble zdiffGrid = null;
long grid0Nrows = grid0.getNRows();
long grid0Ncols = grid0.getNCols();
Grids_Dimensions grid0Dimensions = grid0.getDimensions();
double grid0NoDataValue = grid0.getNoDataValue();
long grid1Nrows = grid1.getNRows();
long grid1Ncols = grid1.getNCols();
Grids_Dimensions grid1Dimensions = grid1.getDimensions();
double grid1NoDataValue = grid1.getNoDataValue();
double noDataValue = grid0NoDataValue;
int grid0CellDistance = grid0.getCellDistance(distance).intValue();
// setNumberOfPairs is the number of pairs of values needed to calculate
// the comparison statistics. It must be > 2
int setNumberOfPairs = 20;
int n;
// Intersection check
BigDecimal grid0Cellsize;
BigDecimal grid1Cellsize;
grid0Cellsize = grid0Dimensions.getCellsize();
grid1Cellsize = grid1Dimensions.getCellsize();
if ((grid1Dimensions.getXMin().compareTo(grid0Dimensions.getXMin().add(grid0Cellsize.multiply(new BigDecimal(Long.toString(grid0Ncols))))) == 1)
|| (grid1Dimensions.getXMax().compareTo(grid0Dimensions.getXMax().add(grid0Cellsize.multiply(new BigDecimal(Long.toString(grid0Nrows))))) == 1)
|| (grid1Dimensions.getYMin().add(grid1Cellsize.multiply(new BigDecimal(Long.toString(grid1Ncols)))).compareTo(grid0Dimensions.getYMin()) == -1)
|| (grid1Dimensions.getYMax().add(grid1Cellsize.multiply(new BigDecimal(Long.toString(grid1Nrows)))).compareTo(grid0Dimensions.getYMin()) == -1)) {
//System.out.println( "Warning!!! No intersection in " + getClass().getName( hoome ) + " regionBivariateStatistics()" );
return result;
}
// if ( ( grid1Xllcorner > grid0Xllcorner + ( ( double ) grid0Ncols * grid0Cellsize ) ) ||
// ( grid1Yllcorner > grid0Yllcorner + ( ( double ) grid0Nrows * grid0Cellsize ) ) ||
// ( grid1Xllcorner + ( ( double ) grid1Ncols * grid1Cellsize ) < grid0Xllcorner ) ||
// ( grid1Yllcorner + ( ( double ) grid1Nrows * grid1Cellsize ) < grid0Yllcorner ) ) {
// System.out.println( "Warning!!! No intersection in regionBivariateStatistics()" );
// return result;
// }
// Set the total sum of all the weights (totalSumWeights) in a
// region that would have no noDataValues
BigDecimal[] kernelParameters = Grids_Kernel.getKernelParameters(grid0, grid0CellDistance, distance, weightIntersect, weightFactor, dp, rm);
BigDecimal totalSumWeight = kernelParameters[0];
// Difference
if (dodiff) {
gf.setNoDataValue(grid0NoDataValue);
diffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
weightedDiffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
normalisedDiffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
weightedNormalisedDiffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
long row;
long col;
for (row = 0; row < grid0Nrows; row++) {
for (col = 0; col < grid0Ncols; col++) {
double max0 = Double.MIN_VALUE;
double max1 = Double.MIN_VALUE;
double min0 = Double.MAX_VALUE;
double min1 = Double.MAX_VALUE;
BigDecimal x0 = grid0.getCellX(col);
BigDecimal y0 = grid0.getCellY(row);
BigDecimal diff = BigDecimal.ZERO;
BigDecimal weightedDiff = BigDecimal.ZERO;
BigDecimal normalisedDiff = BigDecimal.ZERO;
BigDecimal weightedNormalisedDiff = BigDecimal.ZERO;
BigDecimal sumWeight = BigDecimal.ZERO;
n = 0;
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
double value0 = grid0.getCell(x1, y1);
double value1 = grid1.getCell(x1, y1);
if (value0 != grid0NoDataValue) {
max0 = Math.max(max0, value0);
min0 = Math.min(min0, value0);
}
if (value1 != grid1NoDataValue) {
max1 = Math.max(max1, value1);
min1 = Math.min(min1, value1);
}
if (value0 != grid0NoDataValue && value1 != grid1NoDataValue) {
n++;
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
sumWeight = sumWeight.add(weight);
BigDecimal diff2 = BigDecimal.valueOf(value0).subtract(BigDecimal.valueOf(value1));
weightedDiff = weightedDiff.add(diff2.multiply(weight));
diff = diff.add(diff2);
}
}
}
}
if (n > setNumberOfPairs) {
if (max0 != Double.MIN_VALUE && min0 != Double.MAX_VALUE && max1 != Double.MIN_VALUE && min1 != Double.MAX_VALUE) {
double range0 = max0 - min0;
double range1 = max1 - min1;
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
double v0 = grid0.getCell(x1, y1);
double v1 = grid1.getCell(x1, y1);
if (v0 != grid0NoDataValue && v1 != grid1NoDataValue) {
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
double dummy0;
if (range0 > 0.0d) {
dummy0 = (((v0 - min0) / range0) * 9.0d) + 1.0d;
} else {
dummy0 = 1.0d;
}
double dummy1;
if (range1 > 0.0d) {
dummy1 = (((v1 - min1) / range1) * 9.0d) + 1.0d;
} else {
dummy1 = 1.0d;
}
BigDecimal ddiff = BigDecimal.valueOf(dummy0 - dummy1);
normalisedDiff = normalisedDiff.add(ddiff);
weightedNormalisedDiff = weightedNormalisedDiff.add(ddiff.multiply(weight));
}
}
}
}
}
diffGrid.setCell(row, col, diff.doubleValue());
weightedDiffGrid.setCell(row, col, weightedDiff.multiply(sumWeight).doubleValue() / totalSumWeight.doubleValue());
normalisedDiffGrid.setCell(row, col, normalisedDiff.doubleValue());
weightedNormalisedDiffGrid.setCell(row, col, (weightedNormalisedDiff.multiply(sumWeight)).doubleValue() / totalSumWeight.doubleValue());
}
}
}
}
// Correlation and Zscore difference
// temporarily fix range
if (docorr || dozdiff) {
gf.setNoDataValue(grid0NoDataValue);
weightedCorrelationGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
correlationGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
weightedZdiffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
zdiffGrid = (Grids_GridDouble) gf.create(grid0Nrows, grid0Ncols, grid0Dimensions);
// setNumberOfPairs defines how many cells are needed to calculate correlation
double dummy0 = Double.MIN_VALUE;
double dummy1 = Double.MIN_VALUE;
long row;
long col;
for (row = 0; row < grid0Nrows; row++) {
for (col = 0; col < grid0Ncols; col++) {
//if ( grid0.getCell( row, col ) != grid0NoDataValue ) {
BigDecimal x0 = grid0.getCellX(col);
BigDecimal y0 = grid0.getCellY(row);
double max0 = Double.MIN_VALUE;
double max1 = Double.MIN_VALUE;
double min0 = Double.MAX_VALUE;
double min1 = Double.MAX_VALUE;
BigDecimal sumWeight0 = BigDecimal.ZERO;
BigDecimal sumWeight1 = BigDecimal.ZERO;
BigDecimal weightedMean0 = BigDecimal.ZERO;
BigDecimal weightedMean1 = BigDecimal.ZERO;
BigDecimal weightedSum0Squared = BigDecimal.ZERO;
BigDecimal weightedSum1Squared = BigDecimal.ZERO;
BigDecimal weightedSum01 = BigDecimal.ZERO;
BigDecimal weightedStandardDeviation0 = BigDecimal.ZERO;
BigDecimal weightedStandardDeviation1 = BigDecimal.ZERO;
BigDecimal weightedZdiff = BigDecimal.ZERO;
BigDecimal mean0 = BigDecimal.ZERO;
BigDecimal mean1 = BigDecimal.ZERO;
BigDecimal sum0Squared = BigDecimal.ZERO;
BigDecimal sum1Squared = BigDecimal.ZERO;
BigDecimal sum01 = BigDecimal.ZERO;
BigDecimal standardDeviation0 = BigDecimal.ZERO;
BigDecimal standardDeviation1 = BigDecimal.ZERO;
BigDecimal zdiff = BigDecimal.ZERO;
n = 0;
double n0 = 0.0d;
double n1 = 0.0d;
// Calculate max min range sumWeight
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
double v0 = grid0.getCell(x1, y1);
double v1 = grid1.getCell(x1, y1);
if (v0 != grid0NoDataValue) {
max0 = Math.max(max0, v0);
min0 = Math.min(min0, v0);
n0 += 1.0d;
sumWeight0 = sumWeight0.add(weight);
}
if (v1 != grid1NoDataValue) {
max1 = Math.max(max1, v1);
min1 = Math.min(min1, v1);
n1 += 1.0d;
sumWeight1 = sumWeight1.add(weight);
}
if (v0 != grid0NoDataValue && v1 != grid1NoDataValue) {
n++;
}
}
}
}
if (n > setNumberOfPairs) {
if (max0 != Double.MIN_VALUE && min0 != Double.MAX_VALUE && max1 != Double.MIN_VALUE && min1 != Double.MAX_VALUE) {
double range0 = max0 - min0;
double range1 = max1 - min1;
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
double v0 = grid0.getCell(row + p, col + q);
double v1 = grid1.getCell(row + p, col + q);
if (v0 != grid0NoDataValue) {
if (range0 > 0.0d) {
dummy0 = (((v0 - min0) / range0) * 9.0d) + 1.0d;
} else {
dummy0 = 1.0d;
}
weightedMean0 = weightedMean0.add(BigDecimal.valueOf(dummy0 / sumWeight0.doubleValue()).multiply(weight));
mean0 = mean0.add(BigDecimal.valueOf(dummy0 / n0));
}
if (v1 != grid1NoDataValue) {
if (range1 > 0.0d) {
dummy1 = (((v1 - min1) / range1) * 9.0d) + 1.0d;
} else {
dummy1 = 1.0d;
}
weightedMean1 = weightedMean1.add(BigDecimal.valueOf(dummy1 / sumWeight1.doubleValue()).multiply(weight));
mean1 = mean1.add(BigDecimal.valueOf(dummy1 / n1));
}
}
}
}
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
double v0 = grid0.getCell(x1, y1);
if (v0 != grid0NoDataValue) {
if (range0 > 0.0d) {
dummy0 = (((v0 - min0) / range0) * 9.0d) + 1.0d;
} else {
dummy0 = 1.0d;
}
standardDeviation0 = standardDeviation0.add(BigDecimal.valueOf(Math.pow((dummy0 - mean0.doubleValue()), 2.0d)));
weightedStandardDeviation0 = weightedStandardDeviation0.add(BigDecimal.valueOf(Math.pow((dummy0 - weightedMean0.doubleValue()), 2.0d)).multiply(weight));
}
double v1 = grid1.getCell(x1, y1);
if (v1 != grid1NoDataValue) {
if (range1 > 0.0d) {
dummy1 = (((v1 - min1) / range1) * 9.0d) + 1.0d;
} else {
dummy1 = 1.0d;
}
standardDeviation1 = standardDeviation1.add(BigDecimal.valueOf(Math.pow((dummy1 - mean1.doubleValue()), 2.0d)));
weightedStandardDeviation1 = weightedStandardDeviation1.add(BigDecimal.valueOf(Math.pow((dummy1 - weightedMean1.doubleValue()), 2.0d)).multiply(weight));
}
if (v0 != grid0NoDataValue && v1 != grid1NoDataValue) {
//weightedSum0Squared += Math.pow( ( ( value0 * weight ) - weightedMean0 ), 2.0d );
//weightedSum1Squared += Math.pow( ( ( value1 * weight ) - weightedMean1 ), 2.0d );
//weightedSum01 += ( ( value0 * weight ) - weightedMean0 ) * ( ( value1 * weight ) - weightedMean1 );
weightedSum0Squared = weightedSum0Squared.add(BigDecimal.valueOf(Math.pow((dummy0 - weightedMean0.doubleValue()), 2.0d)).multiply(weight));
weightedSum1Squared = weightedSum1Squared.add(BigDecimal.valueOf(Math.pow((dummy1 - weightedMean1.doubleValue()), 2.0d)).multiply(weight));
weightedSum01 = weightedSum01.add(BigDecimal.valueOf((dummy0 - weightedMean0.doubleValue()) * (dummy1 - weightedMean1.doubleValue())).multiply(weight));
sum0Squared = sum0Squared.add(BigDecimal.valueOf(Math.pow((dummy0 - mean0.doubleValue()), 2.0d)));
sum1Squared = sum1Squared.add(BigDecimal.valueOf(Math.pow((dummy1 - mean1.doubleValue()), 2.0d)));
sum01 = sum01.add(BigDecimal.valueOf((dummy0 - mean0.doubleValue()) * (dummy1 - mean1.doubleValue())));
}
}
}
}
BigDecimal denominator = Math_BigDecimal.sqrt(weightedSum0Squared, dp, rm).multiply(Math_BigDecimal.sqrt(weightedSum1Squared, dp, rm));
if (denominator.compareTo(BigDecimal.ZERO) == 1 && denominator.doubleValue() != noDataValue) {
weightedCorrelationGrid.setCell(row, col, weightedSum01.doubleValue() / denominator.doubleValue());
}
denominator = Math_BigDecimal.sqrt(sum0Squared, dp, rm).multiply(Math_BigDecimal.sqrt(sum1Squared, dp, rm));
if (denominator.compareTo(BigDecimal.ZERO) == 1 && denominator.doubleValue() != noDataValue) {
correlationGrid.setCell(row, col, sum01.doubleValue() / denominator.doubleValue());
}
weightedStandardDeviation0 = BigDecimal.valueOf(Math.sqrt(weightedStandardDeviation0.doubleValue() / (n0 - 1.0d)));
standardDeviation0 = BigDecimal.valueOf(Math.sqrt(standardDeviation0.doubleValue() / (n0 - 1.0d)));
weightedStandardDeviation1 = BigDecimal.valueOf(Math.sqrt(weightedStandardDeviation1.doubleValue() / (n1 - 1.0d)));
standardDeviation1 = BigDecimal.valueOf(Math.sqrt(standardDeviation1.doubleValue() / (n1 - 1.0d)));
// Calculate z scores and difference
if (weightedStandardDeviation0.compareTo(BigDecimal.ZERO) == 1 && weightedStandardDeviation1.compareTo(BigDecimal.ZERO) == 1) {
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
double v0 = grid0.getCell(x1, y1);
double v1 = grid1.getCell(x1, y1);
if (v0 != grid0NoDataValue && v1 != grid1NoDataValue) {
if (range0 > 0.0d) {
dummy0 = (((v0 - min0) / range0) * 9.0d) + 1.0d;
} else {
dummy0 = 1.0d;
}
if (range1 > 0.0d) {
dummy1 = (((v1 - min1) / range1) * 9.0d) + 1.0d;
} else {
dummy1 = 1.0d;
}
BigDecimal weight = Grids_Kernel.getKernelWeight(distance, weightIntersect, weightFactor, thisDistance, dp, rm);
//weightedZdiff += ( ( ( ( value0 * weight ) - weightedMean0 ) / weightedStandardDeviation0 ) - ( ( ( value1 * weight ) - weightedMean1 ) / weightedStandardDeviation1 ) );
weightedZdiff = weightedZdiff.add(BigDecimal.valueOf(((((dummy0 - weightedMean0.doubleValue()) / weightedStandardDeviation0.doubleValue())
- ((dummy1 - weightedMean1.doubleValue()) / weightedStandardDeviation1.doubleValue())) * weight.doubleValue())));
// weightedZdiff += (((dummy0 - weightedMean0) / weightedStandardDeviation0)
// - ((dummy1 - weightedMean1) / weightedStandardDeviation1)) * weight;
}
}
}
}
weightedZdiffGrid.setCell(row, col, weightedZdiff.doubleValue());
}
if (standardDeviation0.doubleValue() > 0.0d && standardDeviation1.doubleValue() > 0.0d) {
for (int p = -grid0CellDistance; p <= grid0CellDistance; p++) {
for (int q = -grid0CellDistance; q <= grid0CellDistance; q++) {
BigDecimal x1 = grid0.getCellX(col + q);
BigDecimal y1 = grid0.getCellY(row + p);
BigDecimal thisDistance = Grids_Utilities.distance(x0, y0, x1, y1, dp, rm);
if (thisDistance.compareTo(distance) == -1) {
double v0 = grid0.getCell(x1, y1);
double v1 = grid1.getCell(x1, y1);
if (v0 != grid0NoDataValue && v1 != grid1NoDataValue) {
if (range0 > 0.0d) {
dummy0 = (((v0 - min0) / range0) * 9.0d) + 1.0d;
} else {
dummy0 = 1.0d;
}
if (range1 > 0.0d) {
dummy1 = (((v1 - min1) / range1) * 9.0d) + 1.0d;
} else {
dummy1 = 1.0d;
}
zdiff = zdiff.add(BigDecimal.valueOf((((dummy0 - mean0.doubleValue()) / standardDeviation0.doubleValue()) - ((dummy1 - mean1.doubleValue()) / standardDeviation1.doubleValue()))));
//zdiff += (((dummy0 - mean0) / standardDeviation0) - ((dummy1 - mean1) / standardDeviation1));
}
}
}
}
zdiffGrid.setCell(row, col, zdiff.doubleValue());
}
}
}
}
}
}
allStatistics = 0;
if (dodiff) {
diffGrid.setName(grid0.getName() + "_Diff_" + grid1.getName());
result[allStatistics] = diffGrid;
allStatistics++;
weightedDiffGrid.setName(grid0.getName() + "_WDiff_" + grid1.getName());
result[allStatistics] = weightedDiffGrid;
allStatistics++;
normalisedDiffGrid.setName(grid0.getName() + "_NDiff_" + grid1.getName());
result[allStatistics] = normalisedDiffGrid;
allStatistics++;
weightedNormalisedDiffGrid.setName(grid0.getName() + "_NWDiff_" + grid1.getName());
result[allStatistics] = weightedNormalisedDiffGrid;
allStatistics++;
}
if (docorr) {
weightedCorrelationGrid.setName(grid0.getName() + "_WCorr_" + grid1.getName());
result[allStatistics] = weightedCorrelationGrid;
allStatistics++;
correlationGrid.setName(grid0.getName() + "_Corr_" + grid1.getName());
result[allStatistics] = correlationGrid;
allStatistics++;
}
if (dozdiff) {
weightedZdiffGrid.setName(grid0.getName() + "_WZDiff_" + grid1.getName());
result[allStatistics] = weightedZdiffGrid;
allStatistics++;
zdiffGrid.setName(grid0.getName() + "_ZDiff_" + grid1.getName());
result[allStatistics] = zdiffGrid;
allStatistics++;
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy